2012-05-02 10 views
1

周波数テーブル(つまり、文字列キーと整数値を含むハッシュテーブル)を格納するためにBerkeley DBを使用しようとしています。テーブルはPythonから書かれ、更新され、読み込まれます。私は現在、bsddb3を試しています。これは、文字列の値しかサポートしていないように見えることを除いて、私が望むもののほとんどを行うように見えますか?bsddb3を使ってBerkeley DBに整数値を書き込むにはどうすればいいですか?

私が正しく理解している場合、Berkeley DBはあらゆる種類のバイナリキーとバリューをサポートしています。 bsddb3を使用してBerkeley DBに生の長整数を効率的に渡す方法はありますか?私は値を文字列に/から変換できることを知っています。これはおそらく私がやることですが、より効率的な方法がありますか?私。 '生の'整数を格納することによって?


背景:私は現在、(キーの数百万人の、潜在的に数十、数百いない場合は)大きな周波数テーブルで働いています。これは現在Python辞書を使用して実装されていますが、仮想メモリにスワップするときにスクリプトを中止します。はい、私はRedisを見ましたが、これはデータベース全体をメモリに保存します。だから私はバークレーDBを試してみようとしています。短期メモリ内キャッシュを使用することで、作成効率を向上させることができます。私。メモリ内のPython辞書を作成し、定期的にこれをマスタBerkeley DB頻度テーブルに追加します。

答えて

1

python以外の言語からデータを読み込む必要がありますか?もしそうでなければ、Pythonの長い整数にpickleを使うだけで、読み込んだときにそれらを読み戻すことができます。これは自動的にshelveモジュールを使うことができます(おそらく)。しかし、そうでない場合でも、値を手動でピックルしてアンピクルすることができます。

>>> import cPickle as pickle 
>>> pickle.dumps(19999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999, pickle.HIGHEST_PROTOCOL) 
'\x80\x02\x8a(\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x7fT\x97\x05p\x0b\x18J#\x9aA\xa5.{8=O,f\xfa\x81|\xa1\xef\xaa\xfd\xa2e\x02.' 
>>> pickle.loads('\x80\x02\x8a(\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x7fT\x97\x05p\x0b\x18J#\x9aA\xa5.{8=O,f\xfa\x81|\xa1\xef\xaa\xfd\xa2e\x02.') 
19999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999L 
+0

おそらく別の言語は必要ありません。私はC#のユースケースを念頭に置いていますが、インポートユーティリティ(つまり、ランダムアクセスではなく読み込みからの読み込み)であるため、Pythonで生成されたテキストダンプを扱うことができます。私はpickleが文字列フォーマットよりも少し効率的になるだろうと思いますか? – winwaed

+0

うまく走っているように見えますが、スクリプトは一晩中実行していました。速度のように見えるかもしれません - 多分私はより大きなメモリ内のキャッシュが必要です。 – winwaed

0

のPython structはあなたが別のパッキングフォーマットを使用する可能性がありますあなたのデータに応じて、Pythonの2にはPython 3または文字列にバイトの整数に変換するには符号なしの長い長いまたはuint64_t

struct.unpack('>Q', my_integer) 

これにより、bigendianmy_integerのバイト表現が、bsddbのキー値に必要な辞書順と一致します。スペースを節約するために、よりスマートなパッキング機能(wiredtiger.intpackingをご覧ください)が付いてきます。

Pythonキャッシュは必要ありません。DBEnv.set_cache_max and set_cacheを使用してください。

関連する問題