-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This split-index mode is designed to keep write cost proportional to the number of changes the user has made, not the size of the work tree. (Read cost is another matter, to be dealt separately.) This mode stores index info in a pair of $GIT_DIR/index and $GIT_DIR/sharedindex.<SHA-1>. sharedindex is large and unchanged over time while "index" is smaller and updated often. Format details are in index-format.txt, although not everything is implemented in this patch. Shared indexes are not automatically removed, because it's unclear if the shared index is needed by any (even temporary) indexes by just looking at it. After a while you'll collect stale shared indexes. The good news is one shared index is useable for long, until $GIT_DIR/index becomes too big and sluggish that the new shared index must be created. The safest way to clean shared indexes is to turn off split index mode, so shared files are all garbage, delete them all, then turn on split index mode again. Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
- Loading branch information
Nguyễn Thái Ngọc Duy
authored and
Junio C Hamano
committed
Jun 13, 2014
1 parent
e93021b
commit 5fc2fc8
Showing
8 changed files
with
253 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
#include "cache.h" | ||
#include "split-index.h" | ||
|
||
struct split_index *init_split_index(struct index_state *istate) | ||
{ | ||
if (!istate->split_index) { | ||
istate->split_index = xcalloc(1, sizeof(*istate->split_index)); | ||
istate->split_index->refcount = 1; | ||
} | ||
return istate->split_index; | ||
} | ||
|
||
int read_link_extension(struct index_state *istate, | ||
const void *data_, unsigned long sz) | ||
{ | ||
const unsigned char *data = data_; | ||
struct split_index *si; | ||
if (sz < 20) | ||
return error("corrupt link extension (too short)"); | ||
si = init_split_index(istate); | ||
hashcpy(si->base_sha1, data); | ||
data += 20; | ||
sz -= 20; | ||
if (sz) | ||
return error("garbage at the end of link extension"); | ||
return 0; | ||
} | ||
|
||
int write_link_extension(struct strbuf *sb, | ||
struct index_state *istate) | ||
{ | ||
struct split_index *si = istate->split_index; | ||
strbuf_add(sb, si->base_sha1, 20); | ||
return 0; | ||
} | ||
|
||
static void mark_base_index_entries(struct index_state *base) | ||
{ | ||
int i; | ||
/* | ||
* To keep track of the shared entries between | ||
* istate->base->cache[] and istate->cache[], base entry | ||
* position is stored in each base entry. All positions start | ||
* from 1 instead of 0, which is resrved to say "this is a new | ||
* entry". | ||
*/ | ||
for (i = 0; i < base->cache_nr; i++) | ||
base->cache[i]->index = i + 1; | ||
} | ||
|
||
void merge_base_index(struct index_state *istate) | ||
{ | ||
struct split_index *si = istate->split_index; | ||
|
||
mark_base_index_entries(si->base); | ||
istate->cache_nr = si->base->cache_nr; | ||
ALLOC_GROW(istate->cache, istate->cache_nr, istate->cache_alloc); | ||
memcpy(istate->cache, si->base->cache, | ||
sizeof(*istate->cache) * istate->cache_nr); | ||
} | ||
|
||
void prepare_to_write_split_index(struct index_state *istate) | ||
{ | ||
struct split_index *si = init_split_index(istate); | ||
/* take cache[] out temporarily */ | ||
si->saved_cache_nr = istate->cache_nr; | ||
istate->cache_nr = 0; | ||
} | ||
|
||
void finish_writing_split_index(struct index_state *istate) | ||
{ | ||
struct split_index *si = init_split_index(istate); | ||
istate->cache_nr = si->saved_cache_nr; | ||
} | ||
|
||
void discard_split_index(struct index_state *istate) | ||
{ | ||
struct split_index *si = istate->split_index; | ||
if (!si) | ||
return; | ||
istate->split_index = NULL; | ||
si->refcount--; | ||
if (si->refcount) | ||
return; | ||
if (si->base) { | ||
discard_index(si->base); | ||
free(si->base); | ||
} | ||
free(si); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
#ifndef SPLIT_INDEX_H | ||
#define SPLIT_INDEX_H | ||
|
||
struct index_state; | ||
struct strbuf; | ||
|
||
struct split_index { | ||
unsigned char base_sha1[20]; | ||
struct index_state *base; | ||
unsigned int saved_cache_nr; | ||
int refcount; | ||
}; | ||
|
||
struct split_index *init_split_index(struct index_state *istate); | ||
int read_link_extension(struct index_state *istate, | ||
const void *data, unsigned long sz); | ||
int write_link_extension(struct strbuf *sb, | ||
struct index_state *istate); | ||
void move_cache_to_base_index(struct index_state *istate); | ||
void merge_base_index(struct index_state *istate); | ||
void prepare_to_write_split_index(struct index_state *istate); | ||
void finish_writing_split_index(struct index_state *istate); | ||
void discard_split_index(struct index_state *istate); | ||
|
||
#endif |
Oops, something went wrong.