Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

514 lines
11 KiB

  1. /* --------------------------------------------------------------------
  2. Microsoft OS/2 LAN Manager
  3. Copyright(c) Microsoft Corp., 1990-1999
  4. RPC - Written by Dov Harel
  5. This file contains the implementation for splay tree self
  6. adjusting binary trees
  7. -------------------------------------------------------------------- */
  8. #pragma warning ( disable : 4514 )
  9. #include "dict.hxx"
  10. // Handy macros used to define common tree operations.
  11. // Dummy is a member of the Dictionary now, not a global.
  12. #define ROTATELEFT tmp=t->right; t->right=tmp->left; tmp->left =t; t=tmp
  13. #define ROTATERIGHT tmp=t->left; t->left =tmp->right; tmp->right=t; t=tmp
  14. #define LINKLEFT tmp=t; t = t->right; l = l->right = tmp
  15. #define LINKRIGHT tmp=t; t = t->left; r = r->left = tmp
  16. #define ASSEMBLE r->left = t->right; l->right = t->left; \
  17. t->left = Dummy->right; t->right = Dummy->left
  18. // initialize the memory allocator for TreeNode
  19. FreeListMgr
  20. TreeNode::MyFreeList( sizeof ( TreeNode ) );
  21. //*************************************************************************
  22. //***** Core functions (internal) *****
  23. //*************************************************************************
  24. SSIZE_T // return last comparision
  25. Dictionary::SplayUserType( // general top down splay
  26. pUserType keyItem // pointer to a "key item" searched for
  27. ) //-----------------------------------------------------------------------//
  28. {
  29. TreeNode* t; // current search point
  30. TreeNode* l; // root of "left subtree" < keyItem
  31. TreeNode* r; // root of "right subtree" > keyItem
  32. SSIZE_T kcmp; // cash comparison results
  33. TreeNode* tmp;
  34. if ((fCompare = Compare(keyItem, root->item)) == 0)
  35. return (fCompare);
  36. Dummy = l = r = &Dumbo;
  37. Dumbo.left = Dumbo.right = Nil;
  38. t = root;
  39. do {
  40. if ( fCompare < 0 ) {
  41. if ( t->left == Nil ) break;
  42. if ( (kcmp = Compare(keyItem, t->left->item)) == 0 ) {
  43. LINKRIGHT;
  44. }
  45. else if ( kcmp < 0 ) {
  46. ROTATERIGHT;
  47. if ( t->left != Nil ) {
  48. LINKRIGHT;
  49. }
  50. }
  51. else { // keyItem > t->left->item
  52. LINKRIGHT;
  53. if ( t->right != Nil ) {
  54. LINKLEFT;
  55. }
  56. }
  57. }
  58. else { // keyItem > t->item
  59. if ( t->right == Nil ) break;
  60. if ( (kcmp = Compare(keyItem, t->right->item)) == 0 ) {
  61. LINKLEFT;
  62. }
  63. else if ( kcmp > 0 ) {
  64. ROTATELEFT;
  65. if ( t->right != Nil ) {
  66. LINKLEFT;
  67. }
  68. }
  69. else { // keyItem < t->right->item
  70. LINKLEFT;
  71. if ( t->left != Nil ) {
  72. LINKRIGHT;
  73. }
  74. }
  75. }
  76. } while ( (fCompare = Compare(keyItem, t->item)) != 0 );
  77. ASSEMBLE;
  78. // if (fCompare != Compare(keyItem, t->item))
  79. // printf("Dictionary error!");
  80. root = t;
  81. return(fCompare);
  82. }
  83. //-----------------------------------------------------------------------
  84. TreeNode *
  85. Dictionary::SplayLeft(
  86. TreeNode * t ) // root of tree & current "search" point
  87. {
  88. TreeNode * l = Dummy; // root of "left subtree" < keyItem
  89. TreeNode * r = Dummy; // root of "right subtree" > keyItem
  90. TreeNode * tmp;
  91. if (t == Nil || t->left == Nil)
  92. return(t);
  93. if (t->left->left == Nil) {
  94. ROTATERIGHT;
  95. return(t);
  96. }
  97. Dummy->left = Dummy->right = Nil;
  98. while ( t->left != Nil ) {
  99. ROTATERIGHT;
  100. if ( t->left != Nil ) {
  101. LINKRIGHT;
  102. }
  103. }
  104. ASSEMBLE;
  105. return(t);
  106. }
  107. #ifndef DICT_NOPREV
  108. //-----------------------------------------------------------------------
  109. TreeNode *
  110. Dictionary::SplayRight(
  111. TreeNode * t ) // root of tree & current "search" point
  112. {
  113. TreeNode * l = Dummy; // root of "left subtree" < keyItem
  114. TreeNode * r = Dummy; // root of "right subtree" > keyItem
  115. TreeNode * tmp;
  116. if (t == Nil || t->right == Nil)
  117. return(t);
  118. Dummy->left = Dummy->right = Nil;
  119. while ( t->right != Nil ) {
  120. ROTATELEFT;
  121. if ( t->right != Nil ) {
  122. LINKLEFT;
  123. }
  124. }
  125. ASSEMBLE;
  126. return(t);
  127. }
  128. #endif
  129. // Class methods for Splay Tree
  130. Dict_Status
  131. Dictionary::Dict_Find( // return a item that matches
  132. pUserType itemI // this value
  133. // Returns:
  134. // itemCur - Nil if at not in Dict, else found item
  135. ) //-----------------------------------------------------------------------//
  136. {
  137. itemCur = Nil;
  138. if (root == Nil)
  139. return (EMPTY_DICTIONARY);
  140. if (itemI == Nil)
  141. return (NULL_ITEM);
  142. if (SplayUserType (itemI) == 0){
  143. itemCur = root->item;
  144. return(SUCCESS);
  145. }
  146. // printf("After NotFound %ld: (", this); PrintItem(itemI); printf(")\n"); Dict_Print();
  147. return(ITEM_NOT_FOUND);
  148. }
  149. #ifndef DICT_NONEXT
  150. Dict_Status
  151. Dictionary::Dict_Next( // return the next item
  152. pUserType itemI // of a key greater then this
  153. // Returns:
  154. // itemCur - Nil if at end of Dict, else current item
  155. ) //-----------------------------------------------------------------------//
  156. {
  157. TreeNode* t;
  158. itemCur = Nil;
  159. if (root == Nil)
  160. return (EMPTY_DICTIONARY);
  161. if (itemI == Nil) { // no arg, return first record
  162. root = SplayLeft (root);
  163. itemCur = root->item;
  164. return (SUCCESS);
  165. }
  166. if (itemI != root->item)
  167. if (SplayUserType (itemI) > 0) {
  168. itemCur = root->item;
  169. return (SUCCESS);
  170. }
  171. if (root->right == Nil)
  172. return (LAST_ITEM);
  173. t = root;
  174. root = SplayLeft (root->right);
  175. root->left = t;
  176. t->right = Nil;
  177. itemCur = root->item;
  178. return (SUCCESS);
  179. }
  180. #endif // DICT_NONEXT
  181. #ifndef DICT_NOPREV
  182. Dict_Status
  183. Dictionary::Dict_Prev( // return the previous item
  184. pUserType itemI // of a key less then this
  185. // Returns:
  186. // itemCur - Nil if at begining of Dict, else current item
  187. ) //-----------------------------------------------------------------------//
  188. {
  189. TreeNode* t;
  190. itemCur = Nil;
  191. if (root == Nil)
  192. return (EMPTY_DICTIONARY);
  193. if (itemI == Nil) { // no arg, return last record
  194. root = SplayRight (root);
  195. itemCur = root->item;
  196. return (SUCCESS);
  197. }
  198. if (itemI != root->item)
  199. if (SplayUserType (itemI) < 0) {
  200. itemCur = root->item;
  201. return (SUCCESS);
  202. }
  203. if (root->left == Nil)
  204. return (LAST_ITEM);
  205. t = root;
  206. root = SplayRight (root->left);
  207. root->right = t;
  208. t->left = Nil;
  209. itemCur = root->item;
  210. return (SUCCESS);
  211. }
  212. #endif // DICT_NOPREV
  213. Dict_Status
  214. Dictionary::Dict_Insert( // insert the given item into the tree
  215. pUserType itemI // the item to be inserted
  216. // Returns:
  217. // itemCur - point to new item
  218. ) //-----------------------------------------------------------------------//
  219. {
  220. TreeNode *newNode, *t;
  221. if ((itemCur = itemI) == Nil)
  222. return (NULL_ITEM);
  223. if (root == Nil) {
  224. root = new TreeNode(itemI);
  225. size++;
  226. return (SUCCESS);
  227. }
  228. if (SplayUserType (itemI) == 0)
  229. return (ITEM_ALREADY_PRESENT);
  230. newNode = new TreeNode(itemI);
  231. size++;
  232. t = root;
  233. if (fCompare > 0) {
  234. newNode->right = t->right; // item >= t->item
  235. newNode->left = t;
  236. t->right = Nil;
  237. }
  238. else {
  239. newNode->left = t->left;
  240. newNode->right = t;
  241. t->left = Nil;
  242. }
  243. root = newNode;
  244. // printf("After Insert %ld: (", this); PrintItem(itemI); printf(")\n"); Dict_Print();
  245. return (SUCCESS);
  246. }
  247. Dict_Status
  248. Dictionary::Dict_Delete( // delete the given item from the tree
  249. pUserType *itemI // points to the (key) item to be deleted
  250. // Returns:
  251. // itemCur is Nil - undefined
  252. ) //-----------------------------------------------------------------------//
  253. {
  254. TreeNode *t, *r;
  255. itemCur = Nil;
  256. if (root == Nil)
  257. return (EMPTY_DICTIONARY);
  258. if (itemI == Nil)
  259. return (NULL_ITEM);
  260. if (itemI != root->item) {
  261. if (SplayUserType (*itemI) != 0)
  262. return(ITEM_NOT_FOUND);
  263. }
  264. *itemI = root->item;
  265. t = root;
  266. if (t->left == Nil)
  267. root = t->right;
  268. else if ( (r = t->right) == Nil)
  269. root = t->left;
  270. else {
  271. r = SplayLeft (r);
  272. r->left = t->left; // at this point r->left == Nil
  273. root = r;
  274. }
  275. delete t;
  276. size--;
  277. return (SUCCESS);
  278. }
  279. pUserType
  280. Dictionary::Dict_Delete_One()
  281. {
  282. TreeNode * pCurrent = root;
  283. TreeNode * pPrev = NULL; // NULL indicates prev is root
  284. pUserType pResult;
  285. BOOL fLeft = FALSE;
  286. while ( pCurrent )
  287. {
  288. if ( pCurrent->left )
  289. {
  290. pPrev = pCurrent;
  291. pCurrent = pCurrent->left;
  292. fLeft = TRUE;
  293. continue;
  294. }
  295. if ( pCurrent->right )
  296. {
  297. pPrev = pCurrent;
  298. pCurrent = pCurrent->right;
  299. fLeft = FALSE;
  300. continue;
  301. }
  302. // found a leaf
  303. break;
  304. }
  305. // we are now at a leaf (or tree empty)
  306. if ( !pCurrent )
  307. return NULL;
  308. // unhook from parent
  309. if ( pPrev )
  310. {
  311. if ( fLeft )
  312. pPrev->left = NULL;
  313. else
  314. pPrev->right = NULL;
  315. }
  316. else
  317. root = NULL;
  318. // return the item, and delete the treenode
  319. pResult = pCurrent->item;
  320. delete pCurrent;
  321. size--;
  322. return pResult;
  323. }
  324. short
  325. Dictionary::Dict_GetList(
  326. gplistmgr & ListIter )
  327. {
  328. pUserType pN;
  329. Dict_Status Status;
  330. short Count = 0;
  331. // Get to the top of the dictionary.
  332. Status = Dict_Next( (pUserType)0 );
  333. // make sure we start with a clean iterator
  334. ITERATOR_DISCARD( ListIter );
  335. // Iterate till the entire dictionary is looked at.
  336. while( SUCCESS == Status )
  337. {
  338. pN = Dict_Curr_Item();
  339. ListIter.Insert( pN );
  340. Count++;
  341. Status = Dict_Next( pN );
  342. }
  343. return Count;
  344. }
  345. // Utility functions to print of a tree
  346. #ifndef DICT_NOPRINT
  347. static indentCur;
  348. static PrintFN printCur;
  349. static char spaces[] =
  350. " ";
  351. void
  352. Dictionary::PrinTree( // recursively print out a tree
  353. int lmargin, // current depth & margen
  354. TreeNode *np // subtree to print
  355. ) //-----------------------------------------------------------------------//
  356. {
  357. if (np == Nil)
  358. return;
  359. PrinTree(lmargin+indentCur, np->right);
  360. if (lmargin > sizeof(spaces))
  361. lmargin = sizeof(spaces);;
  362. spaces[lmargin] = 0;
  363. printf(spaces);
  364. spaces[lmargin] = ' ';
  365. Print(np->item);
  366. printf("\n");
  367. PrinTree(lmargin+indentCur, np->left);
  368. }
  369. void
  370. Dictionary::Dict_Print(
  371. long indent
  372. // prints the binary tree (indented right subtree,
  373. // followed by the root, followed by the indented right dubtree)
  374. ) //-----------------------------------------------------------------------//
  375. {
  376. indentCur = indent;
  377. PrinTree(0, root);
  378. }
  379. #endif // DICT_PRINT