static struct cache_tree_sub *find_subtree(struct cache_tree *it, const char *path, int pathlen, int create) { struct cache_tree_sub *down; int pos = subtree_pos(it, path, pathlen); if (0 <= pos) return it->down[pos]; if (!create) return NULL; pos = -pos-1; ALLOC_GROW(it->down, it->subtree_nr + 1, it->subtree_alloc); it->subtree_nr++; FLEX_ALLOC_MEM(down, name, path, pathlen); down->cache_tree = NULL; down->namelen = pathlen; if (pos < it->subtree_nr) MOVE_ARRAY(it->down + pos + 1, it->down + pos, it->subtree_nr - pos - 1); it->down[pos] = down; return down; }
static struct dir_entry *hash_dir_entry(struct index_state *istate, struct cache_entry *ce, int namelen) { /* * Throw each directory component in the hash for quick lookup * during a git status. Directory components are stored without their * closing slash. Despite submodules being a directory, they never * reach this point, because they are stored * in index_state.name_hash (as ordinary cache_entries). */ struct dir_entry *dir; /* get length of parent directory */ while (namelen > 0 && !is_dir_sep(ce->name[namelen - 1])) namelen--; if (namelen <= 0) return NULL; namelen--; /* lookup existing entry for that directory */ dir = find_dir_entry(istate, ce->name, namelen); if (!dir) { /* not found, create it and add to hash table */ FLEX_ALLOC_MEM(dir, name, ce->name, namelen); hashmap_entry_init(dir, memihash(ce->name, namelen)); dir->namelen = namelen; hashmap_add(&istate->dir_hash, dir); /* recursively add missing parent directories */ dir->parent = hash_dir_entry(istate, ce, namelen); } return dir; }
void add_cmdname(struct cmdnames *cmds, const char *name, int len) { struct cmdname *ent; FLEX_ALLOC_MEM(ent, name, name, len); ent->len = len; ALLOC_GROW(cmds->names, cmds->cnt + 1, cmds->alloc); cmds->names[cmds->cnt++] = ent; }
struct ref_entry *create_dir_entry(struct ref_cache *cache, const char *dirname, size_t len, int incomplete) { struct ref_entry *direntry; FLEX_ALLOC_MEM(direntry, name, dirname, len); direntry->u.subdir.cache = cache; direntry->flag = REF_DIR | (incomplete ? REF_INCOMPLETE : 0); return direntry; }
static struct dir_entry *hash_dir_entry_with_parent_and_prefix( struct index_state *istate, struct dir_entry *parent, struct strbuf *prefix) { struct dir_entry *dir; unsigned int hash; int lock_nr; /* * Either we have a parent directory and path with slash(es) * or the directory is an immediate child of the root directory. */ assert((parent != NULL) ^ (strchr(prefix->buf, '/') == NULL)); if (parent) hash = memihash_cont(parent->ent.hash, prefix->buf + parent->namelen, prefix->len - parent->namelen); else hash = memihash(prefix->buf, prefix->len); lock_nr = compute_dir_lock_nr(&istate->dir_hash, hash); lock_dir_mutex(lock_nr); dir = find_dir_entry__hash(istate, prefix->buf, prefix->len, hash); if (!dir) { FLEX_ALLOC_MEM(dir, name, prefix->buf, prefix->len); hashmap_entry_init(dir, hash); dir->namelen = prefix->len; dir->parent = parent; hashmap_add(&istate->dir_hash, dir); if (parent) { unlock_dir_mutex(lock_nr); /* All I really need here is an InterlockedIncrement(&(parent->nr)) */ lock_nr = compute_dir_lock_nr(&istate->dir_hash, parent->ent.hash); lock_dir_mutex(lock_nr); parent->nr++; } } unlock_dir_mutex(lock_nr); return dir; }
static struct reflog_expire_cfg *find_cfg_ent(const char *pattern, size_t len) { struct reflog_expire_cfg *ent; if (!reflog_expire_cfg_tail) reflog_expire_cfg_tail = &reflog_expire_cfg; for (ent = reflog_expire_cfg; ent; ent = ent->next) if (!strncmp(ent->pattern, pattern, len) && ent->pattern[len] == '\0') return ent; FLEX_ALLOC_MEM(ent, pattern, pattern, len); *reflog_expire_cfg_tail = ent; reflog_expire_cfg_tail = &(ent->next); return ent; }
/* * Given a 'name', lookup and return the corresponding attribute in the global * dictionary. If no entry is found, create a new attribute and store it in * the dictionary. */ static const struct git_attr *git_attr_internal(const char *name, int namelen) { struct git_attr *a; if (!attr_name_valid(name, namelen)) return NULL; hashmap_lock(&g_attr_hashmap); a = attr_hashmap_get(&g_attr_hashmap, name, namelen); if (!a) { FLEX_ALLOC_MEM(a, name, name, namelen); a->attr_nr = g_attr_hashmap.map.size; attr_hashmap_add(&g_attr_hashmap, a->name, namelen, a); assert(a->attr_nr == (g_attr_hashmap.map.size - 1)); } hashmap_unlock(&g_attr_hashmap); return a; }