1(* Gdbm -- GNU gdbm persistent string hashtables -- requires Dynlib *)
2
3type table
4
5datatype openmode =
6    READER                              (* read-only access (nonexclusive) *)
7  | WRITER                              (* read/write, table must exist    *)
8  | WRCREAT                             (* read/write, create if necessary *)
9  | NEWDB                               (* read/write, create empty table  *)
10
11type datum = string
12
13exception NotFound
14exception AlreadyThere
15exception NotWriter
16exception Closed
17exception GdbmError of string
18
19val withtable  : string * openmode -> (table -> 'a) -> 'a
20val withtables : (string * openmode) list -> (table list -> 'a) -> 'a
21val add        : table -> datum * datum -> unit
22val insert     : table -> datum * datum -> unit
23val find       : table -> datum -> datum
24val peek       : table -> datum -> datum option
25val hasKey     : table -> datum -> bool
26val remove     : table -> datum -> unit
27val listKeys   : table -> datum list
28val numItems   : table -> int
29val listItems  : table -> (datum * datum) list
30val app        : (datum * datum -> unit) -> table -> unit
31val map        : (datum * datum -> 'a) -> table -> 'a list
32val fold       : (datum * datum * 'a -> 'a) -> 'a -> table -> 'a
33val fastwrite  : bool ref
34val reorganize : table -> unit
35
36(*
37   [table] is the type of an opened table.  A value of type table can
38   be used only in the argument f to the withtable function.  This
39   makes sure that the table is closed after use.
40
41   [openmode] is the type of opening modes.  Read-only access (READER)
42   is non-exclusive; read/write access (WRITER, WRCREAT, NEWDB) is
43   exclusive.
44
45   [withtable (nam, mod) f] first opens the table db in file nam with
46   mode mod, then applies f to db, then closes db.  Makes sure to
47   close db even if an exception is raised during the evaluation of
48   f(db).  Raises GdbmError with an informative message in case the
49   table cannot be opened.  E.g. the table cannot be opened for
50   reading if already opened for writing, and cannot be opened for
51   writing if already opened for reading.
52
53   A table is only guaranteed to work properly if created by withtable
54   using open modes WRCREAT or NEWDB.  If you create a table by
55   creating and then opening an empty file, then numItems, listKeys,
56   listItems, etc. will raise an exception.
57
58   [withtables nammod f], where nammod = [(nam1, mod1), ..., (namn, modn)],
59   is equivalent to
60        withtable (nam1, mod1) (fn db1 =>
61            withtable (nam2, mod2) (fn db2 =>
62                ...
63                    f [db1, db2, ...]))
64   That is, first opens the databases db1, db2, ... in that order in
65   files nam1, nam2, ... with modes mod1, mod2, ..., then applies f to
66   [db1, db2, ...], and finally closes [db1, db2, ...].  Makes sure to
67   close all databases even if an exception is raised during the
68   opening of db1, db2, ... or during the evaluation of f[db1, db2, ...].
69
70   [add db (k,v)] adds the pair (k, v) to db.  Raises AlreadyThere if
71   there is a pair (k, _) in db already.  Raises NotWriter if db is
72   not opened in write mode.
73
74   [insert db (k, v)] adds the pair (k, v) to db, replacing any pair
75   (k, _) at k if present.  Raises NotWriter if db is not opened in
76   write mode.
77
78   [find db k] returns v if the pair (k, v) is in db; otherwise
79   raises NotFound.
80
81   [peek db k] returns SOME v if the pair (k, v) is in db; otherwise
82   returns NONE.
83
84   [hasKey db k] returns true if there is a pair (k, _) in db;
85   otherwise returns false.
86
87   [remove db k] deletes the pair (k, _) from the table if present;
88   otherwise raises NotFound.  Raises NotWriter if db is not opened in
89   write mode.
90
91   [listKeys db] returns a list of all keys in db in an unspecified
92   order.
93
94   [numItems db] is the number of (key, value) pairs in db.
95   Equivalent to length(listKeys db).
96
97   [listItems db] returns a list of all (key, value) pairs in db in some
98   order.  Equivalent to
99        List.map (fn key => (key, find(db,key))) (listKeys db)
100
101   [app f db] is equivalent to List.app f (listItems db), provided the
102   function f does not change the set of keys in the table.
103   Otherwise the effect is unpredictable.
104
105   [map f db] is equivalent to List.map f (listItems db), provided the
106   function f does not change the set of keys in the table.
107   Otherwise the result and effect are unpredictable.
108
109   [fold f a db] is equivalent to
110        List.foldr (fn ((k, v), r) => f(k, v, r)) a (listItems db)
111   provided the function f does not change the set of keys in the
112   table. Otherwise the result and effect are unpredictable.
113
114   [fastwrite] can be set to speed up writes to a table.  By default,
115   !fastwrite is false and every write to a table will be followed by
116   file system synchronization.  This is safe, but slow if you perform
117   thousands of writes.  However, if !fastwrite is true when calling
118   withtable, then writes may not be followed by synchronization,
119   which may speed up writes considerably.  In any case, the file
120   system is synchronized before withtable returns.
121
122   [reorganize db] has no visible effect, but may be called after a
123   lot of deletions to shrink the size of the table file.
124*)
125