1struct::pool(n)               Tcl Data Structures              struct::pool(n)
2
3
4
5______________________________________________________________________________
6

NAME

8       struct::pool - Create and manipulate pool objects (of discrete items)
9

SYNOPSIS

11       package require Tcl  8.2
12
13       package require struct::pool  ?1.2.3?
14
15       ::struct::pool ?poolName? ?maxsize?
16
17       poolName option ?arg arg ...?
18
19       poolName add itemName1 ?itemName2 itemName3 ...?
20
21       poolName clear ?-force?
22
23       poolName destroy ?-force?
24
25       poolName info type ?arg?
26
27       poolName maxsize ?maxsize?
28
29       poolName release itemName
30
31       poolName remove itemName ?-force?
32
33       poolName request itemVar ?options?
34
35______________________________________________________________________________
36

DESCRIPTION

38       This  package  provides pool objects which can be used to manage finite
39       collections of discrete items.
40
41       ::struct::pool ?poolName? ?maxsize?
42              Creates a new pool object. If no poolName is supplied, then  the
43              new  pool  will  be  named poolX, where X is a positive integer.
44              The optional second argument maxsize has to be a positive  inte‐
45              ger indicating the maximum size of the pool; this is the maximum
46              number of items the pool may hold. The default for this value is
47              10.
48
49              The  pool object has an associated global Tcl command whose name
50              is poolName. This command may be used to invoke various configu‐
51              ration  operations  on  the report. It has the following general
52              form:
53
54              poolName option ?arg arg ...?
55                     Option and the args determine the exact behavior  of  the
56                     command.  See  section POOL OBJECT COMMAND for a detailed
57                     list of options and their behaviour.
58

POOLS AND ALLOCATION

60       The purpose of the pool command and the pool  object  command  that  it
61       generates, is to manage pools of discrete items.  Examples of a pool of
62       discrete items are:
63
64       ·      the seats in a cinema, theatre,  train  etc..  for  which  visi‐
65              tors/travelers can  make a reservation;
66
67       ·      the  dynamic  IP-addresses  that  an  ISP  can dole out  to sub‐
68              scribers;
69
70       ·      a car rental's collection of cars, which can be rented  by  cus‐
71              tomers;
72
73       ·      the  class  rooms  in a school building, which need to be sched‐
74              uled;
75
76       ·      the database connections available to client-threads in  a  web-
77              server application;
78
79       ·      the books in a library that customers can borrow;
80
81       ·      etc ...
82
83       The  common denominator in the examples is that there is a more or less
84       fixed number of items (seats, IP-addresses, cars, ...)  that  are  sup‐
85       posed  to  be allocated on a more or less regular basis. An item can be
86       allocated only once at a time. An  item  that  is  allocated,  must  be
87       released  before it can be re-allocated.  While several items in a pool
88       are being allocated and released  continuously,  the  total  number  of
89       items in the pool remains constant.
90
91       Keeping track of which items are allocated, and by whom, is the purpose
92       of the pool command and its subordinates.
93
94       Pool parlance: If we say that an item is allocated, it means  that  the
95       item  is  busy,  owned  or occupied; it is not available anymore. If an
96       item is free, it is available. Deallocating an item  is  equivalent  to
97       setting  free  or  releasing an item. The person or entity to which the
98       item has been allotted is said to own the item.
99

ITEMS

101       Discrete items
102
103       The pool command is designed for discrete items only. Note  that  there
104       are  pools where allocation occurs on a non-discrete basis, for example
105       computer memory. There are also pools from which the  shares  that  are
106       doled  out  are not expected to be returned, for example a charity fund
107       or a pan of soup from which you may receive a portion.  Finally,  there
108       are even pools from which nothing is ever allocated or returned, like a
109       swimming pool or a cesspool.
110
111       Unique item names
112
113       A pool cannot manage duplicate item names. Therefore, items in  a  pool
114       must have unique names.
115
116       Item equivalence
117
118       From  the point of view of the manager of a pool, items are equivalent.
119       The manager of a pool is indifferent about which entity/person occupies
120       a  given  item.  However, clients may have preferences for a particular
121       item, based on some item property they know.
122
123       Preferences
124
125       A future owner may have a preference for a particular item.  Preference
126       based  allocation  is  supported (see the -prefer option to the request
127       subcommand). A preference for a  particular  item  is  most  likely  to
128       result  from variability among features associated with the items. Note
129       that the pool commands themselves are not designed to manage such  item
130       properties.  If  item  properties  play  a role in an application, they
131       should be managed separately.
132

POOL OBJECT COMMAND

