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.
Cons:
Pros:
Creates an instance of TwinDB.
TwinDB_free(TwinDB *self)
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.