Show changes to 3 files +51 −72
cache.h, read-cache.c, read-tree.c
diff --git a/cache.h b/cache.h
--- a/cache.h
+++ b/cache.h
@@ -159,14 +159,13 @@ extern char *prefix_path(const char *pre
extern int read_cache(void);
extern int read_cache_unmerged(void);
extern int write_cache(int newfd);
-extern int cache_name_pos(const char *name, int namelen);
extern int cache_find_name(const char *name, int namelen, struct cache_cursor *cc);
#define ADD_CACHE_OK_TO_ADD 1 /* Ok to add */
#define ADD_CACHE_OK_TO_REPLACE 2 /* Ok to replace file/directory */
#define ADD_CACHE_SKIP_DFCHECK 4 /* Ok to skip DF conflict checks */
extern int add_cache_entry(struct cache_entry *ce, int option);
-extern int remove_cache_entry_at(int pos);
+extern int remove_cache_entry_at(struct cache_cursor *cc);
extern int remove_file_from_cache(char *path);
extern void prune_cache(const char *prefix, int prefix_len);
extern int ce_same_name(struct cache_entry *a, struct cache_entry *b);
diff --git a/read-cache.c b/read-cache.c
--- a/read-cache.c
+++ b/read-cache.c
@@ -123,27 +123,6 @@ int cache_name_compare(const char *name1
return 0;
}
-int cache_name_pos(const char *name, int namelen)
-{
- int first, last;
-
- first = 0;
- last = active_nr;
- while (last > first) {
- int next = (last + first) >> 1;
- struct cache_entry *ce = active_cache[next];
- int cmp = cache_name_compare(name, namelen, ce->name, ntohs(ce->ce_flags));
- if (!cmp)
- return next;
- if (cmp < 0) {
- last = next;
- continue;
- }
- first = next+1;
- }
- return -first-1;
-}
-
/*
* Given a name, find the first cache entry that matches. Returning 1
* means the cursor points to the cache entry with a matching name.
@@ -189,11 +168,13 @@ int cache_find_name(const char *name, in
}
/* Remove entry, return true if there are more entries to go.. */
-int remove_cache_entry_at(int pos)
+int remove_cache_entry_at(struct cache_cursor *cc)
{
+ int pos = cc->pos;
+
active_cache_changed = 1;
active_nr--;
- if (pos >= active_nr)
+ if (cache_eof(cc))
return 0;
memmove(active_cache + pos, active_cache + pos + 1, (active_nr - pos) * sizeof(struct cache_entry *));
return 1;
@@ -201,11 +182,11 @@ int remove_cache_entry_at(int pos)
int remove_file_from_cache(char *path)
{
- int pos = cache_name_pos(path, strlen(path));
- if (pos < 0)
- pos = -pos-1;
- while (pos < active_nr && !strcmp(active_cache[pos]->name, path))
- remove_cache_entry_at(pos);
+ struct cache_cursor cc;
+
+ cache_find_name(path, strlen(path), &cc);
+ while (!cache_eof(&cc) && !strcmp(cc_to_ce(&cc)->name, path))
+ remove_cache_entry_at(&cc);
return 0;
}
@@ -214,13 +195,12 @@ int remove_file_from_cache(char *path)
*/
void prune_cache(const char *prefix, int prefix_len)
{
- int pos = cache_name_pos(prefix, prefix_len);
+ struct cache_cursor cc;
unsigned int first, last;
- if (pos < 0)
- pos = -pos-1;
- active_cache += pos;
- active_nr -= pos;
+ cache_find_name(prefix, prefix_len, &cc);
+ active_cache += cc.pos;
+ active_nr -= cc.pos;
first = 0;
last = active_nr;
while (last > first) {
@@ -237,7 +217,8 @@ void prune_cache(const char *prefix, int
int ce_same_name(struct cache_entry *a, struct cache_entry *b)
{
- int len = ce_namelen(a);
+ int len;
+ len = ce_namelen(a);
return ce_namelen(b) == len && !memcmp(a->name, b->name, len);
}
@@ -271,28 +252,30 @@ int ce_path_match(const struct cache_ent
* Do we have another file that has the beginning components being a
* proper superset of the name we're trying to add?
*/
-static int has_file_name(const struct cache_entry *ce, int pos, int ok_to_replace)
+static int has_file_name(const struct cache_entry *ce, struct cache_cursor *cc, int ok_to_replace)
{
int retval = 0;
int len = ce_namelen(ce);
int stage = ce_stage(ce);
const char *name = ce->name;
- while (pos < active_nr) {
- struct cache_entry *p = active_cache[pos++];
+ while (!cache_eof(cc)) {
+ struct cache_entry *p = cc_to_ce(cc);
if (len >= ce_namelen(p))
break;
if (memcmp(name, p->name, len))
break;
if (ce_stage(p) != stage)
- continue;
+ goto next;
if (p->name[len] != '/')
- continue;
+ goto next;
retval = -1;
if (!ok_to_replace)
break;
- remove_cache_entry_at(--pos);
+ remove_cache_entry_at(cc);
+next:
+ next_cc(cc);
}
return retval;
}
@@ -301,8 +284,9 @@ static int has_file_name(const struct ca
* Do we have another file with a pathname that is a proper
* subset of the name we're trying to add?
*/
-static int has_dir_name(const struct cache_entry *ce, int pos, int ok_to_replace)
+static int has_dir_name(const struct cache_entry *ce, int ok_to_replace)
{
+ struct cache_cursor cc;
int retval = 0;
int stage = ce_stage(ce);
const char *name = ce->name;
@@ -319,12 +303,11 @@ static int has_dir_name(const struct cac
}
len = slash - name;
- pos = cache_name_pos(name, ntohs(create_ce_flags(len, stage)));
- if (pos >= 0) {
+ if (cache_find_name(name, ntohs(create_ce_flags(len, stage)), &cc)) {
retval = -1;
if (ok_to_replace)
break;
- remove_cache_entry_at(pos);
+ remove_cache_entry_at(&cc);
continue;
}
@@ -333,9 +316,8 @@ static int has_dir_name(const struct cac
* already matches the sub-directory, then we know
* we're ok, and we can exit.
*/
- pos = -pos-1;
- while (pos < active_nr) {
- struct cache_entry *p = active_cache[pos];
+ while (!cache_eof(&cc)) {
+ struct cache_entry *p = cc_to_ce(&cc);
if ((ce_namelen(p) <= len) ||
(p->name[len] != '/') ||
memcmp(p->name, name, len))
@@ -347,7 +329,7 @@ static int has_dir_name(const struct cac
* level or anything shorter.
*/
return retval;
- pos++;
+ next_cc(&cc);
}
}
return retval;
@@ -362,45 +344,41 @@ static int has_dir_name(const struct cac
* from the cache so the caller should recompute the insert position.
* When this happens, we return non-zero.
*/
-static int check_file_directory_conflict(const struct cache_entry *ce, int pos, int ok_to_replace)
+static int check_file_directory_conflict(const struct cache_entry *ce, struct cache_cursor *cc, int ok_to_replace)
{
+ struct cache_cursor cd = *cc;
/*
* We check if the path is a sub-path of a subsequent pathname
* first, since removing those will not change the position
* in the array
*/
- int retval = has_file_name(ce, pos, ok_to_replace);
+ int retval = has_file_name(ce, &cd, ok_to_replace);
/*
* Then check if the path might have a clashing sub-directory
* before it.
*/
- return retval + has_dir_name(ce, pos, ok_to_replace);
+ return retval + has_dir_name(ce, ok_to_replace);
}
int add_cache_entry(struct cache_entry *ce, int option)
{
- int pos;
+ struct cache_cursor cc;
int ok_to_add = option & ADD_CACHE_OK_TO_ADD;
int ok_to_replace = option & ADD_CACHE_OK_TO_REPLACE;
int skip_df_check = option & ADD_CACHE_SKIP_DFCHECK;
- pos = cache_name_pos(ce->name, ntohs(ce->ce_flags));
/* existing match? Just replace it */
- if (pos >= 0) {
- active_cache_changed = 1;
- active_cache[pos] = ce;
- return 0;
- }
- pos = -pos-1;
+ if (cache_find_name(ce->name, ntohs(ce->ce_flags), &cc))
+ goto out;
/*
* Inserting a merged entry ("stage 0") into the index
* will always replace all non-merged entries..
*/
- if (pos < active_nr && ce_stage(ce) == 0) {
- while (ce_same_name(active_cache[pos], ce)) {
+ if (!cache_eof(&cc) && ce_stage(ce) == 0) {
+ while (ce_same_name(cc_to_ce(&cc), ce)) {
ok_to_add = 1;
- if (!remove_cache_entry_at(pos))
+ if (!remove_cache_entry_at(&cc))
break;
}
}
@@ -408,11 +386,10 @@ int add_cache_entry(struct cache_entry *
if (!ok_to_add)
return -1;
- if (!skip_df_check && check_file_directory_conflict(ce, pos, ok_to_replace)) {
+ if (!skip_df_check && check_file_directory_conflict(ce, &cc, ok_to_replace)) {
if (!ok_to_replace)
return -1;
- pos = cache_name_pos(ce->name, ntohs(ce->ce_flags));
- pos = -pos-1;
+ cache_find_name(ce->name, ntohs(ce->ce_flags), &cc);
}
/* Make sure the array is big enough .. */
@@ -423,10 +400,13 @@ int add_cache_entry(struct cache_entry *
/* Add it in.. */
active_nr++;
- if (active_nr > pos)
+ if (!cache_eof(&cc)) {
+ int pos = cc.pos;
memmove(active_cache + pos + 1, active_cache + pos, (active_nr - pos - 1) * sizeof(ce));
- active_cache[pos] = ce;
- active_cache_changed = 1;
+ }
+
+out:
+ set_ce_at_cursor(&cc, ce);
return 0;
}
@@ -456,7 +436,7 @@ int read_cache(void)
struct cache_header *hdr;
errno = EBUSY;
- if (active_cache)
+ if (!read_cache_needed())
return error("more than one cachefile");
errno = ENOENT;
fd = open(get_index_file(), O_RDONLY);
diff --git a/read-tree.c b/read-tree.c
--- a/read-tree.c
+++ b/read-tree.c
@@ -135,7 +135,7 @@ static int unpack_trees_rec(struct tree_
if (cache_name && !strcmp(cache_name, first)) {
any_files = 1;
src[0] = cc_to_ce(cc);
- remove_cache_entry_at(cc->pos);
+ remove_cache_entry_at(cc);
}
for (i = 0; i < len; i++) {