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.