3

ノート:

これは、ClojureとGitの両方に意図的にタグ付けされています。これは、ソフトウェアのClojure側とGit側の両方でリバースエンジニアリングを行って、動作させることができてうれしいためです。

問題:

私はたくさんのclojureデータ構造を持っています。ディスクに書き出されたとき(prを使用)、平均してそれぞれ約100kbです。私はそのようなファイルを約1000個持っています。これらのファイルは「構造化された」ドキュメントであり、SVGと同等であると考えてください。

現在、これらの各ファイルに多くの小さな更新を行っています(ノードの追加/削除、ノードのプロパティの変更)。(次に、これらのファイルを(書き込み(pr ...))出力します。

最後に、これらすべてのファイルをgitリポジトリに保存しています。

質問:

これらのファイルを保存する効率的な方法があるかどうか疑問に思っています(異なる書き込みではわずかな変更しかありません)-つまり、メモリに1つのドキュメントのコピーが2つある場合、2MBではなく1MB+イプシロンになります( 2つのドキュメントにはわずかな違いしかなく、構造の大部分を共有しています。)

どういうわけかこの事実を利用したいと思います。それがgitに保存されているときに、この類似性を利用してもらいます。

考えられる解決策:

1)clojure側では、ファイル全体を書き出すのではなく、「前のファイルとの[assoc、dissocからなる]diff」だけを書きます。<-これには多くのエンジニアリングが必要です。

2)FS側では、個々のファイルを保存する代わりに、ディレクトリ全体をbzipに入れて、単一の* .bz2としてコミットします(したがって、同様のファイルは同様のブロックを持ちます)。欠点は、gitで*.bz2ファイルを削除することは悪い考えではないように思われることです。

4

2 に答える 2

3

Git ではなくDatomicの使用を検討したことはありますか?

あなたがしていることは、Datomic のほぼ理想的な使用例のように思えます。Datomic は、本質的に「ファクト グラフ」の Clojure スタイルのデータベースです。これは、構造化データがどのように見えるかをほぼ正確に示しています。

Datomic は、Clojure の不変データ構造と非常によく似た方法でデータを保存します。つまり、構造共有を使用して、小さな変更が少量の追加スペースしか必要としないことを保証します。また、git と同様の方法で履歴全体を保持します。Datomic で git リポジトリをシミュレートするツール ( codeq )もあります。

于 2012-12-09T20:38:18.727 に答える
1

それは興味深い問題です。何ができるか見てみましょう。

内部的には、Git はリポジトリに追加したファイルの完全なコピーをデータベースに保存します。ただし、ローカル リポジトリを最適化するために実行git gcすると、Git は緩いオブジェクトをパックファイルにパックします。同様のファイルは、デルタ圧縮を使用してパックファイルに保存されます。Pro Gitの引用:

Git がオブジェクトをパックするとき、名前とサイズが似ているファイルを探し、ファイルのあるバージョンから次のバージョンへの差分だけを保存します。

その結果、Git 内の同様のファイルのストレージが最適化され、スペースの使用量が削減されます。

内部からユーザーインターフェース部分に移りましょう。ユーザーの観点から見ると、Git は差分に基づいています。コミットを参照し、パッチをマージし、主に差分を扱っている変更を確認します。差分は行指向です。したがって、単一行の最小限の変更により、その行の古いバージョンと新しいバージョンの両方が、生成された差分にまとめて格納されます。あなたが説明したファイル間の差分を読みやすくするにはどうすればよいですか? 行を短くします。それを達成するための2つの簡単な方法があります。

まず、Clojure データ構造を保存する代わりに、それらをYAMLに変換します。YAML 形式で保存されたデータを含むファイルには、問題を解決する比較的短い行があります。clj-yamlが便利です。

データを s 式として格納することに固執する場合、2 番目のアイデアは、生成されたファイル内のすべてのスペースを改行文字に置き換えることです。読みやすさが重要な場合は、後でインデントできます。各スペースを置き換える単純な正規表現を適用する前に、\n内部にスペースを含む文字列があるかどうかを確認してください。

于 2012-12-09T15:31:18.447 に答える