.. _BDB: .. currentmodule:: tokyocabinet ================================= B+ Tree Database --- :class:`BDB` ================================= .. versionadded:: 0.2.0 :class:`BDB` ============ .. class:: BDB Example:: from tokyocabinet import * bdb = BDB() # if need be, you should call tune/setcache/setxmsiz/setdfunit before # open, ex. with default values: bdb.tune(0, 0, 0, -1, -1, 0) bdb.setcache(0, 0) bdb.setxmsiz(0) bdb.setdfunit(0) # open the database bdb.open("casket.tcb", BDBOWRITER | BDBOCREAT) # store records for key, value in [("foo", "hop"), ("bar", "step"), ("baz", "jump")]: bdb[key] = value # retrieve one record print(bdb["foo"]) # traverse records for key in bdb: print(key, bdb[key]) # close the database bdb.close() .. note:: For all methods taking either a *key* argument or a pair *(key, value)*, *key* and *value* must be either :class:`str` (Python2) or :class:`bytes` (Python3). .. seealso:: `The B+ Tree Database API `_ .. describe:: len(bdb) Return the number of records in the database *bdb*. .. describe:: bdb[key] Return the value of *bdb*'s **first record** corresponding to *key*. Raises :exc:`KeyError` if *key* is not in the database. .. describe:: bdb[key] = value Set ``bdb[key]`` to *value*. If *key* has duplicates the **first corresponding record** is modified. .. describe:: del bdb[key] Remove ``bdb[key]`` from *bdb*. Raises :exc:`KeyError` if *key* is not in the database. If *key* has duplicates the **first corresponding record** is deleted. .. describe:: key in bdb Return ``True`` if *bdb* has a key *key*, else ``False``. .. describe:: key not in bdb Equivalent to ``not key in bdb``. .. describe:: iter(bdb) Return an iterator over the keys of the database. .. note:: Better use a :class:`BDBCursor` to iterate over a database with duplicates. .. method:: tune(lmemb, nmemb, bnum, apow, fpow, opts) Tune a database. :param lmemb: the number of members in each leaf page. If specified as 0 or as a negative value, the default value (128) is used. :param nmemb: the number of members in each non-leaf page. If specified as 0 or as a negative value, the default value (256) is used. :param bnum: the number of elements in a bucket array. If specified as 0 or as a negative value, the default value (32749) is used. :param apow: (power of 2) TODO. If specified as a negative value, the default value (8) is used (means: 2**8). :param fpow: (power of 2) TODO. If specified as a negative value, the default value (10) is used (means 2**10). :param opts: options, see `BDB.tune()/BDB.optimize() options`_. .. note:: Tuning an open database is an invalid operation. .. method:: setcache(lcnum, ncnum) Set the cache parameters. :param lcnum: the maximum number of leaf nodes to be cached. If specified as 0 or as a negative value, the default value (1024) is used. :param ncnum: the maximum number of non-leaf nodes to be cached. If specified as 0 or as a negative value, the default value (512) is used. .. note:: Setting the cache parameters on an open database is an invalid operation. .. method:: setxmsiz(xmsiz) Set the extra mapped memory size. :param xmsiz: the amount of extra mapped memory (in what unit?). If specified as 0 or as a negative value, the extra mapped memory is disabled (default). .. note:: Setting the extra memory size on an open database is an invalid operation. .. method:: setdfunit(dfunit) Set auto defragmentation's unit step number. :param dfunit: the unit step number(?). If specified as 0 or as a negative value, auto defragmentation is disabled (default). .. note:: Setting this on an open database is an invalid operation. .. method:: open(path, mode) Open a database. :param path: path to the database file. :param mode: mode, see `BDB.open() modes`_. .. method:: close Close the database. .. note:: BDBs are closed when garbage-collected. .. method:: clear Remove all records from the database. .. method:: copy(path) Copy the database file. :param path: path to the destination file. .. method:: begin Begin a transaction. .. method:: commit Commit a transaction. .. method:: abort Abort a transaction. .. method:: get(key[, duplicate=False]) If *duplicate* is :const:`False` (default) this is equivalent to ``bdb[key]``. If *duplicate* is :const:`True` this method returns a tuple of all the values corresponding to *key*. It will raise :exc:`KeyError` if *key* is not in the database. .. method:: remove(key[, duplicate=False]) If *duplicate* is :const:`False` (default) this is equivalent to ``del bdb[key]``. If *duplicate* is :const:`True` this method removes all records corresponding to *key*. It will raise :exc:`KeyError` if *key* is not in the database. .. method:: put(key, value[, duplicate=False]) If *duplicate* is :const:`False` (default) this is equivalent to ``bdb[key] = value``. If *duplicate* is :const:`True` and *key* is already in the database, this method will store a new duplicate record after the last corresponding record. .. method:: putkeep(key, value) Store a record in the database, unlike the standard forms (``hdb[key] = value`` or :meth:`put`), this method raises :exc:`KeyError` if *key* is already in the database. .. method:: putcat(key, value) Concatenate a value at the end of an existing one. If there is no corresponding record, a new record is stored. If *key* has duplicates the first corresponding record is modified. .. method:: putdup(key, values) Store duplicate records in the database, this is equivalent to:: def putdup(self, key, values): for value in values: self.put(key, value, duplicate=True) .. method:: sync Flush modifications to the database file. .. method:: searchkeys(prefix[, max]) Return a frozenset of keys starting with *prefix*. If given, *max* is the maximum number of keys to fetch, if omitted or specified as a negative value no limit is applied. .. method:: range([begin=None[, end=None[, max=-1]]]) Return a frozenset of all the keys starting with *begin*, all the keys starting with *end* and all the keys in between. If given, *max* is the maximum number of keys to fetch, if omitted or specified as a negative value no limit is applied. Example:: >>> from tokyocabinet import * >>> bdb = BDB() >>> bdb.open("range.tcb", BDBOWRITER | BDBOCREAT) >>> for key, value in [("a", "a"), ("b", "b"), ("c", "c"), ("d", "d")]: ... bdb[key] = value ... >>> bdb.range() frozenset(['a', 'c', 'b', 'd']) >>> bdb.range(end="c") frozenset(['a', 'c', 'b']) >>> >>> bdb.range("b", "d") # begin and end are inclusive frozenset(['c', 'b', 'd']) >>> bdb.range("b", "z") frozenset(['c', 'b', 'd']) >>> bdb.range("z", "b") # end < begin doesn't work frozenset([]) >>> bdb.range("a", "a") # end == begin works frozenset(['a']) >>> bdb.range("A", "Z") # it is case sensitive frozenset([]) >>> bdb.range("A", "z") # uppercase < lowercase frozenset(['a', 'c', 'b', 'd']) >>> bdb.range("z", "A") frozenset([]) >>> bdb.close() >>> .. method:: cursor Return a cursor object (:class:`BDBCursor`). See `BDBCursor operations`_. .. method:: optimize([lmemb=0[, nmemb=0[, bnum=0[, apow=-1[, fpow=-1[, opts=255]]]]]]) Optimize a database. :param lmemb: the number of members in each leaf page. If specified as 0 or as a negative value, the current setting is kept. :param nmemb: the number of members in each non-leaf page. If specified as 0 or as a negative value, the current setting is kept. :param bnum: the number of elements in a bucket array. If specified as 0 or as a negative value, the default value (twice the number of pages) is used. :param apow: (power of 2) TODO. If specified as a negative value, the current setting is kept. :param fpow: (power of 2) TODO. If specified as a negative value, the current setting is kept. :param opts: options, see `BDB.tune()/BDB.optimize() options`_. If specified as 255 (:const:`UINT8_MAX`), the current setting is kept. .. note:: Optimizing a read only database, or during a transaction, is an invalid operation. .. method:: addint(key, num) Store an :class:`int` in the database. If *key* is not in the database, this method stores *num* in the database and returns it. If *key* is already in the database, then it will add *num* to its current value and return the result. If *key* exists but its value cannot be treated as an :class:`int` this method raises :exc:`KeyError`. .. note:: * The returned value will wrap around :const:`INT_MAX` and :const:`INT_MIN`. Example:: >>> bdb.addint('id', INT_MAX) # setting 'id' to INT_MAX 2147483647 >>> bdb.addint('id', 1) # adding 1 to 'id' returns INT_MIN -2147483648 >>> * Trying to access a value set with :meth:`addint` using :meth:`get` or ``bdb[key]`` will **not** return an :class:`int`. It will instead return the internal binary representation of the value. Example:: >>> bdb.addint('id', INT_MAX) # setting 'id' to INT_MAX 2147483647 >>> bdb['id'] '\xff\xff\xff\x7f' >>> .. versionadded:: 0.5.0 .. method:: adddouble(key, num) Store a :class:`float` in the database. If *key* is not in the database, this method stores *num* in the database and returns it. If *key* is already in the database, then it will add *num* to its current value and return the result. If *key* exists but its value cannot be treated as a :class:`float` this method raises :exc:`KeyError`. .. note:: Trying to access a value set with :meth:`adddouble` using :meth:`get` or ``bdb[key]`` will **not** return a :class:`float`. .. versionadded:: 0.5.0 Methods :meth:`keys`, :meth:`values` and :meth:`items` are not yet implemented (mainly because I didn't settle on how to do it: should they return :class:`Iterable`, :class:`Iterator`, :class:`MappingView`, etc.?). Any help would be greatly appreciated in this matter. For the time being, for those of you who really need these methods, it's trivial to implement them in python. Here is an example using cursors and generators:: from tokyocabinet import BDB as _BDB class BDB(_BDB): def keys(self): c = self.cursor() c.first() while True: yield c.key() c.next() def values(self): c = self.cursor() c.first() while True: yield c.value() c.next() def items(self): c = self.cursor() c.first() while True: yield c.item() c.next() .. attribute:: path The path to the database file. .. attribute:: size The size in bytes of the database file. :meth:`BDB.open` modes ====================== .. data:: BDBOREADER Open a database in read-only mode. .. data:: BDBOWRITER Open a database in read-write mode. The following constants can only be combined with :const:`BDBOWRITER` : * .. data:: BDBOCREAT Create a new database file if it does not exists. * .. data:: BDBOTRUNC Create a new database file even if one already exists (truncates existing file). * .. data:: BDBOTSYNC Sync the database file on every transaction. The following constants can be combined with either :const:`BDBOREADER` or :const:`BDBOWRITER` : * .. data:: BDBONOLCK Opens the database file without file locking. * .. data:: BDBOLCKNB Locking is performed without blocking. :meth:`BDB.tune`/:meth:`BDB.optimize` options ============================================= .. data:: BDBTLARGE The size of the database can be larger than 2GB. .. data:: BDBTDEFLATE Each page is compressed with Deflate encoding. .. data:: BDBTBZIP Each page is compressed with BZIP2 encoding. .. data:: BDBTTCBS Each page is compressed with TCBS encoding. :class:`BDBCursor` operations ============================= .. class:: BDBCursor .. warning:: When first returned by :meth:`BDB.cursor` a cursor is not fully initialized. You need to call one of the positioning method (:meth:`first`, :meth:`last` or :meth:`jump`) before you can do anything useful with it. .. method:: first Move to the first record (if there is no such thing :exc:`StopIteration` is raised). .. method:: last Move to the last record (if there is no such thing :exc:`StopIteration` is raised). .. method:: jump(key) Move to the first occurrence of *key*. **If** *key* **is not in the database, the cursor is positioned to the next available record** (if there is no such thing :exc:`StopIteration` is raised). .. method:: prev Move to the previous record (if there is no such thing :exc:`StopIteration` is raised). .. method:: next Move to the next record (if there is no such thing :exc:`StopIteration` is raised). .. method:: put(value[, mode=BDBCPCURRENT]) Store a value at/around the cursor's current position. :param mode: see `BDBCursor.put() modes`_. .. method:: remove Remove the current record. After deletion the cursor is moved to the next available record. .. method:: key Get current key. .. method:: value Get current value. .. method:: item Get current item (a *(key, value)* tuple). :meth:`BDBCursor.put` modes =========================== .. data:: BDBCPCURRENT The current value is overwritten (default). .. data:: BDBCPBEFORE A new item is stored before the current position and the cursor is moved to the newly inserted record. .. data:: BDBCPAFTER A new item is stored after the current position and the cursor is moved to the newly inserted record.