|
|
1.1 root 1: /*************************************************************/
1.1.1.2 root 2: /** **/
3: /** Microsoft RPC Examples **/
4: /** Dictionary Application **/
1.1.1.3 ! root 5: /** Copyright(c) Microsoft Corp. 1992 **/
1.1.1.2 root 6: /** **/
1.1 root 7: /*************************************************************/
8:
9: Overview:
10: ---------
11:
12: This demo is a an example a non trivial local application to RPC.
13: The local program is a character oriented "play" program, which lets a
14: user insert, delete, and iterate over a dictionary. The dictionary is
15: based on splay trees, which are printed out in a format described below.
16:
17: We remoted the basic program by taking the interface to the dictionary
18: (given in dict0.h) and creating an interface to a remote dictionary,
19: (given in replay.idl) which is remoted using RPC.
20:
21: Following the local dictionary interface. which is minimal and uniform,
22: the remote interface is also uniform. However, since the local dictionary
23: is generic (can store any item type, using void* pointers to items),
24: the interface needed to change to deal with predefined (Record) type
25: items in order to be remoted using the Microsoft RPC system. Also,
26: since the local implementation allows a "peek" at the root of the tree
27: using a DICT_CURR_ITEM macro, the whole interface achanged needed a to
28: change.
29:
30: Remote dictionaries are represented by context handles to demonstrate
31: the use of [context_handle]. Context handles are currently initialized
32: using a global primitive handle [implicit_handle].
33:
34: State was added to remote dictionaries in order to allow sharing them,
1.1.1.3 ! root 35: and maintain reference counts. At this time, however, access to shared
! 36: dictionaries is *not* serialized! By default each client gets his own
! 37: copy of the dictionaries. To use shared dictionaries, start the client
! 38: using the -s switch.
1.1 root 39:
40: The use of context to maintain state is also demonstrated by
41: differenciating between a private iterator, activated by "n" for "next"
42: and "p" for "previous", and a global shared iterator activated by "N"
43: for "Next" and "P" for previous. To start iterators, use "h" - go to
44: the "head" of the dictionary, or "t" - go to the "tail" of the dictionary.
45: The private iterator can be reset to DICT_CURR_ITEM using "r".
46:
47: Building on Windows/NT
48: ----------------------
49:
1.1.1.3 ! root 50: The following environment variables should be set for you already.
! 51: set CPU=i386
! 52: set INCLUDE=c:\mstools\h
! 53: set LIB=c:\mstools\lib
! 54: set PATH=c:c:\winnt\system32;\mstools\bin;
! 55:
! 56: For mips, set CPU=mips
! 57:
! 58: Build the sample distributed application:
! 59: nmake cleanall
! 60: nmake
1.1.1.2 root 61:
1.1.1.3 ! root 62: Building on MS-DOS
! 63: ------------------
1.1 root 64:
1.1.1.3 ! root 65: After you install the Microsoft C/C++ version 7.0
! 66: development environment and the Microsoft RPC version
! 67: 1.0 toolkit on an MS-DOS or Microsoft Windows computer,
! 68: you can build the sample client application for MS-DOS.
! 69: Enter:
! 70:
! 71: nmake -f makefile.dos cleanall
! 72: nmake -f makefile.dos
! 73:
1.1 root 74: Using the program:
75: ------------------
76:
77: To use the local dictionary example, type "play".
78:
1.1.1.3 ! root 79: To use the remote versiom, type "server" on the server side.
! 80: On the client side, for each client use "client" for a fresh,
! 81: private copy of the dictionary, or "client -s" for a shared copy
! 82: of the dictionary. The following command line options are
! 83: available on the client side.
1.1 root 84:
85: Options:
86: --------
87:
88: The -? displays the following message:
89:
1.1.1.3 ! root 90: Usage : client [-s] [-n <server>] [-v <view_option>]
1.1 root 91:
1.1.1.3 ! root 92: The -s option is used for using a shared version of the dictionary.
! 93: If none exist, a fresh shared version is created.
1.1 root 94:
95: The -v<option> is used for getting different views of the dictionary:
1.1.1.3 ! root 96: -v normal (default) - default view of the dictionary
! 97: (see explanation below)
! 98: -v flat - Flat printout
! 99: -v rev (or -v reverse) - reversese the tree to print left subtree first
1.1 root 100: followed by the node, followed by the right subtree, at every level
101:
1.1.1.3 ! root 102: The -n <server_name> is used for specifying a server machine. Without it
1.1 root 103: the server is assumed to run on the same machine.
104:
1.1.1.3 ! root 105: If you use the -n option you have to make sure that the server is
1.1 root 106: ready to receive calls; that is you have to start the server, by typing
107:
108: -> server
109:
110: to the console, even if the server is your own machine!
111:
112: Program structure:
113: ==================
114:
115: Basic application:
116: ------------------
117:
118: dict0.h + dict0.c - These files contain a basic generic dictionary
119: implementation, based on Self Adjusting Trees (Splay trees),
120: invented by Sleator and Tarjan. In the remote dictionary
121: application (replay) the generic dictionary code runs on the server,
122: which maintains a data base to be shared by clients.
123:
124: Note that the generic dictionary data structures contain untyped
125: pointers ((void)*), and thus require a special layer of typed trees
126: (strongly typed tree nodes) containing items of RPC-able types
127: in order to convert the local dictionary package and distribute it
128: using the Microsoft RPC system, and particularly the MIDL compiler.
129:
130: If you are interested in RPC (as opposed to splay trees) treat
131: the generic dictionary as a "black box", and ignore the implementation
132: details. Otherwise, you are probably looking at the wrong README
133: file (and should read Tarjan and Sleators paper first anyhow...)
134:
135: Local dictionary:
136: -----------------
137:
138: play.h + play.c - These files contain a simple character oriented
139: interactive demo / test program for the dictionary.
140:
141: Remote dictionary:
142: ------------------
143:
144: replay.idl - The Interface Definition Language (IDL) file contains:
145:
146: o type definitions for the remotable objects required (such as the
147: Record item type, RecordTreeNode, etc)
148:
149: o the context handle definition (a (void)* in this case) providing
150: a handle on a remote dictionary
151:
152: o the signatures for the remote dictionary operations
153:
154: replay.acf - An Attribute Configuration File (ACF), used here to
155: specify the initial binding method. We use implicit_binding to
156: bind to the server initially, and to initialize the context handle.
157:
158: replay.c - This file contains the implementation of the remote, or
159: virtual, dictionary (VDict_...) operations. These are required
160: only on the server side, and are replaced by caller stubs
161: (in replay_c.c) on the client side.
162:
163: Utlities:
164: ---------
165:
166: util0.h + util0.c - These files contain utility routines used by both
167: the client and server applications allocate and to free dictionaries
168: and trees, as well as pretty-print routines, used to print trees on
169: both sides. See description of the user interface portion below for
170: further discussion of the tree printing format.
171:
172: Client side:
173: ------------
174:
175: client.c - This file contains the driver of the client side program.
176: The client binds to the server, initializes a dictionary, and activates
177: a context handle for the dictionary on the server side. It then goes
178: into a test loop which prints the dictionary tree and prompts the user
179: for additional input by printing the following usage message:
180:
1.1.1.2 root 181: Usage:
182: Type a single character, followed by an optional key as follows:
1.1 root 183:
184: i <key> :: Insert <key> into dictionary
185: d <key> :: Delete <key> from dictionary
186: f <key> :: Find <key> in dictionary
1.1.1.2 root 187: N :: next of current item in dictionary
188: P :: previous of current item in dictionary
189: n :: Next of local current item in dictionary
190: p :: Previous of local current item in dictionary
191: h :: Head (first item) of dictionary
192: t :: Tail (last item) of dictionary
193: ? :: Print this message
194: q :: Quit
195:
196: where <key> is <integer> <string>
1.1 root 197:
1.1.1.2 root 198: next op (i d x f n N p P h t ? q):
1.1 root 199:
200: Server side:
201: ------------
202:
203: server.c - This file contains a pretty standard server main loop for
204: the remote dictionary "replay" demo.
205:
206: Tree print format:
207: ------------------
208:
209: The tree printing routine prints the keys in a binary search tree using
210: the following "prinTree" recursive algorithm:
211:
212: prinTree (right subtree, with current indentation + one "tab");
213: print the key at the root (with current indentation);
214: prinTree (left subtree, with current indentation + one "tab");
215:
216: Keys are a pair of the form <integer, string>. Assume the following tree:
217:
218:
219: -----------
220: |0 : jack |
221: -----------
222: / \
223: ---------- -----------
224: |0 : don | |0 : jane |
225: ---------- -----------
226: / \
227: / \
228: ----------- ----------
229: |0 : adam | |0 : eve |
230: ----------- ----------
231:
232: The above print algorithm would print it as follows:
233:
234:
235: 0 : jane
236: 0 : jack
237: 0 : eve
238: 0 : don
239: 0 : adam
240:
241: The left child of a node is printed on the first line following the node
242: with is indented by one more tab then the given node.
243: The right child of a node is printed on the last line preceding the node
244: with is indented by one more tab then the given node.
245: If you tilt your hand to the left while examining the printed tree format
246: it closely resembles the "traditional" format of a rooted binary tree.
247:
248: Known Limitations:
249: ------------------
250:
251: Shared dictionaries are unprotected, so serialized access to the
252: dictionary is assumed. Use at your own risk :)
253:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.