134       The following subcommands and corresponding arguments are available  to
135       any pool object command.
136
137       poolName add itemName1 ?itemName2 itemName3 ...?
138              This  command adds the items on the command line to the pool. If
139              duplicate item names occur on the  command  line,  an  error  is
140              raised.  If  one or more of the items already exist in the pool,
141              this also is considered an error.
142
143       poolName clear ?-force?
144              Removes all items from the pool.  If  there  are  any  allocated
145              items  at  the  time  when  the  command is invoked, an error is
146              raised. This behaviour may be modified through the -force  argu‐
147              ment.  If  it  is supplied on the command line, the pool will be
148              cleared regardless the allocation state of its items.
149
150       poolName destroy ?-force?
151              Destroys the pool data structure, all associated  variables  and
152              the  associated  pool  object  command.  By default, the command
153              checks whether any items are still allocated and raises an error
154              if  such is the case. This behaviour may be modified through the
155              argument -force. If it is supplied on the command line, the pool
156              data  structure will be destroyed regardless allocation state of
157              its items.
158
159       poolName info type ?arg?
160              Returns various information about the pool for further  program‐
161              matic  use.  The type argument indicates the type of information
162              requested. Only the type allocID uses an additional argument.
163
164              allocID itemName
165                     returns the allocID of the item whose name  is  itemName.
166                     Free items have an allocation id of -1.
167
168              allitems
169                     returns a list of all items in the pool.
170
171              allocstate
172                     Returns a list of key-value pairs, where the keys are the
173                     items and the values  are  the  corresponding  allocation
174                     id's. Free items have an allocation id of -1.
175
176              cursize
177                     returns  the  current pool size, i.e. the number of items
178                     in the pool.
179
180              freeitems
181                     returns a list of items that currently are not allocated.
182
183              maxsize
184                     returns the maximum size of the pool.
185
186
187       poolName maxsize ?maxsize?
188              Sets or queries the maximum  size  of  the  pool,  depending  on
189              whether  the  maxsize argument is supplied or not. If maxsize is
190              supplied, the maximum size of the  pool  will  be  set  to  that
191              value.  If  no argument is supplied, the current maximum size of
192              the pool is returned. In this variant, the command is  an  alias
193              for:
194
195              poolName info maxsize.
196
197              The maxsize argument has to be a positive integer.
198
199       poolName release itemName
200              Releases the item whose name is itemName that was allocated pre‐
201              viously. An error is raised if the item was not allocated at the
202              time when the command was issued.
203
204       poolName remove itemName ?-force?
205              Removes  the  item  whose name is itemName from the pool. If the
206              item was allocated at the time when the command was invoked,  an
207              error  is  raised.  This  behaviour  may be modified through the
208              optional argument -force. If it is supplied on the command line,
209              the item will be removed regardless its allocation state.
210
211       poolName request itemVar ?options?
212              Handles  a  request  for an item, taking into account a possible
213              preference for a particular item. There are  two  possible  out‐
214              comes depending on the availability of items:
215
216              [1]    The  request  is  honoured,  an item is allocated and the
217                     variable whose name is passed with the  argument  itemVar
218                     will  be  set to the name of the item that was allocated.
219                     The command returns 1.
220
221              [2]    The request is denied. No item is allocated. The variable
222                     whose name is itemVar is not set.  Attempts to read item‐
223                     Var may raise an error if the variable  was  not  defined
224                     before issuing the request. The command returns 0.
225
226       The  return  values  from  this  command are meant to be inspected. The
227       examples below show how to do this. Failure to check the  return  value
228       may  result  in  erroneous behaviour. If no preference for a particular
229       item is supplied through the  option  -prefer  (see  below),  then  all
230       requests are honoured as long as items are available.
231
232       The following options are supported:
233
234              -allocID allocID
235                     If  the request is honoured, an item will be allocated to
236                     the entity identified by allocID. If the allocation state
237                     of an item is queried, it is this allocation ID that will
238                     be returned. If the option -allocID is not supplied,  the
239                     item  will  be  given to and owned by dummyID. Allocation
240                     id's may be  anything  except  the  value  -1,  which  is
241                     reserved for free items.
242
243              -prefer preferredItem
244                     This  option modifies the allocation strategy as follows:
245                     If the item whose name is preferredItem is not  allocated
246                     at  the  time when the command is invoked, the request is
247                     honoured (return value is 1). If the item  was  allocated
248                     at  the time when the command was invoked, the request is
249                     denied (return value is 0).
250

EXAMPLES

