|
|
1.1 root 1: /*************************************************************/
2: /** **/
3: /** Microsoft RPC Examples **/
4: /** Dictionary Application **/
5: /** Copyright(c) Microsoft Corp. 1991 **/
6: /** **/
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,
35: and maintain reference counts. At this time, however, access to shared
36: dictionaries is *not* serialized! By default each client gets his own copy
37: of the dictionaries. To use shared dictionaries, start the client using
38: the -s switch.
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:
50: On an Windows NT PDK machine type to the console:
51:
52: -> nmake cleanall
53: -> nmake all
54:
55: To remove only object files type:
56:
57: -> nmake clean
58:
59: To build in the NT development environment:
60:
61: -> nmake NTENV= all
62:
63: Using the program:
64: ------------------
65:
66: To use the local dictionary example, type "play".
67:
68: To use the remote versiom, type "server" on the server side. On the client
69: side, for each client use "client" for a fresh, private copy of the
70: dictionary, or "client -s" for a shared copy of the dictionary. The
71: following command line options are available on the client side.
72:
73: Options:
74: --------
75:
76: The -? displays the following message:
77:
78: Usage : client [-s] [-m<machine>] [-v<view_option>]
79:
80: The -s option is used for using a shared version of the dictionary. If
81: none exist, a fresh shared version is created.
82:
83: The -v<option> is used for getting different views of the dictionary:
84: -vnormal (default) - default view of the dictionary (see explanation
85: below)
86: -vflat - Flat printout
87: -vrev (or -vreverse) - reversese the tree to print left subtree first
88: followed by the node, followed by the right subtree, at every level
89:
90: The -m<machine_name> is used for specifying a server machine. Without it
91: the server is assumed to run on the same machine.
92:
93: If you use the -m option you have to make sure that the server is
94: ready to receive calls; that is you have to start the server, by typing
95:
96: -> net start server
97: -> server
98:
99: to the console, even if the server is your own machine!
100:
101: Program structure:
102: ==================
103:
104: Basic application:
105: ------------------
106:
107: dict0.h + dict0.c - These files contain a basic generic dictionary
108: implementation, based on Self Adjusting Trees (Splay trees),
109: invented by Sleator and Tarjan. In the remote dictionary
110: application (replay) the generic dictionary code runs on the server,
111: which maintains a data base to be shared by clients.
112:
113: Note that the generic dictionary data structures contain untyped
114: pointers ((void)*), and thus require a special layer of typed trees
115: (strongly typed tree nodes) containing items of RPC-able types
116: in order to convert the local dictionary package and distribute it
117: using the Microsoft RPC system, and particularly the MIDL compiler.
118:
119: If you are interested in RPC (as opposed to splay trees) treat
120: the generic dictionary as a "black box", and ignore the implementation
121: details. Otherwise, you are probably looking at the wrong README
122: file (and should read Tarjan and Sleators paper first anyhow...)
123:
124: Local dictionary:
125: -----------------
126:
127: play.h + play.c - These files contain a simple character oriented
128: interactive demo / test program for the dictionary.
129:
130: Remote dictionary:
131: ------------------
132:
133: replay.idl - The Interface Definition Language (IDL) file contains:
134:
135: o type definitions for the remotable objects required (such as the
136: Record item type, RecordTreeNode, etc)
137:
138: o the context handle definition (a (void)* in this case) providing
139: a handle on a remote dictionary
140:
141: o the signatures for the remote dictionary operations
142:
143: replay.acf - An Attribute Configuration File (ACF), used here to
144: specify the initial binding method. We use implicit_binding to
145: bind to the server initially, and to initialize the context handle.
146:
147: replay.c - This file contains the implementation of the remote, or
148: virtual, dictionary (VDict_...) operations. These are required
149: only on the server side, and are replaced by caller stubs
150: (in replay_c.c) on the client side.
151:
152: Utlities:
153: ---------
154:
155: util0.h + util0.c - These files contain utility routines used by both
156: the client and server applications allocate and to free dictionaries
157: and trees, as well as pretty-print routines, used to print trees on
158: both sides. See description of the user interface portion below for
159: further discussion of the tree printing format.
160:
161: Client side:
162: ------------
163:
164: client.c - This file contains the driver of the client side program.
165: The client binds to the server, initializes a dictionary, and activates
166: a context handle for the dictionary on the server side. It then goes
167: into a test loop which prints the dictionary tree and prompts the user
168: for additional input by printing the following usage message:
169:
170: Usage:
171: Type a single character, followed by an optional key as follows:
172:
173: i <key> :: Insert <key> into dictionary
174: d <key> :: Delete <key> from dictionary
175: f <key> :: Find <key> in dictionary
176: N :: next of current item in dictionary
177: P :: previous of current item in dictionary
178: n :: Next of local current item in dictionary
179: p :: Previous of local current item in dictionary
180: h :: Head (first item) of dictionary
181: t :: Tail (last item) of dictionary
182: ? :: Print this message
183: q :: Quit
184:
185: <key> is <integer> <string>");
186:
187: Server side:
188: ------------
189:
190: server.c - This file contains a pretty standard server main loop for
191: the remote dictionary "replay" demo.
192:
193: Tree print format:
194: ------------------
195:
196: The tree printing routine prints the keys in a binary search tree using
197: the following "prinTree" recursive algorithm:
198:
199: prinTree (right subtree, with current indentation + one "tab");
200: print the key at the root (with current indentation);
201: prinTree (left subtree, with current indentation + one "tab");
202:
203: Keys are a pair of the form <integer, string>. Assume the following tree:
204:
205:
206: -----------
207: |0 : jack |
208: -----------
209: / \
210: / \
211: ---------- -----------
212: |0 : don | |0 : jane |
213: ---------- -----------
214: / \
215: / \
216: ----------- ----------
217: |0 : adam | |0 : eve |
218: ----------- ----------
219:
220: The above print algorithm would print it as follows:
221:
222:
223: 0 : jane
224: 0 : jack
225: 0 : eve
226: 0 : don
227: 0 : adam
228:
229: The left child of a node is printed on the first line following the node
230: with is indented by one more tab then the given node.
231: The right child of a node is printed on the last line preceding the node
232: with is indented by one more tab then the given node.
233: If you tilt your hand to the left while examining the printed tree format
234: it closely resembles the "traditional" format of a rooted binary tree.
235:
236: Known Limitations:
237: ------------------
238:
239: Shared dictionaries are unprotected, so serialized access to the
240: dictionary is assumed. Use at your own risk :)
241:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.