btree -- 単純な BTree データベース

btree モジュールは、外部記憶装置(ディスクファイル、または一般的な場合はランダムアクセスのストリーム stream)を使用して単純な キー/値 (Key-Value)データベースを実装します。キーはデータベースにソートして格納され、キー値による効率的な検索に加えて、データベースは効率的な順序付き範囲スキャン(特定の範囲内のキーを持つ値の検索)もサポートします。アプリケーションインタフェース側では、BTreeデータベースは標準の辞書型(dict)と同じように機能します。辞書型との大きな違いは、キーと値の両方が bytes 型オブジェクトでなければならないことです(したがって、他の型のオブジェクトを格納する場合は bytes 型オブジェクトにシリアル化しておく必要があります)。

このモジュールは、有名な BerkelyDB ライブラリ、バージョン 1.xx をベースにしています。

サンプルコード:

import btree

# まず、データベースを保持するストリームをオープンする必要があります。
# これは通常ファイルですが、io.BytesIO、raw フラッシュパーティション
# などを使用してインメモリデータベースにすることもできます。多くの場合、
# データベースファイルが存在しない場合には作成し、存在する場合はその
# ファイルを開くようにしたいでしょう。以下の慣用句を使えばそのようにできます。
# "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"])

# データベース内のソートされたキーを b"2" からデータベースの最後まで
# 繰り返し、値のみを返します。values() メソッドに渡す引数がキー値である
# ことに注意してください。
# 以下が表示されます:
#   b'two'
#   b'three'
for word in db.values(b"2"):
    print(word)

del db[b"2"]

# もう True ではないので、False が表示されます
print(b"2" in db)

# 以下が表示されます:
#  b"1"
#  b"3"
for key in db:
    print(key)

db.close()

# 基になるストリームのクローズを忘れないでください!
f.close()

関数

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

ランダムアクセスのストリーム(stream)からデータベースをオープンします(ファイルのオープンに似ています)。他のすべてのパラメータはオプション、キーワード指定のみであり、データベース操作の高度なパラメータを調整できます(ほとんどのユーザには必要ないでしょう):

  • flags - 現在未使用です。
  • pagesize - BTree のノードに使用されるページサイズ。許容範囲は 512 から 65536 です。0 の場合はポート固有のデフォルト値が適用され、ポートのメモリ使用量やパフォーマンスに合わせて最適化されます。
  • cachesize - 推奨されるメモリキャッシュサイズ(バイト単位)。より大きな値を使うのに十分なメモリを備えたボードでは、パフォーマンスが向上する可能性があります。キャッシュのポリシーは次のとおりです。キャッシュ全体は一度に割り当てられません。代わりに、データベース内の新しいページにアクセスすると、 cachesize で指定された値に達するまで、そのページ用のメモリバッファが割り当てられます。その後、これらのバッファーは LRU (Least Recently Used)ポリシーを使用して管理されます。必要に応じて、さらに多くのバッファを割り当てることができます(たとえば、データベースに大きなキーや値が含まれている場合など)。割り当てられたキャッシュバッファは再利用されません。
  • minkeypage - 1 ページに格納するキーの最小数。デフォルト値は 0 ですが、2 を指定したのと同等です。

戻り値は BTree オブジェクトです。これは辞書のプロトコル(一連のメソッド)と、以下で説明する追加のメソッドを実装しています。

メソッド

btree.close()

データベースをクローズします。書き込まれていないデータがまだキャッシュに残っている可能性があるため、処理の最後にデータベースをクローズすることが必須です。これはデータベースがオープンされた元のストリームを閉じないことに注意してください、それは別々にクローズするべきです(それもまたデータがバッファから基となるストレージにフラッシュされることを確実にするために必須です)。

btree.flush()

キャッシュ内のデータを基となるストリームにフラッシュします。

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

標準の辞書メソッドです。

btree.__iter__()

BTree オブジェクトは、(辞書のように)直接繰り返し処理して、すべてのキーに順番にアクセスできます。

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

これらのメソッドは標準的な辞書のメソッドと似ていますが、データベース全体ではなく、主要なサブ範囲にわたって反復するためのオプションのパラメータを取ることもできます。3つのメソッドすべてについて、 start_key 引数と end_key 引数がキー値であることに注意してください。たとえば、 values() メソッドは与えられたキー範囲に対応する値を反復します。 start_key に値がない場合は「最初のキーから」、 end_key がない 場合、または値が None の場合は「データベースの終わりまで」を意味します。デフォルトでの範囲は、 start_key を含みますが、 end_key は外されます。 flagsbtree.INCL を渡すことで繰り返しに end_key を含められます。 flagsbtree.DESC を渡すことで降順のキー方向に反復できます。 flags の値はビットOR(|)演算を使って複数指定できます。

定数

btree.INCL

keys(), values(), items() メソッドに指定するフラグであり、反復対象として終了キーを含めます。

btree.DESC

keys(), values(), items() メソッドに指定するフラグであり、キーの反復方向を降順にします。