252       Two examples are provided. The first one mimics a step by step interac‐
253       tive  tclsh  session,  where each step is explained. The second example
254       shows the usage in a server application that talks to a back-end appli‐
255       cation.
256
257       Example 1
258
259       This  example presents an interactive tclsh session which considers the
260       case of a Car rental's collection of cars. Ten steps explain its  usage
261       in  chronological  order,  from  the creation of the pool, via the most
262       important stages in the usage of a pool, to the final destruction.
263
264       Note aside:
265
266       In this example, brand names are used to label the various items.  How‐
267       ever,  a brand name could be regarded as a property of an item. Because
268       the pool command is not designed to manage properties  of  items,  they
269       need  to  be managed separately. In the latter case the items should be
270       labeled with more neutral names such as: car1, car2, car3 , etc ... and
271       a  separate  database  or  array should hold the brand names associated
272       with the car labels.
273
274                   1. Load the package into an interpreter
275                   % package require pool
276                   0.1
277
278                   2. Create a pool object called `CarPool' with a maximum size of 55 items (cars):
279                   % pool CarPool 55
280                   CarPool
281
282                   4. Add items to the pool:
283                   % CarPool add Toyota Trabant Chrysler1 Chrysler2 Volkswagen
284
285                   5. Somebody crashed the Toyota. Remove it from the pool as follows:
286                   % CarPool remove Toyota
287
288                   6. Acquired a new car for the pool. Add it as follows:
289                   % CarPool add Nissan
290
291                   7. Check whether the pool was adjusted correctly:
292                   % CarPool info allitems
293                   Trabant Chrysler1 Chrysler2 Volkswagen Nissan
294
295
296       Suspend the interactive session temporarily, and show the  programmatic
297       use of the request subcommand:
298
299                   # Mrs. Swift needs a car. She doesn't have a preference for a
300                   # particular car. We'll issue a request on her behalf as follows:
301                   if { [CarPool request car -allocID "Mrs. Swift"] }  {
302                       # request was honoured, process the variable `car'
303                       puts "$car has been allocated to [CarPool info allocID $car]."
304                   } else {
305                       # request was denied
306                        puts "No car available."
307                   }
308
309
310       Note  how the if command uses the value returned by the request subcom‐
311       mand.
312
313                   # Suppose Mr. Wiggly has a preference for the Trabant:
314                   if { [CarPool request car -allocID "Mr. Wiggly" -prefer Trabant] }  {
315                       # request was honoured, process the variable `car'
316                       puts "$car has been allocated to [CarPool info allocID $car]."
317                   } else {
318                       # request was denied
319                        puts "The Trabant was not available."
320                   }
321
322
323       Resume the interactive session:
324
325                   8. When the car is returned then you can render it available by:
326                   % CarPool release Trabant
327
328                   9. When done, you delete the pool.
329                   % CarPool destroy
330                   Couldn't destroy `CarPool' because some items are still allocated.
331
332                   Oops, forgot that Mrs. Swift still occupies a car.
333
334                   10. We force the destruction of the pool as follows:
335                   % CarPool destroy -force
336
337
338       Example 2
339
340       This example describes the case from which the author's need  for  pool
341       management  originated.  It  is an example of a server application that
342       receives requests from client applications.  The  client  requests  are
343       dispatched  onto  a  back-end  application before being returned to the
344       client application. In many cases there are a few equivalent  instances
345       of back-end applications to which a client request may be passed along.
346       The file descriptors that  identify  the  channels  to  these  back-end
347       instances make up a pool of connections. A particular connection may be
348       allocated to just one client request at a time.
349
350                   # Create the pool of connections (pipes)
351                   set maxpipes 10
352                   pool Pipes $maxpipes
353                   for {set i 0} {$i < $maxpipes} {incr i} {
354                       set fd [open "|backendApplication" w+]
355                       Pipes add $fd
356                   }
357
358                   # A client request comes in. The request is identified as `clientX'.
359                   # Dispatch it onto an instance of a back-end application
360                   if { [Pipes request fd -allocID clientX] } {
361                       # a connection was allocated
362                       # communicate to the back-end application via the variable `fd'
363                       puts $fd "someInstruction"
364                       # ...... etc.
365                   } else {
366                       # all connections are currently occupied
367                       # store the client request in a queue for later processing,
368                       # or return a 'Server busy' message to the client.
369                   }
370
371

BUGS, IDEAS, FEEDBACK

373       This document, and the package it describes, will  undoubtedly  contain
374       bugs  and other problems.  Please report such in the category struct ::
375       pool of  the  Tcllib  Trackers  [http://core.tcl.tk/tcllib/reportlist].
376       Please  also  report any ideas for enhancements you may have for either
377       package and/or documentation.
378
379       When proposing code changes, please provide unified diffs, i.e the out‐
380       put of diff -u.
381
382       Note  further  that  attachments  are  strongly  preferred over inlined
383       patches. Attachments can be made by going  to  the  Edit  form  of  the
384       ticket  immediately  after  its  creation, and then using the left-most
385       button in the secondary navigation bar.
386

KEYWORDS

388       discrete items, finite, pool, struct
389

CATEGORY

391       Data structures
392
394       Copyright (c) 2002, Erik Leunissen <e.leunissen@hccnet.nl>
395
396
397
398
399tcllib                               1.2.3                     struct::pool(n)
Impressum