gitdb: Bare Gitリポジトリをデータベースとして使う(仕切り直し)
開発環境の都合で一旦リセットして仕切り直し。。
GitリポジトリをDBとして使うための考察を1つのライブラリとして纏めたい計画。GitリポジトリにはJSONの形でデータを記録し、最初の段階ではその読み書きをライブラリ化する。
次の段階では今MongoDBを使っているポイントをSQLiteにしたい。検索用のインデックスや配付用のアーカイブとしての利用なら手元のDBの規模ならSQLiteでも行けるんではないか説。
prev
write側
元々の設計ではキューイングもライブラリ側で面倒見ようと思ったが、需要が無かったのでやめた。1つのリポジトリに複数スレッド/プロセスからアクセスしないことはユーザーが保証する必要がある。
難しいことはそんなに無いな。。使い方も簡単で、
全てのメソッドがPromiseを返却するので await
を忘れると酷いことになる。
node.jsで子プロセスを起動してstdinを供給する
ファイルをリポジトリに投入するためには、 echo "Data" | git hash-object -w --stdin
のような感じに、標準入力経由でデータを渡す必要がある。これは .stdin.end(buf)
で簡単にできる。
stdoutを受け入れるには、 data
イベントを処理すれば良い。Encodingを指定すると data
イベントには文字列が来るようになる。
Closeのタイミングでプロセスが完了したということになる。
read側
cat-file --batch
で読み取りができる。プロセスを起動しっぱなしにするので、 dispose
を呼ばないとスクリプトが終了しなくなる。
特記事項は無し。
bulk set
巨大なblobを足すことを考えるとbulk updateできた方が便利ではある。Gitのオブジェクトは全てSHA1 + gzipされる都合、追加時のCPUコストが高い。ただし、indexの更新は代表スレッドが一括して行う必要がある。
いちいちwrite-object呼ぶんじゃなくて、自前でSHA1 + deflateするのが最良だよね多分。。nodejsにはzlib最初から入ってるし。。
hexpath
gitdbではオブジェクトのプライマリキーをファイルパスで表現する。このとき、パスの形式には様々なものがある。
hexpath0
および hexpath
は、オブジェクトのSHAハッシュ文字列をプライマリキーとする。hexpathは必ず最初の16bitsをプレフィックスとして切り、残りを長いディレクトリまたはファイル名として使用する。
hexpath0
は、プレフィックスとして使用されたビットはパス名として再利用されない。このためファイルを移動するとプライマリキーが失われる。このフォーマットは .git/objects 以下で使用されているものとほぼ同様となる(ただし、gitは先頭8bitのみをプレフィックスにしている)。 hexpath
は、プレフィックスとして使用されたビットもパス名として再利用する。これはgit-lfsで使用されているものと同じフォーマットとなる。
実際のhexpathは更に prefix と objname を組み合わせてファイルのパスとして使用される。例えば、hexpath objects/c5/25/c525e03a9e6237f3a0ed673876db542b069938c055a6c14b67d6c1a580212c13
は、
- format = hexpath
-
prefix
="objects/"
-
objname
=""
となる。
直接オブジェクトを生成する
さすがにプロセス生成コストがもったいない(主にmacやWindows)から直接投入することにしてみた。
... いやまぁやればできるんだけど、巨大ファイルとか扱いたくなったらどうすんのか問題はあるな。。まぁそういうファイルはプロセス起動して普通にgit呼べば良いんだろうけど。