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