README.TXT
DICT 
 
 
The DICT program demonstrates use of the implicit_handle, context_handle,  
in, and out attributes. 
 
SUMMARY 
======= 
 
This sample program is an example of a non-trivial local application  
converted to a distributed RPC application. 
 
The local program is a character-oriented "play" program, which lets a 
user insert, delete, and iterate over a dictionary. The dictionary is 
based on splay trees, which are printed out in a format described below. 
 
We remoted the basic program by taking the interface to the dictionary 
(given in dict0.h) and creating an interface to a remote dictionary, 
(given in replay.idl) which is remoted using RPC. 
 
Following the local dictionary interface, which is minimal and uniform, 
the remote interface is also uniform. However, since the local dictionary 
is generic (can store any item type, using void* pointers to items), 
the interface needed to change to deal with predefined (Record) type 
items in order to be remoted using the Microsoft RPC system. Also, 
since the local implementation allows a "peek" at the root of the tree 
using a DICT_CURR_ITEM macro, the whole interface needed to change. 
 
Remote dictionaries are represented by context handles to demonstrate 
the use of [context_handle]. Context handles are currently initialized 
using a global primitive handle [implicit_handle]. 
 
State was added to remote dictionaries in order to allow sharing them, 
and maintain reference counts. At this time, however, access to shared 
dictionaries is *not* serialized! By default each client gets his own 
copy of the dictionaries. To use shared dictionaries, start the client 
using the -s switch. 
 
The use of context to maintain state is also demonstrated by 
differentiating between a private iterator, activated by "n" for "next" 
and "p" for "previous", and a global shared iterator, activated by "N" 
for "Next" and "P" for previous. To start iterators, use "h" - go to 
the "head" of the dictionary, or "t" - go to the "tail" of the dictionary. 
The private iterator can be reset to DICT_CURR_ITEM using "r". 
 
FILES 
===== 
 
The directory samples\rpc\dict contains the following files for building 
the DICT distributed application: 
 
File          Description 
 
README.TXT    Readme file for the DICT sample 
REPLAY.IDL    Interface definition language file 
REPLAY.ACF    Attribute configuration file 
CLIENT.C      Client main program 
SERVER.C      Server main program 
PLAY.C 
PLAY.H 
UTIL0.C 
UTIL0.H 
DICT0.C 
DICT0.H 
REPLAY.C 
MAKEFILE      Nmake file to build for Windows NT or Windows 95 
MAKEFILE.DOS  Nmake file to build for MS-DOS 
 
------------------------------------ 
Building on Windows NT or Windows 95 
------------------------------------ 
 
The following environment variables should be already set for you: 
 
  set CPU=i386 
  set INCLUDE=%SDKROOT%\h 
  set LIB=%SDKROOT%\lib 
  set PATH=%SDKROOT%\system32;%SDKROOT%\bin 
 
where %SDKROOT% is the root directory for the 32-bit Windows SDK. 
 
For mips, set CPU=mips 
For alpha, set CPU=alpha 
 
Build the sample distributed application: 
 
  nmake cleanall 
  nmake 
 
------------------------------------------ 
Building the client application for MS-DOS 
------------------------------------------ 
 
After installing the Microsoft Visual C/C++ version 1.50 development 
environment and the 16-bit RPC SDK on a Windows NT or Windows 95 
computer, you can build the sample client application from Windows NT 
or Windows 95: 
 
  nmake -f makefile.dos cleanall 
  nmake -f makefile.dos 
 
This builds the client application client.exe. 
 
You may also execute the Microsoft Visual C/C++ compiler under MS-DOS. 
This requires a two-step build process. 
 
  Step One: Compile the .IDL files under Windows NT or Windows 95: 
 
     nmake -a -f makefile.dos replay.h 
 
  Step Two: Compile the C sources (stub and application) under MS-DOS: 
 
     nmake -f makefile.dos 
 
Using the program: 
------------------ 
 
To use the local dictionary example, type "play". 
 
To use the remote versiom, type "server" on the server side. On the client  
side, for each client use "client" for a fresh,private copy of the  
dictionary, or "client -s" for a shared copy of the dictionary. The  
following command line options are available on the client side. 
 
Options: 
-------- 
 
The -? displays the following message: 
 
Usage : client [-s] [-n <server>] [-v <view_option>] 
 
The -s option is used for using a shared version of the dictionary. 
    If none exist, a fresh shared version is created. 
 
The -v<option> is used for getting different views of the dictionary: 
    -v normal (default) - default view of the dictionary 
    (see explanation below) 
    -v flat - Flat printout 
    -v rev (or -v reverse) - reverses the tree to print left subtree first 
    followed by the node, followed by the right subtree, at every level 
 
