btree – 简化 BTree 数据库

这个 btree 函数使用外部存储器(磁盘文件或者一般情况下的随机访问流 stream )实现了简化版键值数据库功能.键按顺序存储在数据库中, 可以高效的通过键值进行检索, 数据库还支持有效的高效范围内扫描 (使用给定范围内的键检索值). 在应用接口层, BTree 数据库工作模式类似于标准的字典 dict ,一个显著的特征就是键 keys 和值 values 必须以字节对 bytes 出现,(因此如果需要存储其他类型的对象,就需要先将他们转换为字节 bytes )

该模块基于著名的BerkelyDB库version 1.xx.

例子:

import btree

# 首先,我们需要打开一个包含数据库的流
# 这通常是一个文件,但也可以是内存数据库
# 使用 uio.BytesIO, 一个未使用的flash分区.
# 通常, 如果一个数据库文件没有创建那就创建一个如果已经创建好了那就打开它.
# 下面的语句将会告诉我们怎么做.
# 不要使用 "a+b" 访问模式打开数据库.
try:
    f = open("mydb", "r+b")
except OSError:
    f = open("mydb", "w+b")

# 现在打开数据库本身
db = btree.open(f)

# 你添加的键值将会在数据库内按照顺序排序
db[b"3"] = b"three"
db[b"1"] = b"one"
db[b"2"] = b"two"

# 任何数据更改都缓存内存中(除了显示刷新或者关闭数据库),都要在每次处理事件后刷新数据库

db.flush()

# 打印 b'two'
print(db[b"2"])

# Iterate over sorted keys in the database, starting from b"2"
# until the end of the database, returning only values.
# Mind that arguments passed to values() method are *key* values.
# Prints:
#   b'two'
#   b'three'
for word in db.values(b"2"):
    print(word)

del db[b"2"]

# No longer true, prints False
print(b"2" in db)

# Prints:
#  b"1"
#  b"3"
for key in db:
    print(key)

db.close()

# Don't forget to close the underlying stream!
f.close()

Functions

btree.open(stream, *, flags=0, pagesize=0, cachesize=0, minkeypage=0)

Open a database from a random-access stream (like an open file). All other parameters are optional and keyword-only, and allow to tweak advanced parameters of the database operation (most users will not need them):

  • flags - Currently unused.
  • pagesize - Page size used for the nodes in BTree. Acceptable range is 512-65536. If 0, a port-specific default will be used, optimized for port’s memory usage and/or performance.
  • cachesize - Suggested memory cache size in bytes. For a board with enough memory using larger values may improve performance. Cache policy is as follows: entire cache is not allocated at once; instead, accessing a new page in database will allocate a memory buffer for it, until value specified by cachesize is reached. Then, these buffers will be managed using LRU (least recently used) policy. More buffers may still be allocated if needed (e.g., if a database contains big keys and/or values). Allocated cache buffers aren’t reclaimed.
  • minkeypage - Minimum number of keys to store per page. Default value of 0 equivalent to 2.

Returns a BTree object, which implements a dictionary protocol (set of methods), and some additional methods described below.

Methods

btree.close()

Close the database. It’s mandatory to close the database at the end of processing, as some unwritten data may be still in the cache. Note that this does not close underlying stream with which the database was opened, it should be closed separately (which is also mandatory to make sure that data flushed from buffer to the underlying storage).

btree.flush()

Flush any data in cache to the underlying stream.

btree.__getitem__(key)
btree.get(key, default=None)
btree.__setitem__(key, val)
btree.__detitem__(key)
btree.__contains__(key)

Standard dictionary methods.

btree.__iter__()

A BTree object can be iterated over directly (similar to a dictionary) to get access to all keys in order.

btree.keys([start_key[, end_key[, flags]]])
btree.values([start_key[, end_key[, flags]]])
btree.items([start_key[, end_key[, flags]]])

These methods are similar to standard dictionary methods, but also can take optional parameters to iterate over a key sub-range, instead of the entire database. Note that for all 3 methods, start_key and end_key arguments represent key values. For example, values() method will iterate over values corresponding to they key range given. None values for start_key means “from the first key”, no end_key or its value of None means “until the end of database”. By default, range is inclusive of start_key and exclusive of end_key, you can include end_key in iteration by passing flags of btree.INCL. You can iterate in descending key direction by passing flags of btree.DESC. The flags values can be ORed together.

Constants

btree.INCL

A flag for keys(), values(), items() methods to specify that scanning should be inclusive of the end key.

btree.DESC

A flag for keys(), values(), items() methods to specify that scanning should be in descending direction of keys.