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

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

unix.superglobalmegacorp.com

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