The -n <server_name> is used for specifying a server machine.  Without it 
    the server is assumed to run on the same machine. 
 
    If you use the -n option you have to make sure that the server is 
    ready to receive calls; that is you have to start the server, by typing: 
 
    -> server 
 
    to the console, even if the server is your own machine. 
 
Program structure: 
================== 
 
Basic application: 
------------------ 
 
  dict0.h + dict0.c - These files contain a basic generic dictionary 
    implementation, based on Self Adjusting Trees (Splay trees), 
    invented by Sleator and Tarjan. In the remote dictionary 
    application (replay) the generic dictionary code runs on the server, 
    which maintains a data base to be shared by clients. 
 
    Note that the generic dictionary data structures contain untyped 
    pointers ((void)*), and thus require a special layer of typed trees 
    (strongly typed tree nodes) containing items of RPC-able types 
    in order to convert the local dictionary package and distribute it 
    using the Microsoft RPC system, and particularly the MIDL compiler. 
 
    If you are interested in RPC (as opposed to splay trees) treat 
    the generic dictionary as a "black box", and ignore the implementation 
    details. Otherwise, you are probably looking at the wrong README 
    file (and should read Tarjan and Sleators paper first anyhow...) 
 
Local dictionary: 
----------------- 
 
  play.h + play.c - These files contain a simple character-oriented 
    interactive demo / test program for the dictionary. 
 
Remote dictionary: 
------------------ 
 
  replay.idl - The Interface Definition Language (IDL) file contains: 
 
    o type definitions for the remotable objects required (such as the 
      Record item type, RecordTreeNode, etc) 
 
    o the context handle definition (a (void)* in this case) providing 
      a handle on a remote dictionary 
 
    o the signatures for the remote dictionary operations 
 
  replay.acf - An Attribute Configuration File (ACF), used here to 
    specify the initial binding method. We use implicit_binding to 
    bind to the server initially, and to initialize the context handle. 
 
  replay.c - This file contains the implementation of the remote, or 
    virtual, dictionary (VDict_...) operations. These are required 
    only on the server side, and are replaced by caller stubs 
    (in replay_c.c) on the client side. 
 
Utlities: 
--------- 
 
  util0.h + util0.c - These files contain utility routines used by both 
    the client and server applications to allocate and to free dictionaries 
    and trees, as well as pretty-print routines, used to print trees on 
    both sides. See description of the user interface portion below for 
    further discussion of the tree printing format. 
 
Client side: 
------------ 
 
  client.c - This file contains the driver of the client side program. 
    The client binds to the server, initializes a dictionary, and activates 
    a context handle for the dictionary on the server side. It then goes 
    into a test loop which prints the dictionary tree and prompts the user 
    for additional input by printing the following usage message: 
 
Usage: 
Type a single character, followed by an optional key as follows: 
 
    i <key> :: Insert <key> into dictionary 
    d <key> :: Delete <key> from dictionary 
    f <key> :: Find <key> in dictionary 
    N       :: next of current item in dictionary 
    P       :: previous of current item in dictionary 
    n       :: Next of local current item in dictionary 
    p       :: Previous of local current item in dictionary 
    h       :: Head (first item) of dictionary 
    t       :: Tail (last item) of dictionary 
    ?       :: Print this message 
    q       :: Quit 
 
where <key> is <integer> <string> 
 
next op (i d x f n N p P h t ? q): 
 
Server side: 
------------ 
 
  server.c - This file contains a pretty standard server main loop for 
    the remote dictionary "replay" demo. 
 
Tree print format: 
------------------ 
 
The tree printing routine prints the keys in a binary search tree using 
the following "prinTree" recursive algorithm: 
 
    prinTree (right subtree, with current indentation + one "tab"); 
    print the key at the root (with current indentation); 
    prinTree (left subtree, with current indentation + one "tab"); 
 
Keys are a pair of the form <integer, string>.  Assume the following tree: 
 
 
                           ----------- 
                           |0 : jack | 
                           ----------- 
                          /           \ 
                     ----------      ----------- 
                     |0 : don |      |0 : jane | 
                     ----------      ----------- 
                     /       \ 
                    /         \ 
               -----------  ---------- 
               |0 : adam |  |0 : eve | 
               -----------  ---------- 
 
The above print algorithm would print it as follows: 
 
 
        0 : jane 
    0 : jack 
            0 : eve 
        0 : don 
            0 : adam 
 
The left child of a node is printed on the first line following the node 
which is indented by one more tab then the given node. 
The right child of a node is printed on the last line preceding the node 
which is indented by one more tab then the given node. 
If you tilt your hand to the left while examining the printed tree format, 
it closely resembles the "traditional" format of a rooted binary tree. 
 
Known Limitations: 
------------------ 
 
Shared dictionaries are unprotected, so serialized access to the 
dictionary is assumed. Use at your own risk.