2017-11-27 4 views
0

Ich habe einen Git-Treebuilder Ich versuche, mit Blobs zu bevölkern. Also versuche ich eine Art Sharding zu machen, um Blobs nach Dateiname einfacher zu finden. Die Dateien sind nach ihrer ID benannt, also angenommen, ich habe die Dateinamen 11, 15, 21 und schäle sie in Ordnern mit einem Vielfachen von 10, die aufgerundet werden. Dann habe ich zwei Ordner: 20 und 30. (In Wirklichkeit haben wir Millionen von Einträgen).LibGit2 Treebuilder Multilevel-Einfügung

in ihnen:

20 -> 11, 15 
30 -> 21 

Okay, so der Code etwa wie folgt aussieht:

std::string shardName = roundUp(ID, multiple); 

shardTB = shardMap_[shardName]; 
git_treebuilder_insert(NULL, shardTB, ID, &blobOID, GIT_FILEMODE_BLOB); 

git_oid shardOID; 
git_treebuilder_write(&shardOID, shardTB); 
git_treebuilder_insert(NULL, TopLevelTB, shardName, &shardOID, GIT_FILEMODE_TREE); 

So legen wir einen Klecks in die Scherbe TreeBuilder, schreiben Sie den Baum, dann legen Sie den Baum in einige anderer Baumeister.

Dies läuft sehr langsam (etwa 10x langsamer) als im Gegensatz zu den Shards. Ich kann nicht wirklich sagen, warum das so viel langsamer wäre, wenn man bedenkt, dass wir über die gleiche Anzahl von Dateien schreiben. Vielleicht macht libgit2 intern etwas, wenn ein Baum in einem Baumbuilder überschrieben wird. Ich frage mich nur, ob irgendjemand etwas darüber weiß, dh warum das so viel langsamer ist und ob es irgendeinen Weg gibt es zu beschleunigen.

Meine Idee jetzt, um dies zu umgehen ist, nur die Shard-Karte zu halten, und wenn ich die eigentliche Festschreibung machen, durchlaufen Sie die Karte und fügen Sie alle an diesem Punkt, aber ich möchte vermeiden tue dies wenn möglich.

+0

Ich denke, dass das Problem tatsächlich auf die Tatsache zurückzuführen ist, dass wir die gleichen Baumbuilder immer wieder schreiben müssen, jedes Mal, wenn wir einen neuen Blob zu diesem Shard hinzufügen. Sie werden jedes Mal größer, wenn wir ihnen einen Blob hinzufügen, und wir schreiben sie jedes Mal neu, was langsamer werden muss, da die Baumentwickler mehr Blobs haben (wir schreiben am Ende immer wieder dieselben Blobs). Die oben beschriebene Problemumgehung könnte meine beste Lösung sein. – jboretsky

Antwort

2

Es gibt ein paar Möglichkeiten, wie libgit2 einen Haufen dieser Arbeit für Sie erledigen kann. Die "traditionelle" Methode macht, was git tut, wenn Sie git add und git commit verwenden, indem Sie Daten in eine Indexdatei einlesen und dort die Änderungen vornehmen.

Mit libgit2 müssen Sie diese Indexdatenstruktur nicht in einer Datei speichern, sondern können sie im Arbeitsspeicher behandeln. Der Index hat einen Cache, so dass er keine Bäume neu schreiben kann, die sich nicht geändert haben.

Sie können einen neuen Index mit git_index_new() erstellen, lesen Sie unsere alten Baum in mit git_index_read_tree(), führen Sie Ihre Änderungen und schreiben Sie es wieder mit git_index_write_tree_to(). Dadurch wird vermieden, Bäume für "Verzeichnisse" neu zu erstellen, die nicht verändert wurden, und sie werden nur einmal geschrieben, was sich so anhört, als ob Sie das nicht in Ihrer Lösung tun würden.

Dies kann langsam sein, wenn Sie viele Einträge haben, da wir jeden einzelnen Baum einlesen müssen. Wenn Ihre Aktualisierungen häufig eingeschränkt sind, können Sie git_tree_create_updated() verwenden und sie in die gewünschten Änderungen einspeisen. Diese Funktion liest nur die Bäume ein, die sich aufgrund der Liste der von Ihnen bereitgestellten Updates ändern werden. Es ist nicht so flexibel wie alles von Hand, aber es deckt die häufigsten Fälle ab.

Ohne weitere Informationen über die Gesamtarchitektur Ich weiß nicht, warum es so viel langsamer wäre als die sharding nicht verwenden, aber in Ihrem Kommentar

Ich denke, dass das Problem auf die Tatsache zurückzuführen ist eigentlich dass wir benötigen, um die gleiche treebuilders immer und immer wieder, jedes Mal das Hinzufügen eines neuen Blob zu diesem Shard

es klingt wie Sie ausführen, O (n) aktualisiert statt einer, die es sicherlich erklären würde, schreiben.

Sie erwähnen auch "Millionen von Einträgen", was darauf hindeutet, dass Sie versuchen, Git als Datenbank zu verwenden.Der beste Rat, den ich dazu habe, ist nicht, es zu tun, sondern in eine Datenbank zu investieren. Während das Git-System ziemlich wie eine Datenbank aussieht und Dinge enthält, die wir Datenbanken nennen, ist es eine sehr schlechte Allzweck-Datenbank.

+0

Danke für die gründliche Antwort! Ich wusste nichts über die Git-Index-Datei, also werde ich versuchen, zu sehen, wie ich den Code ändern könnte, um es zu benutzen, scheint, dass es Dinge wirklich vereinfachen könnte. Sie haben Recht, es ist nicht ideal, git als Datenbank zu verwenden, aber wir testen es, um zu sehen, wo seine Grenzen liegen. – jboretsky

Verwandte Themen