Annotation of mstools/samples/rpc/dict/replay.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: /*************************************************************************/
        !            10: /***  Example dictionary using splay trees:                            ***/
        !            11: /***  Created: 12/88 - Dov Harel                                       ***/
        !            12: /***                                                                   ***/
        !            13: /***  Modified:                                                        ***/
        !            14: /***                                                                   ***/
        !            15: /***  Dov Harel - 11/10/90, Use "strong types" for remoting            ***/
        !            16: /***  Dov Harel - 11/14/90, Changed interface to demonstrate local vs. ***/
        !            17: /***                        remote iterators.  Modified allocation and ***/
        !            18: /***                        deallocation for remoting the dictionary.  ***/
        !            19: /***  Dov Harel -     5/91, Made it work again.  Changed iterators,    ***/
        !            20: /***                        duplicate nodes and trees.  Added state,   ***/
        !            21: /***                        ref counts, and a -s switch for optional   ***/
        !            22: /***                        sharing of dictionaries.                   ***/
        !            23: /***                        (not yet serialized!)                      ***/
        !            24: /***                                                                   ***/
        !            25: /*************************************************************************/
        !            26: 
        !            27: #include <stdio.h>
        !            28: #include <malloc.h>
        !            29: #include <stdlib.h>
        !            30: #include <string.h>
        !            31: #include "rpc.h"
        !            32: 
        !            33: #include "dict0.h"
        !            34: #include "replay.h"
        !            35: #include "util0.h"
        !            36: 
        !            37: #define TAB_STOPS 3
        !            38: 
        !            39: /*************************************************************************/
        !            40: /***                   Declarations (from replay.h)                    ***/
        !            41: /*************************************************************************/
        !            42: 
        !            43: /*
        !            44: typedef struct _Record {
        !            45:     short key;                      // RPC "generation"
        !            46:     [string] char* name;            // contributor
        !            47: } Record;
        !            48: 
        !            49: typedef struct _RecordTreeNode RecordTreeNode;
        !            50: 
        !            51: typedef struct _RecordTreeNode {
        !            52:     RecordTreeNode *left;           // left child pointer
        !            53:     RecordTreeNode *right;          // right child pointer
        !            54:     Record *item;                   // pointer to a Record structure
        !            55: } RecordTreeNode;
        !            56: 
        !            57: typedef struct _RDict {
        !            58:     RecordTreeNode *root;           // pointer to the root of a SAT
        !            59:     long size;                      // number of records in dictionary
        !            60: } RDict;
        !            61: 
        !            62: // RDict is used for marshalling a complete dictionary.
        !            63: 
        !            64: typedef enum {
        !            65:     DICT_SUCCESS,
        !            66:     DICT_ITEM_ALREADY_PRESENT,
        !            67:     DICT_ITEM_NOT_FOUND,
        !            68:     DICT_FIRST_ITEM,
        !            69:     DICT_LAST_ITEM,
        !            70:     DICT_EMPTY_DICTIONARY,
        !            71:     DICT_NULL_ITEM
        !            72: }
        !            73: VDict_Status;
        !            74: 
        !            75: typedef struct _DictState {
        !            76:     short ref_count;               // for shared dictionaries
        !            77:     Record * curr_record;          // for global iterators
        !            78: } DictState;
        !            79: */
        !            80: 
        !            81: /*************************************************************************/
        !            82: /***                   Internal state access methods                   ***/
        !            83: /*************************************************************************/
        !            84: 
        !            85: #define RDICT_CURR_RECORD(dict) (((DictState*)dict->state)->curr_record)
        !            86: 
        !            87: #define RDICT_REF_COUNT(dict) (((DictState*)dict->state)->ref_count)
        !            88: 
        !            89: #define RDICT_STATE(dict) (((RDict*)dict)->state)
        !            90: 
        !            91: static int active_dictionary = 0;
        !            92: 
        !            93: /*************************************************************************/
        !            94: /***    Generic Dictionary Operations: (From dict0.h)                  ***/
        !            95: /***                                                                   ***/
        !            96: /***    Dictionary *Dict_New(Cmp_rec*, Splay*, print_rec*)             ***/
        !            97: /***                                                                   ***/
        !            98: /***    Dict_Status Dict_Find(Dictionary*, Item*)                      ***/
        !            99: /***    Dict_Status Dict_Next(Dictionary*, Item*)                      ***/
        !           100: /***    Dict_Status Dict_Prev(Dictionary*, Item*)                      ***/
        !           101: /***    Dict_Status Dict_Insert(Dictionary*, Item*)                    ***/
        !           102: /***    Dict_Status Dict_Delete(Dictionary*, Item**)                   ***/
        !           103: /***                                                                   ***/
        !           104: /***    Item* DICT_CURR_ITEM(Dict*)                                    ***/
        !           105: /*************************************************************************/
        !           106: 
        !           107: /*************************************************************************/
        !           108: /***    Virtual Dictionary Operations: (From replay.h)                 ***/
        !           109: /***                                                                   ***/
        !           110: /***    VDict_Status VDict_New(OUT VDict **)                           ***/
        !           111: /***                                                                   ***/
        !           112: /***    VDict_Status VDict_Find(IN VDict*, IN OUT Record**)            ***/
        !           113: /***    VDict_Status VDict_Next(IN VDict*, IN OUT Record**)            ***/
        !           114: /***    VDict_Status VDict_Prev(IN VDict*, IN OUT Record**)            ***/
        !           115: /***    VDict_Status VDict_Insert(IN VDict*, IN Record*)               ***/
        !           116: /***    VDict_Status VDict_Delete(IN VDict*, IN OUT Record**)          ***/
        !           117: /***                                                                   ***/
        !           118: /***    VDict_Status VDict_Curr_Item(IN VDict*, OUT Record**);         ***/
        !           119: /***    VDict_Status VDict_Curr_Delete(IN VDict*, OUT Record**);       ***/
        !           120: /***    VDict_Status VDict_Curr_Next(IN VDict*, OUT Record**);         ***/
        !           121: /***    VDict_Status VDict_Curr_Prev(IN VDict*, OUT Record**);         ***/
        !           122: /***                                                                   ***/
        !           123: /***    VDict_Status VDict_Get_Dict(IN VDict*, OUT RDict**)            ***/
        !           124: /*************************************************************************/
        !           125: 
        !           126: /*************************************************************************/
        !           127: /***                   context rundown routine                         ***/
        !           128: /*************************************************************************/
        !           129: 
        !           130: void VDict_rundown (VDict v_dict)
        !           131: {
        !           132:     Dictionary * pdict = (Dictionary*) v_dict;
        !           133:     short count = --RDICT_REF_COUNT(pdict);
        !           134: 
        !           135:     printf("# of remaining users of context: %d\n\n",
        !           136:         RDICT_REF_COUNT(pdict) );
        !           137: 
        !           138:     if ( RDICT_REF_COUNT(pdict) <= 0) {
        !           139:         printf("CLOSING CONTEXT\n\n");
        !           140: 
        !           141:         // free the splay tree
        !           142:         RDict_Free_Dict(v_dict);
        !           143: 
        !           144:         // free the dictionary object
        !           145:         free_state( (DictState*) pdict->state );
        !           146:         MIDL_user_free( v_dict );
        !           147:         if ( count == 0)
        !           148:             active_dictionary = 0;
        !           149:     }
        !           150: }
        !           151: 
        !           152: //  For now: need to allocate a new item record prior to operation,
        !           153: //  for all OUT and IN OUT arguments, as the callee stub will free
        !           154: //  storage allocated for such pointer parameters.
        !           155: //
        !           156: //  Will be fixed by the introduction of [allocate(dont_free)]
        !           157: //  ACF pointer type and parameter attribute.
        !           158: 
        !           159: /**************************************************************************
        !           160:  * VDict_New initializes a new dictionary if (1) a non shared dictionary
        !           161:  * was requested, or (2) a shared dictionary was requested, but no shared
        !           162:  * dictionary is currently active.  There is at most one shared dictionary
        !           163:  * at any point in time.
        !           164:  *
        !           165:  * BUGBUG: shared dictionaries are *NOT* locked (by semaphore, to
        !           166:  * serialize access to them.  They *should be, though...
        !           167:  **************************************************************************
        !           168: */
        !           169: 
        !           170: VDict_Status
        !           171: VDict_New(
        !           172:   IN short shared_dict,
        !           173:   OUT VDict * v_dict
        !           174:   )
        !           175: {
        !           176:     Dictionary * pdict0;
        !           177:     static Dictionary * pdict;
        !           178: 
        !           179:     if (!active_dictionary  || !shared_dict) {
        !           180:         /* server side dictionary initialization */
        !           181:         pdict0 = Dict_New(comp, tdSplay, printRecord);
        !           182: 
        !           183:         ((RDict*)pdict0)->state = allocate_state();
        !           184:         // The above assignment initializes RDICT_CURR_RECORD(pdict0)
        !           185:         // to "minus infinity" in the order
        !           186: 
        !           187:         Init_dict(pdict0);
        !           188:         *v_dict = (VDict)pdict0;
        !           189: 
        !           190:         if (shared_dict) {
        !           191:             printf("OPENING SHARED DICTIONARY CONTEXT!\n\n");
        !           192:             active_dictionary = 1;
        !           193:             pdict = pdict0;
        !           194:             RDICT_REF_COUNT(pdict)++;
        !           195:         } // else RDICT_REF_COUNT(pdict0) = 0;
        !           196:     }
        !           197:     else {
        !           198:         RDICT_REF_COUNT(pdict)++;
        !           199:         printf("# of users of shared context: %d\n\n", RDICT_REF_COUNT(pdict));
        !           200:         *v_dict = (VDict)pdict;
        !           201:     }
        !           202: 
        !           203:     return(DICT_SUCCESS);
        !           204: }
        !           205: 
        !           206: VDict_Status
        !           207: VDict_Find(
        !           208:     IN VDict  v_dict,
        !           209:     IN OUT Record ** item
        !           210:     )
        !           211: {
        !           212:     Dictionary * pdict = (Dictionary*) (v_dict);
        !           213:     Dict_Status status;
        !           214: 
        !           215:     status = Dict_Find(pdict, *item);
        !           216:     if ( (pdict == NULL) || DICT_EMPTY(pdict) ) {
        !           217:         *item = NULL; }
        !           218:     else {
        !           219:         *item = DICT_CURR_ITEM(pdict);
        !           220:         *item = ItemDuplicate(*item);
        !           221:     }
        !           222:     return( (VDict_Status)status );
        !           223: }
        !           224: 
        !           225: VDict_Status
        !           226: VDict_Next(
        !           227:     IN VDict  v_dict,
        !           228:     IN OUT Record ** item
        !           229:     )
        !           230: // get successor of *item, and update *item to point to it
        !           231: {
        !           232:     Dictionary * pdict = (Dictionary*) (v_dict);
        !           233:     Dict_Status status;
        !           234: 
        !           235:     status = Dict_Next(pdict, *item);
        !           236:     if ( (pdict == NULL) || DICT_EMPTY(pdict) ) {
        !           237:         *item = NULL; }
        !           238:     else {
        !           239:         if (*item == NULL)
        !           240:             ItemCopy(DICT_CURR_ITEM(pdict), RDICT_CURR_RECORD(pdict));
        !           241:         *item = DICT_CURR_ITEM(pdict);
        !           242:     }
        !           243:     *item = ItemDuplicate(*item);
        !           244:     return( (VDict_Status)status );
        !           245: }
        !           246: 
        !           247: VDict_Status
        !           248: VDict_Prev(
        !           249:     IN VDict  v_dict,
        !           250:     IN OUT Record ** item
        !           251:     )
        !           252: // get predecessor of *item, and update *item to point to it
        !           253: {
        !           254:     Dictionary * pdict = (Dictionary*) (v_dict);
        !           255:     RDict * prdict = (RDict*)pdict;  // debug...
        !           256:     Dict_Status status;
        !           257: 
        !           258:     status = Dict_Prev(pdict, *item);
        !           259:     if ( (pdict == NULL) || DICT_EMPTY(pdict) ) {
        !           260:         *item = NULL; }
        !           261:     else {
        !           262:         if (*item == NULL)
        !           263:             ItemCopy(DICT_CURR_ITEM(pdict), RDICT_CURR_RECORD(pdict));
        !           264:         *item = DICT_CURR_ITEM(pdict);
        !           265:     }
        !           266:     *item = ItemDuplicate(*item);
        !           267:     return( (VDict_Status)status );
        !           268: }
        !           269: 
        !           270: VDict_Status
        !           271: VDict_Curr_Next(
        !           272:     IN VDict  v_dict,
        !           273:     OUT Record ** item
        !           274:     )
        !           275: // get successor of RDICT_CURR_RECORD(v_dict),
        !           276: // and update *item to point to it (global iterator prev)
        !           277: {
        !           278:     Dictionary * pdict = (Dictionary*) (v_dict);
        !           279:     RDict * prdict = (RDict*) pdict; // for debug ease...
        !           280:     Dict_Status status;
        !           281: 
        !           282:     if ( (pdict == NULL) || DICT_EMPTY(pdict) ) {
        !           283:         status = EMPTY_DICTIONARY;
        !           284:         *item = NULL; }
        !           285:     else {
        !           286:         // old code uses DICT_CURR_ITEM as iterator state
        !           287:         // status = Dict_Next(pdict, DICT_CURR_ITEM(pdict));
        !           288:         // *item = DICT_CURR_ITEM(pdict);
        !           289: 
        !           290:         // update RDICT_CURR_RECORD(pdict)
        !           291:         status = Dict_Next(pdict, RDICT_CURR_RECORD(pdict));
        !           292:         ItemCopy(DICT_CURR_ITEM(pdict), RDICT_CURR_RECORD(pdict));
        !           293:         *item = DICT_CURR_ITEM(pdict);
        !           294:     }
        !           295:     *item = ItemDuplicate(*item);
        !           296:     return( (VDict_Status)status );
        !           297: }
        !           298: 
        !           299: VDict_Status
        !           300: VDict_Curr_Prev(
        !           301:     IN VDict  v_dict,
        !           302:     OUT Record ** item
        !           303:     )
        !           304: // get predecessor of RDICT_CURR_RECORD(v_dict),
        !           305: // and update *item to point to it (global iterator prev)
        !           306: {
        !           307:     Dictionary * pdict = (Dictionary*) (v_dict);
        !           308:     RDict * prdict = (RDict*) pdict; // for debug ease...
        !           309:     Dict_Status status;
        !           310: 
        !           311:     if ( (pdict == NULL) || DICT_EMPTY(pdict) ) {
        !           312:         status = EMPTY_DICTIONARY;
        !           313:         *item = NULL; }
        !           314:     else {
        !           315:         // update RDICT_CURR_RECORD(pdict)
        !           316:         status = Dict_Prev(pdict, RDICT_CURR_RECORD(pdict));
        !           317:         ItemCopy(DICT_CURR_ITEM(pdict), RDICT_CURR_RECORD(pdict));
        !           318:         *item = DICT_CURR_ITEM(pdict);
        !           319:     }
        !           320:     *item = ItemDuplicate(*item);
        !           321:     return( (VDict_Status)status );
        !           322: }
        !           323: 
        !           324: VDict_Status
        !           325: VDict_Insert(
        !           326:     IN VDict  v_dict,
        !           327:     IN Record * item
        !           328:     )
        !           329: {
        !           330:     Dictionary * pdict = (Dictionary*) (v_dict);
        !           331:     Dict_Status status;
        !           332:     Record * rp = makeRecord(item->key, item->name);
        !           333: 
        !           334:     status = Dict_Insert(pdict, rp); // No return value required.
        !           335:     return( (VDict_Status)status );
        !           336: }
        !           337: 
        !           338: VDict_Status
        !           339: VDict_Delete(
        !           340:     IN VDict  v_dict,
        !           341:     IN OUT Record ** item
        !           342:     )
        !           343: {
        !           344:     Dictionary * pdict = (Dictionary*) (v_dict);
        !           345:     Dict_Status status;
        !           346: 
        !           347:     status = Dict_Delete(pdict, (void **)item); // (*item) is returned by Dict_Delete!
        !           348:     // *item = ItemDuplicate(*item);
        !           349:     // no need to duplicate *item: deleted items need to be deallocated.
        !           350:     return( (VDict_Status)status );
        !           351: }
        !           352: 
        !           353: VDict_Status
        !           354: VDict_Curr_Item(
        !           355:     IN VDict  v_dict,
        !           356:     OUT Record ** item
        !           357:     )
        !           358: {
        !           359:     Dictionary * pdict = (Dictionary*) (v_dict);
        !           360:     Dict_Status status;
        !           361: 
        !           362:     if ( (pdict == NULL) || DICT_EMPTY(pdict) ) {
        !           363:         status = EMPTY_DICTIONARY;
        !           364:         *item = NULL; }
        !           365:     else {
        !           366:         status = SUCCESS;
        !           367:         *item = DICT_CURR_ITEM(pdict);
        !           368:     }
        !           369:     *item = ItemDuplicate(*item);
        !           370:     return( (VDict_Status)status );
        !           371: }
        !           372: 
        !           373: VDict_Status
        !           374: VDict_Curr_Delete(
        !           375:     IN VDict  v_dict,
        !           376:     OUT Record ** item
        !           377:     )
        !           378: {
        !           379:     Dictionary * pdict = (Dictionary*) (v_dict);
        !           380:     Dict_Status status;
        !           381: 
        !           382:     if ( (pdict == NULL) || DICT_EMPTY(pdict) ) {
        !           383:         status = EMPTY_DICTIONARY;
        !           384:         *item = NULL; }
        !           385:     else {
        !           386:         *item = DICT_CURR_ITEM(pdict);
        !           387:        status = Dict_Delete( pdict, (void **)item );
        !           388:     }
        !           389:     // *item = ItemDuplicate(*item);
        !           390:     // no need to duplicate *item: deleted items need to be deallocated.
        !           391:     return( (VDict_Status)status );
        !           392: }
        !           393: 
        !           394: VDict_Status
        !           395: VDict_Get_Dict(
        !           396:     IN VDict  v_dict,
        !           397:     OUT RDict ** r_dict
        !           398:     )
        !           399: //  used to transmit the dictionary back to the callee
        !           400: //  (In this demo program - for printing on the client side)
        !           401: {
        !           402:     Dictionary * pdict = (Dictionary*) (v_dict);
        !           403:     RDict * prdict = (RDict*)pdict;  // debug...
        !           404: 
        !           405:     if (pdict == NULL) return(DICT_EMPTY_DICTIONARY);
        !           406:     else {
        !           407:         prinTree (0, 3, pdict->root, printRecord);
        !           408: 
        !           409:         *r_dict = RDict_Duplicate((RDict*)pdict);
        !           410:             // Duplication is done to avoid freeing the tree by
        !           411:             // the callee stub.  This is a temporary fix, until we
        !           412:             // implement [allocate(dont_free)]!
        !           413: 
        !           414:         return(DICT_SUCCESS);
        !           415:     }
        !           416: }
        !           417: 
        !           418: /*************************************************************************/
        !           419: /***                        Server Utility Functions                   ***/
        !           420: /*************************************************************************/
        !           421: 
        !           422: void
        !           423: Init_dict(Dictionary * dp)
        !           424: {
        !           425:     Record* rp;
        !           426: 
        !           427:     printf ("in Init_dict\n");
        !           428: 
        !           429: /*
        !           430: */
        !           431:     rp = makeRecord(0, "jack_smith"); Dict_Insert(dp, rp);
        !           432:     rp = makeRecord(0, "john_doe"); Dict_Insert(dp, rp);
        !           433:     rp = makeRecord(1, "steve_johnson"); Dict_Insert(dp, rp);
        !           434:     rp = makeRecord(2, "debbie_jones"); Dict_Insert(dp, rp);
        !           435:     rp = makeRecord(0, "mike_jacobs"); Dict_Insert(dp, rp);
        !           436:     rp = makeRecord(2, "bill_jackson"); Dict_Insert(dp, rp);
        !           437:     rp = makeRecord(0, "jane_doe"); Dict_Insert(dp, rp);
        !           438:     rp = makeRecord(1, "james_doe"); Dict_Insert(dp, rp);
        !           439:     rp = makeRecord(1, "jean_doe"); Dict_Insert(dp, rp);
        !           440:     rp = makeRecord(0, "joana_smith"); Dict_Insert(dp, rp);
        !           441:     rp = makeRecord(1, "michael_jones"); Dict_Insert(dp, rp);
        !           442:     rp = makeRecord(0, "dianne_jackson"); Dict_Insert(dp, rp);
        !           443:     rp = makeRecord(0, "jacob_jacobson"); Dict_Insert(dp, rp);
        !           444: 
        !           445:     Dict_Print(dp, TAB_STOPS);
        !           446: }
        !           447: 
        !           448: /*************************************************************************/
        !           449: /***                        Play oriented Functions ...                ***/
        !           450: /*** (used to empty the tree and replace it by a tree of integers      ***/
        !           451: /*************************************************************************/
        !           452: 
        !           453: VDict_Status
        !           454: VDict_X_Dict(
        !           455:     IN VDict  v_dict
        !           456:     )
        !           457: // Empty the dictionary
        !           458: {
        !           459:     // Dictionary * pdict = (Dictionary*) (v_dict);
        !           460:     RDict * prdict = (RDict*)v_dict;
        !           461: 
        !           462:     if (DICT_EMPTY(prdict))
        !           463:         return(DICT_EMPTY_DICTIONARY);
        !           464: 
        !           465:     RecordTreeNodeFree(prdict->root);
        !           466:     prdict->root = NULL;
        !           467:         return(DICT_SUCCESS);
        !           468: }
        !           469: 
        !           470: VDict_Status
        !           471: VDict_I_Dict(
        !           472:     IN VDict  v_dict,
        !           473:     IN short  size
        !           474:     )
        !           475: // Insert integers from 3 to a specified upper bound into the tree
        !           476: {
        !           477:     // Dictionary * pdict = (Dictionary*) (v_dict);
        !           478:     RDict * prdict = (RDict*)v_dict;
        !           479:     Dict_Status status;
        !           480:     short i;
        !           481: 
        !           482:     // Insert (<num'>, "") for all num' s.t. 3 < num' < num
        !           483: 
        !           484:     for (i=3; i < size; i++) {
        !           485:         status = VDict_Insert(
        !           486:             prdict,
        !           487:             makeRecord(i, "")
        !           488:             );
        !           489:         }
        !           490:     return( (VDict_Status)status );
        !           491: }

unix.superglobalmegacorp.com

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