Annotation of mstools/samples/rpc/dict/replay.c, revision 1.1.1.2

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: /*************************************************************************/
                     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;
1.1.1.2 ! root      281:     Record * curr_record;
1.1       root      282: 
                    283:     if ( (pdict == NULL) || DICT_EMPTY(pdict) ) {
                    284:         status = EMPTY_DICTIONARY;
                    285:         *item = NULL; }
                    286:     else {
                    287:         // old code uses DICT_CURR_ITEM as iterator state
                    288:         // status = Dict_Next(pdict, DICT_CURR_ITEM(pdict));
                    289:         // *item = DICT_CURR_ITEM(pdict);
                    290: 
                    291:         // update RDICT_CURR_RECORD(pdict)
                    292:         status = Dict_Next(pdict, RDICT_CURR_RECORD(pdict));
                    293:         ItemCopy(DICT_CURR_ITEM(pdict), RDICT_CURR_RECORD(pdict));
                    294:         *item = DICT_CURR_ITEM(pdict);
                    295:     }
                    296:     *item = ItemDuplicate(*item);
                    297:     return( (VDict_Status)status );
                    298: }
                    299: 
                    300: VDict_Status
                    301: VDict_Curr_Prev(
                    302:     IN VDict  v_dict,
                    303:     OUT Record ** item
                    304:     )
                    305: // get predecessor of RDICT_CURR_RECORD(v_dict),
                    306: // and update *item to point to it (global iterator prev)
                    307: {
                    308:     Dictionary * pdict = (Dictionary*) (v_dict);
                    309:     RDict * prdict = (RDict*) pdict; // for debug ease...
                    310:     Dict_Status status;
1.1.1.2 ! root      311:     Record * curr_record;
1.1       root      312: 
                    313:     if ( (pdict == NULL) || DICT_EMPTY(pdict) ) {
                    314:         status = EMPTY_DICTIONARY;
                    315:         *item = NULL; }
                    316:     else {
                    317:         // update RDICT_CURR_RECORD(pdict)
                    318:         status = Dict_Prev(pdict, RDICT_CURR_RECORD(pdict));
                    319:         ItemCopy(DICT_CURR_ITEM(pdict), RDICT_CURR_RECORD(pdict));
                    320:         *item = DICT_CURR_ITEM(pdict);
                    321:     }
                    322:     *item = ItemDuplicate(*item);
                    323:     return( (VDict_Status)status );
                    324: }
                    325: 
                    326: VDict_Status
                    327: VDict_Insert(
                    328:     IN VDict  v_dict,
                    329:     IN Record * item
                    330:     )
                    331: {
                    332:     Dictionary * pdict = (Dictionary*) (v_dict);
                    333:     Dict_Status status;
                    334:     Record * rp = makeRecord(item->key, item->name);
                    335: 
                    336:     status = Dict_Insert(pdict, rp); // No return value required.
                    337:     return( (VDict_Status)status );
                    338: }
                    339: 
                    340: VDict_Status
                    341: VDict_Delete(
                    342:     IN VDict  v_dict,
                    343:     IN OUT Record ** item
                    344:     )
                    345: {
                    346:     Dictionary * pdict = (Dictionary*) (v_dict);
                    347:     Dict_Status status;
                    348: 
                    349:     status = Dict_Delete(pdict, (void **)item); // (*item) is returned by Dict_Delete!
                    350:     // *item = ItemDuplicate(*item);
                    351:     // no need to duplicate *item: deleted items need to be deallocated.
                    352:     return( (VDict_Status)status );
                    353: }
                    354: 
                    355: VDict_Status
                    356: VDict_Curr_Item(
                    357:     IN VDict  v_dict,
                    358:     OUT Record ** item
                    359:     )
                    360: {
                    361:     Dictionary * pdict = (Dictionary*) (v_dict);
                    362:     Dict_Status status;
                    363: 
                    364:     if ( (pdict == NULL) || DICT_EMPTY(pdict) ) {
                    365:         status = EMPTY_DICTIONARY;
                    366:         *item = NULL; }
                    367:     else {
                    368:         status = SUCCESS;
                    369:         *item = DICT_CURR_ITEM(pdict);
                    370:     }
                    371:     *item = ItemDuplicate(*item);
                    372:     return( (VDict_Status)status );
                    373: }
                    374: 
                    375: VDict_Status
                    376: VDict_Curr_Delete(
                    377:     IN VDict  v_dict,
                    378:     OUT Record ** item
                    379:     )
                    380: {
                    381:     Dictionary * pdict = (Dictionary*) (v_dict);
                    382:     Dict_Status status;
                    383: 
                    384:     if ( (pdict == NULL) || DICT_EMPTY(pdict) ) {
                    385:         status = EMPTY_DICTIONARY;
                    386:         *item = NULL; }
                    387:     else {
                    388:         *item = DICT_CURR_ITEM(pdict);
                    389:        status = Dict_Delete( pdict, (void **)item );
                    390:     }
                    391:     // *item = ItemDuplicate(*item);
                    392:     // no need to duplicate *item: deleted items need to be deallocated.
                    393:     return( (VDict_Status)status );
                    394: }
                    395: 
                    396: VDict_Status
                    397: VDict_Get_Dict(
                    398:     IN VDict  v_dict,
                    399:     OUT RDict ** r_dict
                    400:     )
                    401: //  used to transmit the dictionary back to the callee
                    402: //  (In this demo program - for printing on the client side)
                    403: {
                    404:     Dictionary * pdict = (Dictionary*) (v_dict);
                    405:     RDict * prdict = (RDict*)pdict;  // debug...
                    406: 
                    407:     if (pdict == NULL) return(DICT_EMPTY_DICTIONARY);
                    408:     else {
                    409:         prinTree (0, 3, pdict->root, printRecord);
                    410: 
                    411:         *r_dict = RDict_Duplicate((RDict*)pdict);
                    412:             // Duplication is done to avoid freeing the tree by
                    413:             // the callee stub.  This is a temporary fix, until we
                    414:             // implement [allocate(dont_free)]!
                    415: 
                    416:         return(DICT_SUCCESS);
                    417:     }
                    418: }
                    419: 
                    420: /*************************************************************************/
                    421: /***                        Server Utility Functions                   ***/
                    422: /*************************************************************************/
                    423: 
                    424: void
                    425: Init_dict(Dictionary * dp)
                    426: {
                    427:     Record* rp;
                    428: 
                    429: /*
                    430: */
1.1.1.2 ! root      431:     rp = makeRecord((short)0, "jack_smith"); Dict_Insert(dp, rp);
        !           432:     rp = makeRecord((short)0, "john_doe"); Dict_Insert(dp, rp);
        !           433:     rp = makeRecord((short)1, "steve_johnson"); Dict_Insert(dp, rp);
        !           434:     rp = makeRecord((short)2, "debbie_jones"); Dict_Insert(dp, rp);
        !           435:     rp = makeRecord((short)0, "mike_jacobs"); Dict_Insert(dp, rp);
        !           436:     rp = makeRecord((short)2, "bill_jackson"); Dict_Insert(dp, rp);
        !           437:     rp = makeRecord((short)0, "jane_doe"); Dict_Insert(dp, rp);
        !           438:     rp = makeRecord((short)1, "james_doe"); Dict_Insert(dp, rp);
        !           439:     rp = makeRecord((short)1, "jean_doe"); Dict_Insert(dp, rp);
        !           440:     rp = makeRecord((short)0, "joana_smith"); Dict_Insert(dp, rp);
        !           441:     rp = makeRecord((short)1, "michael_jones"); Dict_Insert(dp, rp);
        !           442:     rp = makeRecord((short)0, "dianne_jackson"); Dict_Insert(dp, rp);
        !           443:     rp = makeRecord((short)0, "jacob_jacobson"); Dict_Insert(dp, rp);
1.1       root      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;
1.1.1.2 ! root      461:     Dict_Status status;
1.1       root      462: 
                    463:     if (DICT_EMPTY(prdict))
                    464:         return(DICT_EMPTY_DICTIONARY);
                    465: 
                    466:     RecordTreeNodeFree(prdict->root);
                    467:     prdict->root = NULL;
                    468:         return(DICT_SUCCESS);
                    469: }
                    470: 
                    471: VDict_Status
                    472: VDict_I_Dict(
                    473:     IN VDict  v_dict,
                    474:     IN short  size
                    475:     )
                    476: // Insert integers from 3 to a specified upper bound into the tree
                    477: {
                    478:     // Dictionary * pdict = (Dictionary*) (v_dict);
                    479:     RDict * prdict = (RDict*)v_dict;
                    480:     Dict_Status status;
                    481:     short i;
                    482: 
                    483:     // Insert (<num'>, "") for all num' s.t. 3 < num' < num
                    484: 
                    485:     for (i=3; i < size; i++) {
                    486:         status = VDict_Insert(
                    487:             prdict,
1.1.1.2 ! root      488:             makeRecord(i, "<")
1.1       root      489:             );
                    490:         }
                    491:     return( (VDict_Status)status );
                    492: }

unix.superglobalmegacorp.com

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