Write the shortest program to build a cdb database, using the following syntax for input:
+klen,dlen:key->data
followed by a newline. Example:
+3,5:one->Hello
+3,7:two->Goodbye
(Unlike the real cdbmake, your program doesn't need to catch the empty-line-as-end-of-input case if you don't want to.) Your program needs to handle arbitrary strings (including NUL, newline, +
, ,
, :
, and/or ->
) in both the key and data correctly; therefore, using any kind of line-based input is likely to be wrong. You may assume the input is always valid, and you can assume that there is at most one instance of any key in the input.
The hash tables your program generates must behave like real hash tables. In other words, the hash tables should provide amortised constant-time lookups.
If your language provides built-in hash tables, you're allowed to use them, if they help any. However, do not use any cdb libraries or cdb programs to solve this question.
If your program writes the cdb to standard output, you may assume that it's redirected to a regular file. For example, you may seek or mmap
it.
In the case of multiple shortest entries, the earliest-posted wins (as stipulated by the fastest gun in the west rule).
Here's a complete description of cdb's format as written by cdb's inventor:
A cdb is an associative array: it maps strings (keys) to strings (data).
A cdb contains 256 pointers to linearly probed open hash tables. The hash tables contain pointers to (key,data) pairs. A cdb is stored in a single file on disk:
+----------------+---------+-------+-------+-----+---------+ | p0 p1 ... p255 | records | hash0 | hash1 | ... | hash255 | +----------------+---------+-------+-------+-----+---------+
Each of the 256 initial pointers states a position and a length. The position is the starting byte position of the hash table. The length is the number of slots in the hash table.
Records are stored sequentially, without special alignment. A record states a key length, a data length, the key, and the data.
Each hash table slot states a hash value and a byte position. If the byte position is 0, the slot is empty. Otherwise, the slot points to a record whose key has that hash value.
Positions, lengths, and hash values are 32-bit quantities, stored in little-endian form in 4 bytes. Thus a cdb must fit into 4 gigabytes.
A record is located as follows. Compute the hash value of the key in the record. The hash value modulo 256 is the number of a hash table. The hash value divided by 256, modulo the length of that table, is a slot number. Probe that slot, the next higher slot, and so on, until you find the record or run into an empty slot.
The cdb hash function is
h = ((h << 5) + h) ^ c
, with a starting hash of 5381.