ALGO.C
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:11k
源码类别:

Windows编程

开发平台:

Visual C++

  1. /*++
  2. Copyright (c) 1995  Microsoft Corporation
  3. Module Name:
  4.     netiplookupalgo.c
  5. Abstract:
  6. Revision History:
  7. --*/
  8. DWORD g_dwBitMask = {0x00000001,
  9.                      0x00000002,
  10.                      0x00000004,
  11.                      0x00000008,
  12.                      0x00000010,
  13.                      0x00000020,
  14.                      0x00000040,
  15.                      0x00000080,
  16.                      0x00000100,
  17.                      0x00000200,
  18.                      0x00000400,
  19.                      0x00000800,
  20.                      0x00001000,
  21.                      0x00002000,
  22.                      0x00004000,
  23.                      0x00008000,
  24.                      0x00010000,
  25.                      0x00020000,
  26.                      0x00040000,
  27.                      0x00080000,
  28.                      0x00100000,
  29.                      0x00200000,
  30.                      0x00400000,
  31.                      0x00800000,
  32.                      0x01000000,
  33.                      0x02000000,
  34.                      0x04000000,
  35.                      0x08000000,
  36.                      0x10000000,
  37.                      0x20000000,
  38.                      0x40000000,
  39.                      0x80000000};
  40. DWORD g_dwPrefixMask = {0x00000001,
  41.                         0x00000003,
  42.                         0x00000007,
  43.                         0x0000000F,
  44.                         0x0000001F,
  45.                         0x0000003F,
  46.                         0x0000007F,
  47.                         0x000000FF,
  48.                         0x000001FF,
  49.                         0x000003FF,
  50.                         0x000007FF,
  51.                         0x00000FFF,
  52.                         0x00001FFF,
  53.                         0x00003FFF,
  54.                         0x00007FFF,
  55.                         0x0000FFFF,
  56.                         0x0001FFFF,
  57.                         0x0003FFFF,
  58.                         0x0007FFFF,
  59.                         0x000FFFFF,
  60.                         0x001FFFFF,
  61.                         0x003FFFFF,
  62.                         0x007FFFFF,
  63.                         0x00FFFFFF,
  64.                         0x01FFFFFF,
  65.                         0x03FFFFFF,
  66.                         0x07FFFFFF,
  67.                         0x0FFFFFFF,
  68.                         0x1FFFFFFF,
  69.                         0x3FFFFFFF,
  70.                         0x7FFFFFFF,
  71.                         0xFFFFFFFF}
  72. BYTE
  73. DistPos(
  74.     IN  PTRIE_KEY   ptkKey1,
  75.     IN  PTRIE_KEY   ptkKey2
  76.     )
  77. /*++
  78.   Routine Description
  79.       Returns the position of the distinguishing bit for two keys. This is
  80.       the first bit that differs between the two keys.  If one key is a prefix
  81.       of another (strict or non strict), then the dist bit is 1+width of the smaller
  82.       key (== length of smaller key)
  83.       
  84.       Notationally:
  85.       DistBit(K1, K2) = Min{i|K1[i] != K2[i]}
  86.       DistBit(K1, K2) = Length(K1) iff K1 is a prefix of K2
  87.       
  88.       
  89.   Arguments
  90.   Return Value
  91.       NO_ERROR
  92. --*/
  93. {
  94.     BYTE    byLength;
  95.     
  96.     byLength = MAX(Length(ptkKey1),
  97.                    Length(ptkKey2));
  98.     
  99.     for(i = 0; i < byLength; i++)
  100.     {
  101.         if(ptkKey1->dwAddr & g_dwBitMask[i] isnot
  102.            ptkKey2->dwAddr & g_dwBitMask[i])
  103.         {
  104.             break;
  105.         }
  106.     }
  107.     
  108.     return i;
  109. }
  110.     
  111. PTRIE_KEY
  112. GetKey(
  113.     IN  PTRIE_NODE  ptnNode,
  114.     IN  PTRIE_KEY   ptkKey,
  115.     OUT PBYTE       pbyPosition
  116.     )
  117. /*++
  118.   Routine Description
  119.       Given a input key and node, returns the stored key in the node
  120.       whose index bit matches with the input key
  121.   Arguments
  122.   Return Value
  123.       NO_ERROR
  124. --*/
  125. {
  126.     
  127.     if(Width(ptkKey) < Index(ptnNode))
  128.     {
  129.         return NULL;
  130.     }
  131.     *pbyPosition = GetRelevantBit(ptkKey->dwAddr, Index(ptnNode));
  132.     
  133. #if DBG
  134.     //
  135.     // A little consistency check here
  136.     //
  137.     
  138.     if(LeftKey(ptnNode))
  139.     {
  140.         ASSERT(ptnNode->byPosition is LEFT);
  141.     }
  142.     if(RightKey(ptnNode))
  143.     {
  144.         ASSERT(ptnNode->byPosition is RIGHT);
  145.     }
  146.     
  147. #endif
  148.     
  149.     return GetKeyByPosition(ptnNode,
  150.                             *pbyPosition);
  151. }
  152. PTRIE_NODE
  153. GetSubTrie(
  154.     IN  PTRIE_NODE  ptnNode,
  155.     IN  PTRIE_KEY   ptkKey,
  156.     OUT PBYTE       pbyPosition
  157.     )
  158. /*++
  159.   Routine Description
  160.   Locks
  161.   Arguments
  162.   Return Value
  163.       NO_ERROR
  164. --*/
  165. {
  166.     
  167.     if(Width(ptkKey) < Index(ptnNode))
  168.     {
  169.         return NULL;
  170.     }
  171.     *pbyPosition = GetRelevantBit(ptkKey->dwAddr, Index(ptnNode));
  172. #if DBG
  173.     //
  174.     // A little consistency check here
  175.     //
  176.     
  177.     if(LeftSubTrie(ptnNode))
  178.     {
  179.         ASSERT(ptnNode->ptnTrie[LEFT]->byPosition is LEFT);
  180.     }
  181.     if(RightSubTrie(ptnNode))
  182.     {
  183.         ASSERT(ptnNode->ptnTrie[RIGHT]->byPosition is RIGHT);
  184.     }
  185.     
  186. #endif
  187.     return GetSubTrieByPosition(ptnNode,
  188.                                 *pbyPosition);
  189.     
  190. }
  191. PTRIE_KEY
  192. GetClosestKey(
  193.     PTRIE_NODE  ptnNode,
  194.     PTRIE_KEY   ptkKey
  195.     )
  196. /*++
  197.   Routine Description
  198.       If the length of the key is greater than or equal to the index, return
  199.       any Key.
  200.       else
  201.          If a key with matching relevant bit is found, return that, else
  202.          return the other key
  203.   Locks
  204.   Arguments
  205.   Return Value
  206.       NO_ERROR
  207. --*/
  208. {
  209.     PTRIE_KEY   ptkTemp;
  210.     BYTE        byPos;
  211.     
  212.     if(Width(ptkKey) >= Index(ptnNode))
  213.     {
  214.         ptkTemp = GetKey(ptnNode,
  215.                          ptkKey,
  216.                          &byPos);
  217.         
  218.         if(ptkTemp isnot NULL)
  219.         {
  220.             return ptkTemp;
  221.         }
  222.         else
  223.         {
  224.             return GetKeyByPosition(ptnNode,
  225.                                     ComplementPosition(byPos))
  226.         }
  227.     }
  228.     else
  229.     {
  230.         //
  231.         // For now we return the left key first
  232.         //
  233.         ptkTemp = GetKeyByPosition(ptnNode,
  234.                                    LEFT);
  235.         
  236.         if(ptkTemp)
  237.         {
  238.             return ptkTemp;
  239.         }
  240.         else
  241.         {
  242.             return GetKeyByPosition(ptnNode,
  243.                                     RIGHT);
  244.         }
  245.     }
  246. }
  247. PTRIE_NODE
  248. GetClosestSubTrie(
  249.     PTRIE_NODE  ptnNode,
  250.     PTRIE_KEY   ptkKey
  251.     )
  252. /*++
  253.   Routine Description
  254.       If the length of the key is greater than or equal to the index, return
  255.       any sub trie.
  256.       else
  257.          If a trie with matching relevant bit is found, return that, else
  258.          return the other trie
  259.   Locks
  260.   Arguments
  261.   Return Value
  262.       NO_ERROR
  263. --*/
  264. {
  265.     PTRIE_NODE  ptnTemp;
  266.     BYTE        byPos;
  267.     
  268.     if(Width(ptkKey) >= Index(ptnNode))
  269.     {
  270.         ptnTemp = GetSubTrie(ptnNode,
  271.                              ptkKey,
  272.                              &byPos);
  273.         
  274.         if(ptnTemp isnot NULL)
  275.         {
  276.             return ptnTemp;
  277.         }
  278.         else
  279.         {
  280.             return GetSubTrieByPosition(ptnNode,
  281.                                         ComplementPosition(byPos))
  282.         }
  283.     }
  284.     else
  285.     {
  286.         //
  287.         // For now we return the left trie first
  288.         //
  289.         ptkTemp = GetSubTrieByPosition(ptnNode,
  290.                                        LEFT);
  291.         
  292.         if(ptkTemp)
  293.         {
  294.             return ptkTemp;
  295.         }
  296.         else
  297.         {
  298.             return GetSubTrieByPosition(ptnNode,
  299.                                         RIGHT);
  300.         }
  301.     }
  302. }
  303. PTRIE_NODE
  304. CreateNode(
  305.     IN  BYTE        byIndex,
  306.     IN  PTRIE_KEY   ptkKey
  307.     )
  308. /*++
  309.   Routine Description
  310.   Locks
  311.   Arguments
  312.   Return Value
  313.       NO_ERROR
  314. --*/
  315. {
  316.     PTRIE_NODE  ptnNode;
  317.     ptnNode = HeapAlloc(g_hPrivateHeap,
  318.                         0,
  319.                         sizeof(TRIE_NODE));
  320.     if(ptnNode is NULL)
  321.     {
  322.         printf("Unable to allocate node. Error %dn",
  323.                GetLastError());
  324.         return NULL;
  325.     }
  326.     
  327.     ptnNode->ptnTrie[LEFT]  = NULL;
  328.     ptnNode->ptnTrie[RIGHT] = NULL;
  329.     
  330.     ptnNode->ptnParent      = NULL;
  331.     ptnNode->byIndex        = byIndex;
  332.     //
  333.     // See where the key would go into the allocated node
  334.     //
  335.     
  336.     GetKey(ptnNode,
  337.            ptkKey,
  338.            &byPos);
  339.     //
  340.     // Since we are going to be inserting the key here, set
  341.     // its position field also
  342.     //
  343.     ptkKey->byPos = byPos;
  344.     
  345.     ptnNode->rgptkKey[byPos]  = ptkKey;
  346.     
  347.     ptnNode->rgptkKey[ComplementPosition(byPos)] = NULL;
  348.     return ptnNode;
  349. }
  350. DWORD
  351. InsertKey(
  352.     PTRIE_NODE  *pptnRoot,
  353.     PTRIE_KEY   ptkKey
  354.     )
  355. /*++
  356.   Routine Description
  357.   Locks
  358.   Arguments
  359.   Return Value
  360.       NO_ERROR
  361. --*/
  362. {
  363.     PTRIE_NODE  ptnTempNode;
  364.     if(*pptnRoot is NULL)
  365.     {
  366.         *pptnRoot = AllocateNode(Width(ptkKey),
  367.                                  ptkKey);
  368.         if(*pptnRoot is NULL)
  369.         {
  370.             return ERROR_NOT_ENOUGH_MEMORY;
  371.         }
  372.         return NO_ERROR;
  373.     }
  374.     ptnTempNode = *pptnRoot;
  375.     //
  376.     // Descend the tree, branching according to the Index bit
  377.     // Stop when the node is a leaf OR
  378.     // when the index is greater than the width of the key OR
  379.     // when the prefix of the node is not the same as the key
  380.     //
  381.     // The prefix is found by (ptkKey->dwAddr & g_dwPrefixMask[Index])
  382.     //
  383.     
  384.     while(!IsLeafNode(ptnTempNode) and
  385.           (Width(ptkKey) > Index(ptnTempNode)) and
  386.           (ptnTempNode->rgptkKey[ptnTempNode->byNonNullKey] & g_dwPrefixMask[Index(ptnTempNode)] is
  387.            ptkKey[
  388.     {
  389.         ptnTempNode = ClosestSubTrie(ptnTempNode,
  390.                                      ptkKey);
  391.     }
  392.     byDistPost = DistPos(key,
  393.                          ClosestKey(ptnNode,ptkKey));
  394.     byIndex = MIN(Lenght(Key), byDistPos);
  395.     if(ptnTempNode is *pptnRoot)
  396.     {
  397.         InsertInOrAbove(pptnRoot,
  398.                         ptnTempNode,
  399.                         ptkKey,
  400.                         byDistPos);
  401.     }
  402.     else
  403.     {
  404.         if(GetSubTrie(ptnNode, ptkKey) is NULL)
  405.         {
  406.             InsertWithEmptySubTrie(ptnNode,
  407.                                    ptkKey,
  408.                                    byDistPos);
  409.         }
  410.         else
  411.         {
  412.             InsertWithNonEmptySubTrie(ptnNode,
  413.                                       ptkKey,
  414.                                       byDistPos);
  415.         }
  416.     }
  417.     return NO_ERROR;
  418. }
  419.     
  420. DWORD
  421. InsertInOrAbove(
  422.     PTRIE_NODE  *pptnRoot,
  423.     PTRIE_NODE  ptnNode,
  424.     PTRIE_KEY   ptkKey,
  425.     BYTE        byDistPos
  426.     )
  427. /*++
  428.   Routine Description
  429.   Locks
  430.   Arguments
  431.   Return Value
  432.       NO_ERROR
  433. --*/
  434. {
  435.     if(