その名はuit

以前ぼくのかんがえたさいきょうのファイルsyncシステムとして書いたヤツだが、 しばらく考えていたら結構簡単に始められるくらいの仕様になってきた気がするので、作り始める事にした。

名前はunique it、略してuitとする。以下の説明を見ると分かるように、かなりgitに影響を受けているので、名前も似せてgをuにしたものとした。

F#で作ってる。

github: uit

Uit.fsxがここまでやった事のほぼ全て(まだ型を考えたくらいで動いてはいない)

uitに関する雑多なメモ

一気に作れるほどまだ自分の中で固まって無いので、ここにだらだらと考えている事を書き出す事にする。

まずはsyncよりも前に、ファイルを一意に管理する事にする。 ファイルは同じファイルが複数なければそんまま残す。

uitが管理するディレクトリツリーをrepoと呼ぶ。 repoはトップディレクトリに.uitディレクトリを持つ。

.uitディレクトリの下には、今の所以下の2つのディレクトリがある。

  • hash
  • dirs

.uit/hash下にはファイルのSHA256ハッシュ(以下ハッシュと呼ぶ)の先頭二文字でdirをほって、その中に「それ以後.txt」というファイルを置く。 このファイルには、このハッシュのblobがどこにあるかの情報が乗っている。

一行1パスで、各行は

lastModified entryDate path

がタブ区切りで入っている。 この情報を使って「ハッシュ値ー>パスの一覧」が取得出来る。 なお、entryDateはこのエントリが最後に更新された時間。

コマンド的には以下のようなのを想定

$ uit list 48491d8
134267 234267 music/song/some_music.mp3
134267 234789 guitar/hikigatari/some_music.mp3
...

.uit/dirs 下には対象とするrepoのディレクトリツリーをそのまま複製したディレクトリツリーを持ち、 各ディレクトリにはdir.txtというファイルがある。

この中には各行にファイルの情報があり、内容は

lastModified endtryDate hash ファイル名

がタブ区切りで入っている。 この情報を使って「パスー>ハッシュ値」が取得出来る。

$ uit hash music/song/some_music.mp3
48491d8......

リンクの仕組み

さて、ハッシュでパスの一覧を取った時に複数のパスがあれば、 一つ以外はリンクに置き換える事が出来る。 リンクは元のファイル名に.uitの拡張子を足した物とする。 もともとそういう拡張子のデータがあった場合とかの事は考えない。

で、このファイルにはハッシュ値を入れておく。

いつでもハッシュ値でパスの一覧を取った時に一つは実体のまま残すようにする。 ハッシュ値から一覧を取った時、一番上が実体な物になるようにしておく。(二番目以降が実体のままな事もある)。

実体をInstance、リンクをReferenceのファイルと呼ぶ。

$ uit uniqit 48491d8

などとするとこのハッシュのファイルのうち一番目のパスだけを残して他を全てリンクに置き換える。

実体化するパスを変更したい場合はinstanceコマンドで指定する。

$ uit inst music/mp3/single/somesong.mp3

するとこのパスからdirsを用いてハッシュを取り出し、ハッシュからファイル一覧を取り出して、必要だったらmoveして元のファイルをリンクに置き換えて、ハッシュ.txtの順番を更新する(EntryDateも更新する)。

またはハッシュ値とリストの何番目かを指定も出来るhinstanceというサブコマンドも作りたい。

$ uit hinst 48491d8 2

listした後にhinstする感じで使いたい。

とりあえずここまでを作りたいなぁ、と思っている。

シンクの仕組み

基本的には上書きする一方向syncを基本として、 必要だったら両方向きになるように2回走らせる。

シンクとしてはまず.uit/hash以下からハッシュ値の一覧をそれぞれ作成し、 srcにあってdestに無いハッシュ値のファイルの先頭をコピーする。 その後はdirs下を比較していって、destになければReferenceファイルを作成していく。

すでにファイルがあった場合はまだあまり考えてないが、 conflictディレクトリかなんかに一覧を残してある程度手動で直すのを考えている。

とにかく、基本的にはblobとしては削除しないのでツリーのどっかにはファイルは残るようにして、なにも考えずにoverwrite syncしていけるようにしたい。 バックアップとかで使いたいので、とにかくどこかにはちゃんとファイルはコピーされる事は保証したい。 これはハッシュ値のリストで漏れが無い事は保証出来ているはず。