Annotation of mstools/samples/rpc/dict/dict0.c, revision 1.1

1.1     ! root        1: /*************************************************************/
        !             2: /**                                                         **/
        !             3: /**                 Microsoft RPC Examples                  **/
        !             4: /**                 Dictionary Application                  **/
        !             5: /**             Copyright(c) Microsoft Corp. 1991           **/
        !             6: /**                                                         **/
        !             7: /*************************************************************/
        !             8: 
        !             9: #include <stdio.h>
        !            10: #include <malloc.h>
        !            11: #include <stdlib.h>
        !            12: #include <string.h>
        !            13: #include <ctype.h>
        !            14: #include <windows.h>
        !            15: 
        !            16: #include <rpc.h>
        !            17: #include "dict0.h"
        !            18: 
        !            19: /************************************************************************/
        !            20: TreeNode Dumbo;
        !            21: // volatile
        !            22: TreeNode *Dummy = &Dumbo;      // a global dummy node
        !            23: 
        !            24: #define ROTATELEFT tmp=t->right; t->right=tmp->left; tmp->left=t; t=tmp
        !            25: #define ROTATERIGHT tmp=t->left; t->left=tmp->right; tmp->right=t; t=tmp
        !            26: #define LINKLEFT tmp=t; t=t->right; l=l->right=tmp
        !            27: #define LINKRIGHT tmp=t; t=t->left; r=r->left=tmp
        !            28: #define ASSEMBLE r->left=t->right; l->right=t->left; \
        !            29:                  t->left=Dummy->right; t->right=Dummy->left
        !            30: /************************************************************************/
        !            31: 
        !            32: /************************************************************************
        !            33:  Basic structure declarations from dict0.h:
        !            34: 
        !            35: typedef struct tnode {
        !            36:     struct tnode *left;     // left child pointer
        !            37:     struct tnode *right;    // right child pointer
        !            38:     void *item;             // pointer to some structure
        !            39: } TreeNode;
        !            40: 
        !            41: typedef struct dictnode {
        !            42:     TreeNode *root;                 // pointer to the root of a SAT
        !            43:     long size;                      // number of records in dictionary
        !            44:     void * state;                   // reserved for state info
        !            45:     // int (*cmp_rec)(void *, void *); comparison function pointer
        !            46:     cmp_rec_func cmp_rec;
        !            47:     TreeNode* (*splay)(TreeNode *, void *, cmp_rec_func);
        !            48:                                     // pointer to a splay function
        !            49:     void (*print_rec)(void *);      // one line print function
        !            50: } Dictionary;
        !            51: 
        !            52: #define DICT_CURR_ITEM(pDict) pDict->root->item
        !            53: 
        !            54: typedef enum {
        !            55:     SUCCESS,
        !            56:     ITEM_ALREADY_PRESENT,
        !            57:     ITEM_NOT_FOUND,
        !            58:     FIRST_ITEM,
        !            59:     LAST_ITEM,
        !            60:     EMPTY_DICTIONARY,
        !            61:     NULL_ITEM
        !            62: }
        !            63: Dict_Status;
        !            64: **************************************************************************/
        !            65: 
        !            66: 
        !            67: /*************************************************************************/
        !            68: /***                MIDL_user_allocate / MIDL_user_free                ***/
        !            69: /*************************************************************************/
        !            70: 
        !            71: void *
        !            72: MIDL_user_allocate(unsigned long count);
        !            73: 
        !            74: void
        !            75: MIDL_user_free(void * p);
        !            76: 
        !            77: /*************************************************************************/
        !            78: /***    Minimal Dictionary Operations:                                 ***/
        !            79: /***                                                                   ***/
        !            80: /***    Dictionary *Dict_New(Cmp_rec*, Splay*, print_rec*)             ***/
        !            81: /***                                                                   ***/
        !            82: /***    Dict_Status Dict_Find(Dictionary*, Item*)                      ***/
        !            83: /***    Dict_Status Dict_Next(Dictionary*, Item*)                      ***/
        !            84: /***    Dict_Status Dict_Prev(Dictionary*, Item*)                      ***/
        !            85: /***    Dict_Status Dict_Insert(Dictionary*, Item*)                    ***/
        !            86: /***    Dict_Status Dict_Delete(Dictionary*, Item**)                   ***/
        !            87: /***                                                                   ***/
        !            88: /***    Item* DICT_CURR_ITEM(Dict*)                                    ***/
        !            89: /*************************************************************************/
        !            90: 
        !            91: #define TreeNode_New(pnode, pitem) pnode = \
        !            92:     (TreeNode*) MIDL_user_allocate (sizeof(TreeNode)); \
        !            93:     pnode->left = pnode->right = NULL; pnode->item = pitem;
        !            94: 
        !            95: Dictionary*
        !            96: Dict_New(                    // returns a new dictionary node
        !            97:     int (*cmp_rec)           // pointer to item comparison function
        !            98:         (void *, void *),
        !            99:     TreeNode* (*splay)       // pointer to a splay function
        !           100:         (TreeNode *, void *, cmp_rec_func),
        !           101:     void (*print_rec)        // pointer to one line item print routine
        !           102:         (void *) )
        !           103: {
        !           104:     Dictionary* dp;
        !           105:     dp = (Dictionary*)MIDL_user_allocate(sizeof(Dictionary));
        !           106:     dp->root = NULL;
        !           107:     dp->size = 0;
        !           108:     dp->state = NULL;
        !           109:     dp->print_rec = print_rec;
        !           110:     dp->splay = splay;
        !           111:     dp->cmp_rec = cmp_rec;
        !           112:     return(dp);
        !           113: }
        !           114: 
        !           115: 
        !           116: Dict_Status
        !           117: Dict_Find(
        !           118:     Dictionary* dp,     // Dictionary to be searched.
        !           119:     void* item)         // Item searched for.
        !           120: {
        !           121:     int keycmp;
        !           122:     TreeNode* t;
        !           123: 
        !           124:     if (dp->root == NULL) return (EMPTY_DICTIONARY);
        !           125:     if (item == NULL) return(NULL_ITEM);
        !           126:     t = dp->root = dp->splay(dp->root, item, dp->cmp_rec);
        !           127:     keycmp = (dp->cmp_rec)( t->item, item );
        !           128:     if (keycmp != 0)
        !           129:         return(ITEM_NOT_FOUND);
        !           130:     else return(SUCCESS);
        !           131: }
        !           132: 
        !           133: Dict_Status
        !           134: Dict_Next(
        !           135:     Dictionary* dp,     // Dictionary to be searched.
        !           136:     void* item)         // A Key item.  Advance to successor of item in dp.
        !           137: {
        !           138:     TreeNode* t;
        !           139:     int keycmp;
        !           140: 
        !           141:     if (dp->root == NULL) return (EMPTY_DICTIONARY);
        !           142:     if (item == NULL) { dp->root = tdSplayLeft(dp->root);
        !           143:         return(SUCCESS);
        !           144:     }
        !           145:     if (item == DICT_CURR_ITEM(dp)) {
        !           146:         t = dp->root;
        !           147:         keycmp = 0; }
        !           148:     else {
        !           149:         dp->root = t = dp->splay(dp->root, item, dp->cmp_rec);
        !           150:         keycmp = (dp->cmp_rec)( item, t->item );
        !           151:     }
        !           152:     if (keycmp < 0)
        !           153:         return(SUCCESS);
        !           154:     else if (t->right == NULL) {
        !           155:         return(LAST_ITEM); }
        !           156:     else {
        !           157:         t = dp->root;
        !           158:         dp->root = tdSplayLeft(t->right);
        !           159:         dp->root->left = t;
        !           160:         t->right = NULL;
        !           161:         return(SUCCESS);
        !           162:     }
        !           163: }
        !           164: 
        !           165: Dict_Status
        !           166: Dict_Prev(
        !           167:     Dictionary* dp,     // Dictionary to be searched.
        !           168:     void* item)         // A Key item.  Retreat to predecessor of item in dp.
        !           169: {
        !           170:     TreeNode* t;
        !           171:     int keycmp;
        !           172: 
        !           173:     if (dp->root == NULL) return (EMPTY_DICTIONARY);
        !           174:     if (item == NULL) { dp->root = tdSplayRight(dp->root);
        !           175:         return(SUCCESS);
        !           176:     }
        !           177:     if (item == DICT_CURR_ITEM(dp)) {
        !           178:         t = dp->root;
        !           179:         keycmp = 0; }
        !           180:     else {
        !           181:         dp->root = t = dp->splay(dp->root, item, dp->cmp_rec);
        !           182:         keycmp = (dp->cmp_rec)( item, t->item );
        !           183:     }
        !           184:     if (keycmp > 0)
        !           185:         return(SUCCESS);
        !           186:     else if (t->left == NULL) {
        !           187:         return(FIRST_ITEM); }
        !           188:     else {
        !           189:         t = dp->root;
        !           190:         dp->root = tdSplayRight(t->left);
        !           191:         dp->root->right = t;
        !           192:         t->left = NULL;
        !           193:         return(SUCCESS);
        !           194:     }
        !           195: }
        !           196: 
        !           197: Dict_Status
        !           198: Dict_Insert(            // insert the given item into the tree
        !           199:     Dictionary* dp,     // the modified dictionary
        !           200:     void* item)         // the item to be inserted
        !           201: {
        !           202:     int keycmp;
        !           203:     TreeNode *t, *newNode;
        !           204: 
        !           205:     if (item == NULL) return(NULL_ITEM);
        !           206:     if (dp->root == NULL) {
        !           207:         TreeNode_New(newNode, item);
        !           208:         dp->root = newNode;
        !           209:         dp->size++;
        !           210:         return(SUCCESS);
        !           211:     }
        !           212:     t = dp->root = dp->splay(dp->root, item, dp->cmp_rec);
        !           213:     keycmp = (dp->cmp_rec)( t->item, item );
        !           214:     if (keycmp == 0)
        !           215:         return(ITEM_ALREADY_PRESENT);
        !           216: 
        !           217:     TreeNode_New(newNode, item);
        !           218:     if (keycmp < 0) {   // t->item < item
        !           219:         newNode->right = t->right;
        !           220:         t->right = NULL;
        !           221:         newNode->left = t; }
        !           222:     else {
        !           223:         newNode->left = t->left;
        !           224:         t->left = NULL;
        !           225:         newNode->right = t;
        !           226:     }
        !           227:     dp->root = newNode;
        !           228:     dp->size++;
        !           229:     return(SUCCESS);
        !           230: }
        !           231: 
        !           232: 
        !           233: Dict_Status
        !           234: Dict_Delete(            // delete the given item into from the tree
        !           235:     Dictionary* dp,     // the modified dictionary
        !           236:     void** pItem)       // IN: points to the (key) item to be deleted
        !           237:                         // OUT: points to the item just deleted
        !           238: {
        !           239:     TreeNode *t, *r;
        !           240:     int keycmp;
        !           241:     void* item = *pItem;
        !           242:     t = dp->root;
        !           243: 
        !           244:     if (item == NULL) return(NULL_ITEM);
        !           245:     if (dp->root == NULL) return (EMPTY_DICTIONARY);
        !           246:     if (item == DICT_CURR_ITEM(dp))
        !           247:         keycmp = 0;
        !           248:     else {
        !           249:         dp->root = t = dp->splay(dp->root, item, dp->cmp_rec);
        !           250:         keycmp = (dp->cmp_rec)( item, t->item );
        !           251:     }
        !           252:     if (keycmp != 0)
        !           253:         return(ITEM_NOT_FOUND);
        !           254:     *pItem = DICT_CURR_ITEM(dp);
        !           255: 
        !           256:     if (t->left == NULL) {
        !           257:         dp->root = t->right; }
        !           258:     else if ( (r = t->right) == NULL) {
        !           259:         dp->root = t->left; }
        !           260:     else  {
        !           261:         r = tdSplayLeft(r);
        !           262:         // at this point r->left == NULL
        !           263:         r->left = t->left;
        !           264:         dp->root = r;
        !           265:     }
        !           266:     t->left = t->right = t->item = NULL;
        !           267:     MIDL_user_free(t);
        !           268:     dp->size--;
        !           269:     return(SUCCESS);
        !           270: }
        !           271: 
        !           272: 
        !           273: /*************************************************************************/
        !           274: /*****              Core functions (internal)                        *****/
        !           275: /*************************************************************************/
        !           276: 
        !           277: TreeNode *              // returns the new root
        !           278: tdSplay(                // general top down splay
        !           279:     TreeNode *root,     // the current root of the tree
        !           280:     void *keyItem,      // pointer to a "key item" searched for
        !           281:     int (*cmp)(void *, void *) )
        !           282:                         // pointer to a comparison function
        !           283: {
        !           284:     TreeNode* t=root;   // current search point
        !           285:     TreeNode* l;        // root of "left subtree" < keyItem
        !           286:     TreeNode* r;        // root of "right subtree" > keyItem
        !           287:     int kcmpt, kcmpleft, kcmpright;
        !           288:                         // cash comparison results
        !           289:     TreeNode* tmp;
        !           290: 
        !           291: /***/
        !           292:     Dummy = &Dumbo;
        !           293:     l = Dummy;
        !           294:     r = Dummy;
        !           295: /***/
        !           296: 
        !           297:     if ( (root == NULL) || ((*cmp)(keyItem, root->item) == 0) ) return (root);
        !           298:     Dummy->left=Dummy->right=NULL;
        !           299:     while ( (kcmpt = (*cmp)(keyItem, t->item)) != 0 ) {
        !           300:         if ( kcmpt < 0 ) {
        !           301:             if ( t->left == NULL ) break;
        !           302:             if ( (kcmpleft = (*cmp)(keyItem, t->left->item)) == 0 ) {
        !           303:                 LINKRIGHT; }
        !           304:             else if ( kcmpleft < 0 ) {
        !           305:                 ROTATERIGHT;
        !           306:                 if ( t->left != NULL ) {
        !           307:                     LINKRIGHT; } }
        !           308:             else { // keyItem > t->left->item
        !           309:                 LINKRIGHT;
        !           310:                 if ( t->right != NULL ) {
        !           311:                     LINKLEFT; } } }
        !           312:         else { // keyItem > t->item
        !           313:             if ( t->right == NULL ) break;
        !           314:             if ( (kcmpright = (*cmp)(keyItem, t->right->item)) == 0 ) {
        !           315:                 LINKLEFT; }
        !           316:             else if ( kcmpright > 0 ) {
        !           317:                 ROTATELEFT;
        !           318:                 if ( t->right != NULL ) {
        !           319:                     LINKLEFT; } }
        !           320:             else { // keyItem < t->right->item
        !           321:                 LINKLEFT;
        !           322:                 if ( t->left != NULL ) {
        !           323:                     LINKRIGHT; } }
        !           324:         }
        !           325:     }
        !           326:     // assemble:
        !           327:         r->left=t->right; l->right=t->left;
        !           328:         t->left=Dummy->right; t->right=Dummy->left;
        !           329:         return(t);
        !           330: }
        !           331: 
        !           332: TreeNode*
        !           333: tdSplayLeft(TreeNode* root)
        !           334: {
        !           335:     TreeNode* t=root;   // current "search" point
        !           336:     TreeNode* l=Dummy;  // root of "left subtree" < keyItem
        !           337:     TreeNode* r=Dummy;  // root of "right subtree" > keyItem
        !           338:     TreeNode* tmp;
        !           339: 
        !           340:     if ((t == NULL) || (t->left == NULL)) return(t);
        !           341:     if (t->left->left == NULL) {
        !           342:         ROTATERIGHT; return(t); }
        !           343:     Dummy->left=Dummy->right=NULL;
        !           344:     while ( t->left != NULL ) {
        !           345:         ROTATERIGHT;
        !           346:         if ( t->left != NULL ) {
        !           347:             LINKRIGHT; }
        !           348:     }
        !           349:     r->left=t->right; l->right=t->left;
        !           350:     t->left=Dummy->right; t->right=Dummy->left;
        !           351:     return(t);
        !           352: }
        !           353: 
        !           354: TreeNode*
        !           355: tdSplayRight(TreeNode* root)
        !           356: {
        !           357:     TreeNode* t=root;   // current "search" point
        !           358:     TreeNode* l=Dummy;  // root of "left subtree" < keyItem
        !           359:     TreeNode* r=Dummy;  // root of "right subtree" > keyItem
        !           360:     TreeNode* tmp;
        !           361: 
        !           362:     if ((t == NULL) || (t->right == NULL)) return(t);
        !           363:     Dummy->left=Dummy->right=NULL;
        !           364:     while ( t->right != NULL ) {
        !           365:         ROTATELEFT;
        !           366:         if ( t->right != NULL ) {
        !           367:             LINKLEFT; }
        !           368:     }
        !           369:     r->left=t->right; l->right=t->left;
        !           370:     t->left=Dummy->right; t->right=Dummy->left;
        !           371:     return(t);
        !           372: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.