It accomplishes this by maintaining twin BerkeleyDB databases and using "lock" files to indicate when a set of writes are in progress.
Put and delete entries are cached in memory until TwinDB_sync() is called or a read occurs (by calling TwinDB_get()). Then, it:
and repeats this process for the backup database. Upon startup, it checks to see if a lock is on either file. If so, it assumes that database file is corrupt and replaces it with the other.
Creates an instance of TwinDB.
Frees the specified instance of TwinDB, closing it if needed.
void TwinDB_path_(TwinDB *self, char *path);
Sets the file path of the database. The instance will create two files at the specified path with the suffixes "1.tdb" and "2.tdb".
void TwinDB_setWriteCacheSizeLimit_(TwinDB *self, size_t size)
Sets the limit of the write cache in bytes. Onces the write cache exceeds this limit, TwinDB_sync() will automatically be called. If the size is set to zero (which is the default), there is no limit.
void TwinDB_open(TwinDB *self);
Open the database. TwinDB_path_() must be called first.
void TwinDB_close(TwinDB *self);
Close the databases.
void TwinDB_delete(TwinDB *self);
Delete the databases.
void TwinDB_sync(TwinDB *self);
Save any cached writes (put or delete operations).
void TwinDB_put(TwinDB *self, DBT *key, DBT *value);
Set a key value pair. This operation is cached in memory until TwinDB_sync() or TwinDB_read() is called.
void TwinDB_get(TwinDB *self, DBT *key, DBT *value);
Get the value for the specified key.
void TwinDB_del(TwinDB *self, DBT *key);
Delete the specified key if present. This operation is cached in memory until TwinDB_sync() or TwinDB_read() is called.