2017-11-27 9 views
0

나는 블롭으로 채우려 고 노력하는 git treebuilder가 있습니다. 그래서 파일 이름으로 blob을 쉽게 찾을 수 있도록 sharding을하려고합니다. 파일 이름은 ID로 이름 지어 졌으므로 파일 이름이 11, 15, 21이고 10을 반올림 한 폴더로 분할한다고 가정합니다. 그러면 폴더가 두 개 있습니다 : 20와 30입니다. 실제로는 수백만 개의 항목이 있습니다. 그 안에서LibGit2 treebuilder 다중 레벨 삽입

:

코드 이런 식으로 뭔가 보이는 있도록
20 -> 11, 15 
30 -> 21 

좋아요 :

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); 

그래서 우리는 다음 몇 가지로 그 나무를 삽입, 트리 쓰기, 샤드 treebuilder로 BLOB를 삽입을 다른 treebuilder입니다.

샤드를 사용하지 않고 천천히 (약 10 배 느리게) 실행합니다. 왜 우리가 같은 수의 파일을 쓰고 있다고 생각 하느냐에 따라 이것이 왜 그렇게 느린 지 말할 수 없습니다. 아마 libgit2는 treebuilder 내의 트리를 덮어 쓸 때 내부적으로 뭔가를하고있을 것입니다. 누군가가 그것에 대해 아무것도 모르는 지 궁금해합니다. 즉 속도가 느린 이유와 속도를 높이는 방법이 있다면 말입니다.

내 생각은이 문제를 해결하기 위해 단지 샤드 맵을 유지하는 것입니다. 그러면 실제 커밋을 할 때지도를 반복하고 그 시점에서 모두 추가합니다.하지만 피하고 싶습니다. 가능한 경우이 작업을 수행하십시오.

+0

저는이 문제가 실제로 우리가 동일한 트리 빌더를 반복해서 쓰고 그 조각에 새 BLOB를 추가해야 할 필요가 있다고 생각합니다. 그것들은 blob을 추가 할 때마다 더 커지기 때문에 우리는 treebuilders가 더 많은 blob을 보유 할 때마다 느리게해야하는 모든 시간을 매번 재 작성합니다. 우리는 동일한 blob을 여러 번 다시 작성합니다. 위에 설명 된 내 해결 방법을 수행하는 것이 최선의 방법 일 수 있습니다. – jboretsky

답변

2

libgit2에이 작업을 여러 가지 방법으로 제공 할 수 있습니다. "전통적인"방법은 git addgit commit을 사용할 때 인덱스 파일로 데이터를 읽고 거기에서 수정을 수행 할 때 git이하는 일을합니다.

libgit2를 사용하면이 인덱스 데이터 구조를 파일에 저장할 필요가 없지만 메모리 내에서 처리 할 수 ​​있습니다. 인덱스에는 캐시가 있으므로 변경되지 않은 트리를 다시 작성하지 않음을 알고 있습니다.

으로 새 색인을 만들고 git_index_read_tree()으로 이전 트리를 읽고 수정 한 후 git_index_write_tree_to()으로 다시 쓸 수 있습니다. 이렇게하면 수정되지 않은 "디렉토리"에 대한 트리를 다시 만들지 않고 한 번만 작성하여 솔루션에서 수행하지 않는 것처럼 들릴 수 있습니다.

우리는 모든 트리를 읽을 필요가 있기 때문에 많은 항목이 있으면 느려질 수 있습니다. 업데이트 범위가 제한적일 경우 git_tree_create_updated()을 사용하고 원하는 수정 내용을 제공 할 수 있습니다. 이 함수는 사용자가 제공 한 업데이트 목록의 결과로 변경 될 나무 만 읽습니다. 모든 것을 손으로하는 것처럼 유연하지는 않지만 가장 일반적인 경우를 다루고 있습니다.

전체 아키텍처에 대한 자세한 내용은없이

는 샤딩을 사용하지 않는 것보다 훨씬 느린 이유는 모르겠지만, 귀하의 코멘트에

나는 문제가 실제로 때문이라고 생각 그 shard에 새로운 BLOB를 추가 할 때마다 동일한 트리 빌더를 계속 작성해야한다는 것입니다.

O (n) 업데이트를 수행하는 것처럼 보이지만 확실하게 설명 할 수 있습니다.

또한 Git을 데이터베이스로 사용하려는 "수백만 개의 항목"이 있음을 언급합니다.내가 가지고있는 최선의 충고는 그것을하는 것이 아니라 대신 데이터베이스를 사용하는 데 투자하는 것입니다. 힘내 시스템은 데이터베이스와 매우 흡사하게 보이며 데이터베이스라고 불리는 것들을 포함하고 있지만 매우 일반적인 목적의 데이터베이스입니다.

+0

철저한 답변을 보내 주셔서 감사합니다. 나는 자식 인덱스 파일에 대해 몰랐다. 그래서 코드를 수정하여 실제로 그것을 단순화 할 수있는 것처럼 보일 것이다. git을 데이터베이스로 사용하는 것이 이상적이지는 않지만, 한계를 확인하기 위해 테스트하고 있습니다. – jboretsky