Beispiel #1
0
/*
 * Test performance of hashmap.[ch]
 * Usage: time echo "perfhashmap method rounds" | test-hashmap
 */
static void perf_hashmap(unsigned int method, unsigned int rounds)
{
	struct hashmap map;
	char buf[16];
	struct test_entry **entries;
	unsigned int *hashes;
	unsigned int i, j;

	entries = malloc(TEST_SIZE * sizeof(struct test_entry *));
	hashes = malloc(TEST_SIZE * sizeof(int));
	for (i = 0; i < TEST_SIZE; i++) {
		snprintf(buf, sizeof(buf), "%i", i);
		entries[i] = alloc_test_entry(0, buf, strlen(buf), "", 0);
		hashes[i] = hash(method, i, entries[i]->key);
	}

	if (method & TEST_ADD) {
		/* test adding to the map */
		for (j = 0; j < rounds; j++) {
			hashmap_init(&map, (hashmap_cmp_fn) test_entry_cmp, 0);

			/* add entries */
			for (i = 0; i < TEST_SIZE; i++) {
				hashmap_entry_init(entries[i], hashes[i]);
				hashmap_add(&map, entries[i]);
			}

			hashmap_free(&map, 0);
		}
	} else {
		/* test map lookups */
		hashmap_init(&map, (hashmap_cmp_fn) test_entry_cmp, 0);

		/* fill the map (sparsely if specified) */
		j = (method & TEST_SPARSE) ? TEST_SIZE / 10 : TEST_SIZE;
		for (i = 0; i < j; i++) {
			hashmap_entry_init(entries[i], hashes[i]);
			hashmap_add(&map, entries[i]);
		}

		for (j = 0; j < rounds; j++) {
			for (i = 0; i < TEST_SIZE; i++) {
				hashmap_get_from_hash(&map, hashes[i],
						      entries[i]->key);
			}
		}

		hashmap_free(&map, 0);
	}
}
Beispiel #2
0
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;
}
Beispiel #3
0
node *LVARglobaldef( node *arg_node, info *arg_info)
{
    char *var_name;

    DBUG_ENTER("LVARglobaldef");

    var_name = VAR_NAME(GLOBALDEF_ID( arg_node));

    /* set declaration of this global variable */
    VAR_DECL(GLOBALDEF_ID( arg_node) ) = arg_node;

    /* check for duplicated variable declaration */
    if(hashmap_contains(arg_info->global, var_name)) {
        CTIerror(":%d: error: '%s' has already been defined in this context",
                NODE_LINE(arg_node), var_name);

        CTIerror(":%d: error: location of earlier definition",
                NODE_LINE((node *)hashmap_get(arg_info->global, var_name)));
        DBUG_RETURN(arg_node);
    }

    /* add global variabele declaration to hashmap */
    hashmap_add(arg_info->global, var_name, arg_node);

    DBUG_RETURN( arg_node);
}
Beispiel #4
0
/*
 * Adds a directory listing to the cache.
 */
static void fscache_add(struct fscache *cache, struct fsentry *fse)
{
	if (fse->list)
		fse = fse->list;

	for (; fse; fse = fse->next)
		hashmap_add(&cache->map, fse);
}
Beispiel #5
0
static void cache_add(struct submodule_cache *cache,
		      struct submodule *submodule)
{
	unsigned int hash = hash_sha1_string(submodule->gitmodules_sha1,
					     submodule->name);
	struct submodule_entry *e = xmalloc(sizeof(*e));
	hashmap_entry_init(e, hash);
	e->config = submodule;
	hashmap_add(&cache->for_name, e);
}
Beispiel #6
0
static void hash_index_entry(struct index_state *istate, struct cache_entry *ce)
{
	if (ce->ce_flags & CE_HASHED)
		return;
	ce->ce_flags |= CE_HASHED;
	hashmap_entry_init(ce, memihash(ce->name, ce_namelen(ce)));
	hashmap_add(&istate->name_hash, ce);

	if (ignore_case)
		add_dir_entry(istate, ce);
}
Beispiel #7
0
static void changed_files(struct hashmap *result, const char *index_path,
			  const char *workdir)
{
	struct child_process update_index = CHILD_PROCESS_INIT;
	struct child_process diff_files = CHILD_PROCESS_INIT;
	struct strbuf index_env = STRBUF_INIT, buf = STRBUF_INIT;
	const char *git_dir = absolute_path(get_git_dir()), *env[] = {
		NULL, NULL
	};
	FILE *fp;

	strbuf_addf(&index_env, "GIT_INDEX_FILE=%s", index_path);
	env[0] = index_env.buf;

	argv_array_pushl(&update_index.args,
			 "--git-dir", git_dir, "--work-tree", workdir,
			 "update-index", "--really-refresh", "-q",
			 "--unmerged", NULL);
	update_index.no_stdin = 1;
	update_index.no_stdout = 1;
	update_index.no_stderr = 1;
	update_index.git_cmd = 1;
	update_index.use_shell = 0;
	update_index.clean_on_exit = 1;
	update_index.dir = workdir;
	update_index.env = env;
	/* Ignore any errors of update-index */
	run_command(&update_index);

	argv_array_pushl(&diff_files.args,
			 "--git-dir", git_dir, "--work-tree", workdir,
			 "diff-files", "--name-only", "-z", NULL);
	diff_files.no_stdin = 1;
	diff_files.git_cmd = 1;
	diff_files.use_shell = 0;
	diff_files.clean_on_exit = 1;
	diff_files.out = -1;
	diff_files.dir = workdir;
	diff_files.env = env;
	if (start_command(&diff_files))
		die("could not obtain raw diff");
	fp = xfdopen(diff_files.out, "r");
	while (!strbuf_getline_nul(&buf, fp)) {
		struct path_entry *entry;
		FLEX_ALLOC_STR(entry, path, buf.buf);
		hashmap_entry_init(entry, strhash(buf.buf));
		hashmap_add(result, entry);
	}
	fclose(fp);
	if (finish_command(&diff_files))
		die("diff-files did not exit properly");
	strbuf_release(&index_env);
	strbuf_release(&buf);
}
Beispiel #8
0
void
_isvn_commitdrain_add(unsigned rev, int incr)
{
	struct fetchdone_range *newr, *exist, key;

	key.r_lo = rev;
	hashmap_entry_init(&key.r_entry, memhash(&key.r_lo, sizeof(key.r_lo)));

	if (incr > 0) {
		newr = xmalloc(sizeof(*newr));
		newr->r_lo = rev;
		newr->r_hi = incr;  /* reused as refcnt */
		hashmap_entry_init(&newr->r_entry,
		    memhash(&newr->r_lo, sizeof(newr->r_lo)));
	} else
		newr = NULL;

	isvn_g_lock();
	exist = hashmap_get(&g_commitdrain_hash, &key);

	if (incr > 0) {
		if (exist)
			exist->r_hi += incr;
		else
			hashmap_add(&g_commitdrain_hash, newr);
	} else {
		int refcnt;

		/* INVARIANTS */
		if (exist == NULL)
			die("negative refcnt %d (ne)", incr);

		refcnt = (int)exist->r_hi + incr;

		/* INVARIANTS */
		if (refcnt < 0)
			die("negative refcnt %d", refcnt);

		if (refcnt > 0)
			exist->r_hi = refcnt;
		else {
			hashmap_remove(&g_commitdrain_hash, exist);
			/* free it below */
			newr = exist;
		}
	}
	isvn_g_unlock();

	if (exist && newr)
		free(newr);
}
Beispiel #9
0
static void *lazy_name_thread_proc(void *_data)
{
	struct lazy_name_thread_data *d = _data;
	int k;

	for (k = 0; k < d->istate->cache_nr; k++) {
		struct cache_entry *ce_k = d->istate->cache[k];
		ce_k->ce_flags |= CE_HASHED;
		hashmap_entry_init(ce_k, d->lazy_entries[k].hash_name);
		hashmap_add(&d->istate->name_hash, ce_k);
	}

	return NULL;
}
Beispiel #10
0
struct patch_id *add_commit_patch_id(struct commit *commit,
				     struct patch_ids *ids)
{
	struct patch_id *key = xcalloc(1, sizeof(*key));

	if (!patch_id_defined(commit))
		return NULL;

	if (init_patch_id_entry(key, commit, ids)) {
		free(key);
		return NULL;
	}

	hashmap_add(&ids->patches, key);
	return key;
}
Beispiel #11
0
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;
}
Beispiel #12
0
void fscache_merge(struct fscache *dest)
{
	struct hashmap_iter iter;
	struct hashmap_entry *e;
	struct fscache *cache = fscache_getcache();

	/*
	 * Only do the merge if fscache was enabled and we have a dest
	 * cache to merge into.
	 */
	if (!dest) {
		fscache_enable(0);
		return;
	}
	if (!cache)
		BUG("fscache_merge() called on a thread where fscache has not been initialized");

	TlsSetValue(dwTlsIndex, NULL);
	trace_printf_key(&trace_fscache, "fscache_merge: lstat %u, opendir %u, "
		"total requests/misses %u/%u\n",
		cache->lstat_requests, cache->opendir_requests,
		cache->fscache_requests, cache->fscache_misses);

	/*
	 * This is only safe because the primary thread we're merging into
	 * isn't being used so the critical section only needs to prevent
	 * the the child threads from stomping on each other.
	 */
	EnterCriticalSection(&fscache_cs);

	hashmap_iter_init(&cache->map, &iter);
	while ((e = hashmap_iter_next(&iter)))
		hashmap_add(&dest->map, e);

	mem_pool_combine(dest->mem_pool, cache->mem_pool);

	dest->lstat_requests += cache->lstat_requests;
	dest->opendir_requests += cache->opendir_requests;
	dest->fscache_requests += cache->fscache_requests;
	dest->fscache_misses += cache->fscache_misses;
	initialized--;
	LeaveCriticalSection(&fscache_cs);

	free(cache);

}
Beispiel #13
0
/* Add 'value' to a hashmap based on the provided 'key'. */
static void attr_hashmap_add(struct attr_hashmap *map,
			     const char *key, size_t keylen,
			     void *value)
{
	struct attr_hash_entry *e;

	if (!map->map.tablesize)
		attr_hashmap_init(map);

	e = xmalloc(sizeof(struct attr_hash_entry));
	hashmap_entry_init(e, memhash(key, keylen));
	e->key = key;
	e->keylen = keylen;
	e->value = value;

	hashmap_add(&map->map, e);
}
Beispiel #14
0
static void add_left_or_right(struct hashmap *map, const char *path,
			      const char *content, int is_right)
{
	struct pair_entry *e, *existing;

	FLEX_ALLOC_STR(e, path, path);
	hashmap_entry_init(e, strhash(path));
	existing = hashmap_get(map, e, NULL);
	if (existing) {
		free(e);
		e = existing;
	} else {
		e->left[0] = e->right[0] = '\0';
		hashmap_add(map, e);
	}
	strlcpy(is_right ? e->right : e->left, content, PATH_MAX);
}
Beispiel #15
0
void
isvn_mark_fetchdone(unsigned revlo, unsigned revhi)
{
	struct fetchdone_range *done, *exist, key;

	done = xmalloc(sizeof(*done));
	if (done == NULL)
		die("malloc");

	isvn_g_lock();
	if (g_rev_fetchdone == revlo - 1) {
		g_rev_fetchdone = revhi;

		while (true) {
			key.r_lo = revhi + 1;
			hashmap_entry_init(&key.r_entry,
				memhash(&key.r_lo, sizeof(key.r_lo)));

			exist = hashmap_remove(&g_fetchdone_hash, &key);
			if (!exist)
				break;

			g_rev_fetchdone = revhi = exist->r_hi;
			free(exist);
		}

		cond_broadcast(&g_rev_cond);
	} else {
		done->r_lo = revlo;
		done->r_hi = revhi;
		hashmap_entry_init(&done->r_entry,
			memhash(&done->r_lo, sizeof(done->r_lo)));
		hashmap_add(&g_fetchdone_hash, done);
		done = NULL;
	}
	isvn_g_unlock();

	if (done)
		free(done);
}
Beispiel #16
0
static void find_exact_matches(struct string_list *a, struct string_list *b)
{
	struct hashmap map;
	int i;

	hashmap_init(&map, (hashmap_cmp_fn)patch_util_cmp, NULL, 0);

	/* First, add the patches of a to a hash map */
	for (i = 0; i < a->nr; i++) {
		struct patch_util *util = a->items[i].util;

		util->i = i;
		util->patch = a->items[i].string;
		util->diff = util->patch + util->diff_offset;
		hashmap_entry_init(util, strhash(util->diff));
		hashmap_add(&map, util);
	}

	/* Now try to find exact matches in b */
	for (i = 0; i < b->nr; i++) {
		struct patch_util *util = b->items[i].util, *other;

		util->i = i;
		util->patch = b->items[i].string;
		util->diff = util->patch + util->diff_offset;
		hashmap_entry_init(util, strhash(util->diff));
		other = hashmap_remove(&map, util, NULL);
		if (other) {
			if (other->matching >= 0)
				BUG("already assigned!");

			other->matching = i;
			util->matching = other->i;
		}
	}

	hashmap_free(&map, 0);
}
Beispiel #17
0
Datei: describe.c Projekt: 9b/git
static void add_to_known_names(const char *path,
			       const unsigned char *peeled,
			       int prio,
			       const unsigned char *sha1)
{
	struct commit_name *e = find_commit_name(peeled);
	struct tag *tag = NULL;
	if (replace_name(e, prio, sha1, &tag)) {
		if (!e) {
			e = xmalloc(sizeof(struct commit_name));
			hashcpy(e->peeled, peeled);
			hashmap_entry_init(e, sha1hash(peeled));
			hashmap_add(&names, e);
			e->path = NULL;
		}
		e->tag = tag;
		e->prio = prio;
		e->name_checked = 0;
		hashcpy(e->sha1, sha1);
		free(e->path);
		e->path = xstrdup(path);
	}
}
Beispiel #18
0
int subprocess_start(struct hashmap *hashmap, struct subprocess_entry *entry, const char *cmd,
	subprocess_start_fn startfn)
{
	int err;
	struct child_process *process;
	const char *argv[] = { cmd, NULL };

	entry->cmd = cmd;
	process = &entry->process;

	child_process_init(process);
	process->argv = argv;
	process->use_shell = 1;
	process->in = -1;
	process->out = -1;
	process->clean_on_exit = 1;
	process->clean_on_exit_handler = subprocess_exit_handler;

	err = start_command(process);
	if (err) {
		error("cannot fork to run subprocess '%s'", cmd);
		return err;
	}

	hashmap_entry_init(entry, strhash(cmd));

	err = startfn(entry);
	if (err) {
		error("initialization for subprocess '%s' failed", cmd);
		subprocess_stop(hashmap, entry);
		return err;
	}

	hashmap_add(hashmap, entry);
	return 0;
}
Beispiel #19
0
void hashmap_test(void)
{
    printf("hashmap: running tests...");
    
    Hashmap *map_1;
    
    map_1 = hashmap_create(100, NULL, &hashmap_hash_cstring, &hashmap_compare_cstring);
    hashmap_add(map_1, "pickles", (void*)pickle_value);
    assert( hashmap_count(map_1) == 1 );
    
    assert( hashmap_contains(map_1, "apricots") == HASHMAP_NOT_FOUND );
    assert( hashmap_contains(map_1, "pickles") == HASHMAP_FOUND );
    
    assert( hashmap_item(map_1, "apricots") == NULL );
    assert( hashmap_item(map_1, "pickles") == pickle_value );
    
    hashmap_add(map_1, "pickles", (void*)pickle_value);
    assert( hashmap_count(map_1) == 1 );
    
    hashmap_add(map_1, "apples", (void*)apple_value);
    assert( hashmap_count(map_1) == 2 );
    
    assert( hashmap_contains(map_1, "apricots") == HASHMAP_NOT_FOUND );
    assert( hashmap_contains(map_1, "pickles") == HASHMAP_FOUND );
    assert( hashmap_contains(map_1, "apples") == HASHMAP_FOUND );
    
    assert( hashmap_item(map_1, "apricots") == NULL );
    assert( hashmap_item(map_1, "pickles") == pickle_value );
    assert( hashmap_item(map_1, "apples") == apple_value );
    
    hashmap_add(map_1, "pizza", (void*)pizza_value);
    assert( hashmap_count(map_1) == 3 );
    
    assert( hashmap_contains(map_1, "apricots") == HASHMAP_NOT_FOUND );
    assert( hashmap_contains(map_1, "pickles") == HASHMAP_FOUND );
    assert( hashmap_contains(map_1, "apples") == HASHMAP_FOUND );
    assert( hashmap_contains(map_1, "pizza") == HASHMAP_FOUND );
    
    assert( hashmap_item(map_1, "apricots") == NULL );
    assert( hashmap_item(map_1, "pickles") == pickle_value );
    assert( hashmap_item(map_1, "apples") == apple_value );
    assert( hashmap_item(map_1, "pizza") == pizza_value );
    
    assert(map_1->buckets[28].pair_count == 1);
    assert(map_1->buckets[66].pair_count == 1);
    assert(map_1->buckets[51].pair_count == 1);
    assert(map_1->buckets[10].pair_count == 0);
    
    hashmap_enumerate(map_1, test_enumerator_);
    
    hashmap_remove(map_1, "apples");
    assert( hashmap_count(map_1) == 2 );
    
    assert( hashmap_contains(map_1, "apricots") == HASHMAP_NOT_FOUND );
    assert( hashmap_contains(map_1, "pickles") == HASHMAP_FOUND );
    assert( hashmap_contains(map_1, "apples") == HASHMAP_NOT_FOUND );
    assert( hashmap_contains(map_1, "pizza") == HASHMAP_FOUND );
    
    assert( hashmap_item(map_1, "apricots") == NULL );
    assert( hashmap_item(map_1, "pickles") == pickle_value );
    assert( hashmap_item(map_1, "apples") == NULL );
    assert( hashmap_item(map_1, "pizza") == pizza_value );
    
    hashmap_clear(map_1);
    assert( hashmap_count(map_1) == 0 );
    
    hashmap_dispose(map_1);
    
    assert( (unsigned long)hashmap_hash_cstring(NULL, "pickles") % 100 == 28 );
    assert( (unsigned long)hashmap_hash_cstring(NULL, "apples") % 100 == 66 );
    assert( (unsigned long)hashmap_hash_cstring(NULL, "pizza") % 100 == 51 );
    assert( (unsigned long)hashmap_hash_cstring(NULL, "apricots") % 100 == 10 );
    
    map_1 = hashmap_create(1, NULL, &hashmap_hash_cstring, &hashmap_compare_cstring);
    hashmap_add(map_1, "pickles", (void*)pickle_value);
    assert( hashmap_count(map_1) == 1 );
    hashmap_add(map_1, "pizza", (void*)pizza_value);
    assert( hashmap_count(map_1) == 2 );
    hashmap_add(map_1, "apples", (void*)apple_value);
    assert( hashmap_count(map_1) == 3 );
    
    assert( hashmap_contains(map_1, "apricots") == HASHMAP_NOT_FOUND );
    assert( hashmap_contains(map_1, "pickles") == HASHMAP_FOUND );
    assert( hashmap_contains(map_1, "apples") == HASHMAP_FOUND );
    assert( hashmap_contains(map_1, "pizza") == HASHMAP_FOUND );
    
    assert( hashmap_item(map_1, "apricots") == NULL );
    assert( hashmap_item(map_1, "pickles") == pickle_value );
    assert( hashmap_item(map_1, "apples") == apple_value );
    assert( hashmap_item(map_1, "pizza") == pizza_value );
    
    assert(map_1->buckets[0].pair_count == 3);
    
    hashmap_add(map_1, "pizza", (void*)apple_value);
    assert( hashmap_count(map_1) == 3 );
    
    assert( hashmap_contains(map_1, "apricots") == HASHMAP_NOT_FOUND );
    assert( hashmap_contains(map_1, "pickles") == HASHMAP_FOUND );
    assert( hashmap_contains(map_1, "apples") == HASHMAP_FOUND );
    assert( hashmap_contains(map_1, "pizza") == HASHMAP_FOUND );
    
    assert( hashmap_item(map_1, "apricots") == NULL );
    assert( hashmap_item(map_1, "pickles") == pickle_value );
    assert( hashmap_item(map_1, "apples") == apple_value );
    assert( hashmap_item(map_1, "pizza") == apple_value );
    
    assert(strcmp(map_1->buckets[0].pairs[0]->key, "apples") == 0);
    assert(strcmp(map_1->buckets[0].pairs[1]->key, "pickles") == 0);
    assert(strcmp(map_1->buckets[0].pairs[2]->key, "pizza") == 0);
    
    hashmap_dispose(map_1);
    
    printf("ok.\n");
}
Beispiel #20
0
/*
 * Looks up or creates a cache entry for the specified key.
 */
static struct fsentry *fscache_get(struct fscache *cache, struct fsentry *key)
{
	struct fsentry *fse;
	int dir_not_found;

	cache->fscache_requests++;
	/* check if entry is in cache */
	fse = hashmap_get(&cache->map, key, NULL);
	if (fse) {
		if (fse->st_mode)
			fsentry_addref(fse);
		else
			fse = NULL; /* non-existing directory */
		return fse;
	}
	/* if looking for a file, check if directory listing is in cache */
	if (!fse && key->list) {
		fse = hashmap_get(&cache->map, key->list, NULL);
		if (fse) {
			/*
			 * dir entry without file entry, or dir does not
			 * exist -> file doesn't exist
			 */
			errno = ENOENT;
			return NULL;
		}
	}

	/* create the directory listing */
	fse = fsentry_create_list(cache, key->list ? key->list : key, &dir_not_found);

	/* leave on error (errno set by fsentry_create_list) */
	if (!fse) {
		if (dir_not_found && key->list) {
			/*
			 * Record that the directory does not exist (or is
			 * empty, which for all practical matters is the same
			 * thing as far as fscache is concerned).
			 */
			fse = fsentry_alloc(cache, key->list->list,
					    key->list->name, key->list->len);
			fse->st_mode = 0;
			hashmap_add(&cache->map, fse);
		}
		return NULL;
	}

	/* add directory listing to the cache */
	cache->fscache_misses++;
	fscache_add(cache, fse);

	/* lookup file entry if requested (fse already points to directory) */
	if (key->list)
		fse = hashmap_get(&cache->map, key, NULL);

	if (fse && !fse->st_mode)
		fse = NULL; /* non-existing directory */

	/* return entry or ENOENT */
	if (fse)
		fsentry_addref(fse);
	else
		errno = ENOENT;

	return fse;
}
Beispiel #21
0
int fatfs_vfs_lookup( struct file_node *node, struct file_node *buf, char *name, int flags ){
	int ret = -ERROR_NOT_FOUND;
	fatfs_device_t *dev = node->fs->devstruct;

	unsigned cluster_size;
	//char namebuf[256];
	char *namebuf;
	uint8_t *sectbuf;
	int i;
	int has_longname = 0;

	fatfs_dirent_t *dirbuf;
	fatfs_dircache_t *dircache;
	fatfs_dircache_t *newcache;
	fatfs_longname_ent_t *longentbuf;

	dircache = hashmap_get( dev->inode_map, node->inode );

	if ( dircache ){
		namebuf = knew( char[ 256 ]);

		if ( dircache->dir.attributes & FAT_ATTR_DIRECTORY ){

			cluster_size = dev->bpb->bytes_per_sect * dev->bpb->sect_per_clus;
			sectbuf = knew( uint8_t[cluster_size] ); 
			dirbuf = (void *)sectbuf;

			VFS_FUNCTION(( &dev->device_node ), read, sectbuf,
					cluster_size, dev->bpb->bytes_per_sect * node->inode );

			for ( i = 0; i < dev->bpb->dirents; i++ ){

				if ( *(char *)(dirbuf + i) == 0 || *(char *)(dirbuf + i) == 0xe5 )
					continue;

				if ( dirbuf[i].attributes == FAT_ATTR_LONGNAME ){
					longentbuf = (void *)(dirbuf + i);
					fatfs_apply_longname( longentbuf, namebuf, 256 );
					has_longname = 1;

				} else {
					char *fname = has_longname? namebuf : (char *)dirbuf[i].name;

					if ( strcmp( name, fname ) == 0 ){
						// Found it, cool
						newcache = knew( fatfs_dircache_t );
						memcpy( &newcache->dir, dirbuf + i, sizeof( fatfs_dirent_t ));
						newcache->references = 0;

						buf->inode = fatfs_relclus_to_sect( dev, newcache->dir.cluster_low );
						buf->fs = node->fs;
						buf->mount = 0;

						if ( hashmap_get( dev->inode_map, buf->inode ) == 0 )
							hashmap_add( dev->inode_map, buf->inode, newcache );

						ret = 0;
						break;
					}

					has_longname = 0;
					namebuf[0] = 0;
				}
			}

			kfree( sectbuf );

		} else {
			ret = -ERROR_NOT_DIRECTORY;
		}

		kfree( namebuf );
	} else {
Beispiel #22
0
void myHashMapPut(MyHashMap*obj, int key, int value){
    hashmap_add(hm, key, value);
}
Beispiel #23
0
void
isvn_mark_commitdone(unsigned revlo, unsigned revhi)
{
	struct fetchdone_range *done, *exist, key;
	struct fetchdone_range *drainex, drainkey;

	/* In particular, checking for refs in need of draining ... for each
	 * rev in range. */
	if (revlo != revhi)
		die("XXX batched commitdones notimpl.");

	done = xmalloc(sizeof(*done));

	drainkey.r_lo = revlo;
	hashmap_entry_init(&drainkey.r_entry,
	    memhash(&drainkey.r_lo, sizeof(drainkey.r_lo)));

	isvn_g_lock();

	/* For revs with multiple branch edits (rare), wait until all commits
	 * are in before marking done. */
	drainex = hashmap_get(&g_commitdrain_hash, &drainkey);
	if (drainex) {
		drainex->r_hi--;
		if (drainex->r_hi == 0) {
			hashmap_remove(&g_commitdrain_hash, drainex);
			free(drainex);
		} else
			goto out;
	}

	if (g_rev_commitdone == revlo - 1) {
		g_rev_commitdone = revhi;

		while (true) {
			key.r_lo = revhi + 1;
			hashmap_entry_init(&key.r_entry,
				memhash(&key.r_lo, sizeof(key.r_lo)));

			exist = hashmap_remove(&g_commitdone_hash, &key);
			if (!exist)
				break;

			g_rev_commitdone = revhi = exist->r_hi;
			free(exist);
		}

		cond_broadcast(&g_commitdone_cond);
	} else {
		done->r_lo = revlo;
		done->r_hi = revhi;
		hashmap_entry_init(&done->r_entry,
			memhash(&done->r_lo, sizeof(done->r_lo)));
		hashmap_add(&g_commitdone_hash, done);
		done = NULL;
	}

out:
	isvn_g_unlock();

	if (done)
		free(done);
}
Beispiel #24
0
/*
 * Read stdin line by line and print result of commands to stdout:
 *
 * hash key -> strhash(key) memhash(key) strihash(key) memihash(key)
 * put key value -> NULL / old value
 * get key -> NULL / value
 * remove key -> NULL / old value
 * iterate -> key1 value1\nkey2 value2\n...
 * size -> tablesize numentries
 *
 * perfhashmap method rounds -> test hashmap.[ch] performance
 */
int main(int argc, char *argv[])
{
	char line[1024];
	struct hashmap map;
	int icase;

	/* init hash map */
	icase = argc > 1 && !strcmp("ignorecase", argv[1]);
	hashmap_init(&map, (hashmap_cmp_fn) (icase ? test_entry_cmp_icase
			: test_entry_cmp), 0);

	/* process commands from stdin */
	while (fgets(line, sizeof(line), stdin)) {
		char *cmd, *p1 = NULL, *p2 = NULL;
		int l1 = 0, l2 = 0, hash = 0;
		struct test_entry *entry;

		/* break line into command and up to two parameters */
		cmd = strtok(line, DELIM);
		/* ignore empty lines */
		if (!cmd || *cmd == '#')
			continue;

		p1 = strtok(NULL, DELIM);
		if (p1) {
			l1 = strlen(p1);
			hash = icase ? strihash(p1) : strhash(p1);
			p2 = strtok(NULL, DELIM);
			if (p2)
				l2 = strlen(p2);
		}

		if (!strcmp("hash", cmd) && l1) {

			/* print results of different hash functions */
			printf("%u %u %u %u\n", strhash(p1), memhash(p1, l1),
					strihash(p1), memihash(p1, l1));

		} else if (!strcmp("add", cmd) && l1 && l2) {

			/* create entry with key = p1, value = p2 */
			entry = alloc_test_entry(hash, p1, l1, p2, l2);

			/* add to hashmap */
			hashmap_add(&map, entry);

		} else if (!strcmp("put", cmd) && l1 && l2) {

			/* create entry with key = p1, value = p2 */
			entry = alloc_test_entry(hash, p1, l1, p2, l2);

			/* add / replace entry */
			entry = hashmap_put(&map, entry);

			/* print and free replaced entry, if any */
			puts(entry ? get_value(entry) : "NULL");
			free(entry);

		} else if (!strcmp("get", cmd) && l1) {

			/* lookup entry in hashmap */
			entry = hashmap_get_from_hash(&map, hash, p1);

			/* print result */
			if (!entry)
				puts("NULL");
			while (entry) {
				puts(get_value(entry));
				entry = hashmap_get_next(&map, entry);
			}

		} else if (!strcmp("remove", cmd) && l1) {

			/* setup static key */
			struct hashmap_entry key;
			hashmap_entry_init(&key, hash);

			/* remove entry from hashmap */
			entry = hashmap_remove(&map, &key, p1);

			/* print result and free entry*/
			puts(entry ? get_value(entry) : "NULL");
			free(entry);

		} else if (!strcmp("iterate", cmd)) {

			struct hashmap_iter iter;
			hashmap_iter_init(&map, &iter);
			while ((entry = hashmap_iter_next(&iter)))
				printf("%s %s\n", entry->key, get_value(entry));

		} else if (!strcmp("size", cmd)) {

			/* print table sizes */
			printf("%u %u\n", map.tablesize, map.size);

		} else if (!strcmp("intern", cmd) && l1) {

			/* test that strintern works */
			const char *i1 = strintern(p1);
			const char *i2 = strintern(p1);
			if (strcmp(i1, p1))
				printf("strintern(%s) returns %s\n", p1, i1);
			else if (i1 == p1)
				printf("strintern(%s) returns input pointer\n", p1);
			else if (i1 != i2)
				printf("strintern(%s) != strintern(%s)", i1, i2);
			else
				printf("%s\n", i1);

		} else if (!strcmp("perfhashmap", cmd) && l1 && l2) {

			perf_hashmap(atoi(p1), atoi(p2));

		} else {

			printf("Unknown command %s\n", cmd);

		}
	}

	hashmap_free(&map, 1);
	return 0;
}
Beispiel #25
0
/*
 * Looks up or creates a cache entry for the specified key.
 */
static struct fsentry *fscache_get(struct fsentry *key)
{
	struct fsentry *fse, *future, *waiter;
	int dir_not_found;

	EnterCriticalSection(&mutex);
	/* check if entry is in cache */
	fse = fscache_get_wait(key);
	if (fse) {
		if (fse->st_mode)
			fsentry_addref(fse);
		else
			fse = NULL; /* non-existing directory */
		LeaveCriticalSection(&mutex);
		return fse;
	}
	/* if looking for a file, check if directory listing is in cache */
	if (!fse && key->list) {
		fse = fscache_get_wait(key->list);
		if (fse) {
			LeaveCriticalSection(&mutex);
			/*
			 * dir entry without file entry, or dir does not
			 * exist -> file doesn't exist
			 */
			errno = ENOENT;
			return NULL;
		}
	}

	/* add future entry to indicate that we're loading it */
	future = key->list ? key->list : key;
	future->next = NULL;
	future->refcnt = 0;
	hashmap_add(&map, future);

	/* create the directory listing (outside mutex!) */
	LeaveCriticalSection(&mutex);
	fse = fsentry_create_list(future, &dir_not_found);
	EnterCriticalSection(&mutex);

	/* remove future entry and signal waiting threads */
	hashmap_remove(&map, future, NULL);
	waiter = future->next;
	while (waiter) {
		HANDLE h = waiter->hwait;
		waiter = waiter->next;
		SetEvent(h);
	}

	/* leave on error (errno set by fsentry_create_list) */
	if (!fse) {
		if (dir_not_found && key->list) {
			/*
			 * Record that the directory does not exist (or is
			 * empty, which for all practical matters is the same
			 * thing as far as fscache is concerned).
			 */
			fse = fsentry_alloc(key->list->list,
					    key->list->name, key->list->len);
			fse->st_mode = 0;
			hashmap_add(&map, fse);
		}
		LeaveCriticalSection(&mutex);
		return NULL;
	}

	/* add directory listing to the cache */
	fscache_add(fse);

	/* lookup file entry if requested (fse already points to directory) */
	if (key->list)
		fse = hashmap_get(&map, key, NULL);

	if (fse && !fse->st_mode)
		fse = NULL; /* non-existing directory */

	/* return entry or ENOENT */
	if (fse)
		fsentry_addref(fse);
	else
		errno = ENOENT;

	LeaveCriticalSection(&mutex);
	return fse;
}
Beispiel #26
0
static void testmap(unsigned n, unsigned m, unsigned of, unsigned fp) {
	unsigned *knownkeys = malloc(sizeof (unsigned) * (m + of));
	unsigned *mapkeys = malloc(sizeof (unsigned) * (m + of));
	char *mapvals = malloc(sizeof (char *) * (m + of));
	unsigned i, j, k;
	int err;

	memset(knownkeys, 0, sizeof (unsigned) * (m + of));
	memset(mapkeys, 0, sizeof (unsigned) * (m + of));
	memset(mapvals, 0, sizeof (char *) * (m + of));

	timebase_init(&timebase);

	printf("adding %d\n", n);
	tacc = 0;
	tcnt = 0;
	for (i = 0; i < n + of; ++i) {
add_again:
		k = rand() % 0xffff;

		for (j = 0; j < i; ++j)
			if (k == knownkeys[j])
				goto add_again;

		knownkeys[i] = k;

		tick = timebase_count();
		if ((err = hashmap_add(mapkeys, m, k)) < 0) {
			fprintf(stderr, "hashmap_add failed: i=%d/%d k=%04x\n", i, n, k);
			exit(1);
		}
		tock = timebase_count();
		tacc += tock - tick;
		++tcnt;
	}
	printf(" => %lums [%lu]\n", timebase_msec(&timebase, tacc), tcnt);

	printf("finding %d\n", n);
	tacc = 0;
	tcnt = 0;
	for (i = 0; i < n; ++i) {
		k = knownkeys[i];

		tick = timebase_count();
		if (hashmap_find(mapkeys, m, k) < 0) {
			fprintf(stderr, "hashmap_find failed: i=%d/%d k=%04x\n", i, n, k);
			exit(1);
		}
		tock = timebase_count();
		tacc += tock - tick;
		++tcnt;
	}
	printf(" => %lums [%lu]\n", timebase_msec(&timebase, tacc), tcnt);

	printf("finding %d invalid\n", fp);
	tacc = 0;
	tcnt = 0;
	k = 0x1337;
	for (i = 0; i < fp; ++i) {
fp_again:
		k = ((k + 0x5125) ^ 0x3851) & 0xffff;

		for (j = 0; j < n; ++j)
			if (k == knownkeys[j])
				goto fp_again;

		tick = timebase_count();
		if (hashmap_find(mapkeys, m, k) >= 0) {
			fprintf(stderr, "hashmap_find false positive: i=%d/%d k=%04x\n", i, n, k);
			exit(1);
		}
		tock = timebase_count();
		tacc += tock - tick;
		++tcnt;
	}
	printf(" => %lums [%lu]\n", timebase_msec(&timebase, tacc), tcnt);

	printf("removing %d + verifying\n", n);
	tacc = 0;
	tcnt = 0;
	for (i = 0; i < n; ++i) {
		for (j = i; j < n; ++j) {
			k = knownkeys[j];

			if (hashmap_find(mapkeys, m, k) < 0) {
				fprintf(stderr, "hashmap_find failed during removal: j=%d/%d k=%04x\n", j, n, k);
				exit(1);
			}
		}

		k = knownkeys[i];

		tick = timebase_count();
		if (hashmap_remove(mapkeys, m, k) < 0) {
			fprintf(stderr, "hashmap_find failed: i=%d/%d k=%04x\n", i, n, k);
			exit(1);
		}
		tock = timebase_count();
		tacc += tock - tick;
		++tcnt;
	}
	printf(" => %lums [%lu]\n", timebase_msec(&timebase, tacc), tcnt);

	free(knownkeys);
	free(mapkeys);
	free(mapvals);

	printf("OK\n");
}
Beispiel #27
0
static int run_dir_diff(const char *extcmd, int symlinks, const char *prefix,
			int argc, const char **argv)
{
	char tmpdir[PATH_MAX];
	struct strbuf info = STRBUF_INIT, lpath = STRBUF_INIT;
	struct strbuf rpath = STRBUF_INIT, buf = STRBUF_INIT;
	struct strbuf ldir = STRBUF_INIT, rdir = STRBUF_INIT;
	struct strbuf wtdir = STRBUF_INIT;
	char *lbase_dir, *rbase_dir;
	size_t ldir_len, rdir_len, wtdir_len;
	const char *workdir, *tmp;
	int ret = 0, i;
	FILE *fp;
	struct hashmap working_tree_dups, submodules, symlinks2;
	struct hashmap_iter iter;
	struct pair_entry *entry;
	struct index_state wtindex;
	struct checkout lstate, rstate;
	int rc, flags = RUN_GIT_CMD, err = 0;
	struct child_process child = CHILD_PROCESS_INIT;
	const char *helper_argv[] = { "difftool--helper", NULL, NULL, NULL };
	struct hashmap wt_modified, tmp_modified;
	int indices_loaded = 0;

	workdir = get_git_work_tree();

	/* Setup temp directories */
	tmp = getenv("TMPDIR");
	xsnprintf(tmpdir, sizeof(tmpdir), "%s/git-difftool.XXXXXX", tmp ? tmp : "/tmp");
	if (!mkdtemp(tmpdir))
		return error("could not create '%s'", tmpdir);
	strbuf_addf(&ldir, "%s/left/", tmpdir);
	strbuf_addf(&rdir, "%s/right/", tmpdir);
	strbuf_addstr(&wtdir, workdir);
	if (!wtdir.len || !is_dir_sep(wtdir.buf[wtdir.len - 1]))
		strbuf_addch(&wtdir, '/');
	mkdir(ldir.buf, 0700);
	mkdir(rdir.buf, 0700);

	memset(&wtindex, 0, sizeof(wtindex));

	memset(&lstate, 0, sizeof(lstate));
	lstate.base_dir = lbase_dir = xstrdup(ldir.buf);
	lstate.base_dir_len = ldir.len;
	lstate.force = 1;
	memset(&rstate, 0, sizeof(rstate));
	rstate.base_dir = rbase_dir = xstrdup(rdir.buf);
	rstate.base_dir_len = rdir.len;
	rstate.force = 1;

	ldir_len = ldir.len;
	rdir_len = rdir.len;
	wtdir_len = wtdir.len;

	hashmap_init(&working_tree_dups,
		     (hashmap_cmp_fn)working_tree_entry_cmp, NULL, 0);
	hashmap_init(&submodules, (hashmap_cmp_fn)pair_cmp, NULL, 0);
	hashmap_init(&symlinks2, (hashmap_cmp_fn)pair_cmp, NULL, 0);

	child.no_stdin = 1;
	child.git_cmd = 1;
	child.use_shell = 0;
	child.clean_on_exit = 1;
	child.dir = prefix;
	child.out = -1;
	argv_array_pushl(&child.args, "diff", "--raw", "--no-abbrev", "-z",
			 NULL);
	for (i = 0; i < argc; i++)
		argv_array_push(&child.args, argv[i]);
	if (start_command(&child))
		die("could not obtain raw diff");
	fp = xfdopen(child.out, "r");

	/* Build index info for left and right sides of the diff */
	i = 0;
	while (!strbuf_getline_nul(&info, fp)) {
		int lmode, rmode;
		struct object_id loid, roid;
		char status;
		const char *src_path, *dst_path;

		if (starts_with(info.buf, "::"))
			die(N_("combined diff formats('-c' and '--cc') are "
			       "not supported in\n"
			       "directory diff mode('-d' and '--dir-diff')."));

		if (parse_index_info(info.buf, &lmode, &rmode, &loid, &roid,
				     &status))
			break;
		if (strbuf_getline_nul(&lpath, fp))
			break;
		src_path = lpath.buf;

		i++;
		if (status != 'C' && status != 'R') {
			dst_path = src_path;
		} else {
			if (strbuf_getline_nul(&rpath, fp))
				break;
			dst_path = rpath.buf;
		}

		if (S_ISGITLINK(lmode) || S_ISGITLINK(rmode)) {
			strbuf_reset(&buf);
			strbuf_addf(&buf, "Subproject commit %s",
				    oid_to_hex(&loid));
			add_left_or_right(&submodules, src_path, buf.buf, 0);
			strbuf_reset(&buf);
			strbuf_addf(&buf, "Subproject commit %s",
				    oid_to_hex(&roid));
			if (!oidcmp(&loid, &roid))
				strbuf_addstr(&buf, "-dirty");
			add_left_or_right(&submodules, dst_path, buf.buf, 1);
			continue;
		}

		if (S_ISLNK(lmode)) {
			char *content = get_symlink(&loid, src_path);
			add_left_or_right(&symlinks2, src_path, content, 0);
			free(content);
		}

		if (S_ISLNK(rmode)) {
			char *content = get_symlink(&roid, dst_path);
			add_left_or_right(&symlinks2, dst_path, content, 1);
			free(content);
		}

		if (lmode && status != 'C') {
			if (checkout_path(lmode, &loid, src_path, &lstate)) {
				ret = error("could not write '%s'", src_path);
				goto finish;
			}
		}

		if (rmode && !S_ISLNK(rmode)) {
			struct working_tree_entry *entry;

			/* Avoid duplicate working_tree entries */
			FLEX_ALLOC_STR(entry, path, dst_path);
			hashmap_entry_init(entry, strhash(dst_path));
			if (hashmap_get(&working_tree_dups, entry, NULL)) {
				free(entry);
				continue;
			}
			hashmap_add(&working_tree_dups, entry);

			if (!use_wt_file(workdir, dst_path, &roid)) {
				if (checkout_path(rmode, &roid, dst_path,
						  &rstate)) {
					ret = error("could not write '%s'",
						    dst_path);
					goto finish;
				}
			} else if (!is_null_oid(&roid)) {
				/*
				 * Changes in the working tree need special
				 * treatment since they are not part of the
				 * index.
				 */
				struct cache_entry *ce2 =
					make_cache_entry(rmode, roid.hash,
							 dst_path, 0, 0);

				add_index_entry(&wtindex, ce2,
						ADD_CACHE_JUST_APPEND);

				add_path(&rdir, rdir_len, dst_path);
				if (ensure_leading_directories(rdir.buf)) {
					ret = error("could not create "
						    "directory for '%s'",
						    dst_path);
					goto finish;
				}
				add_path(&wtdir, wtdir_len, dst_path);
				if (symlinks) {
					if (symlink(wtdir.buf, rdir.buf)) {
						ret = error_errno("could not symlink '%s' to '%s'", wtdir.buf, rdir.buf);
						goto finish;
					}
				} else {
					struct stat st;
					if (stat(wtdir.buf, &st))
						st.st_mode = 0644;
					if (copy_file(rdir.buf, wtdir.buf,
						      st.st_mode)) {
						ret = error("could not copy '%s' to '%s'", wtdir.buf, rdir.buf);
						goto finish;
					}
				}
			}
		}
	}

	fclose(fp);
	fp = NULL;
	if (finish_command(&child)) {
		ret = error("error occurred running diff --raw");
		goto finish;
	}

	if (!i)
		goto finish;

	/*
	 * Changes to submodules require special treatment.This loop writes a
	 * temporary file to both the left and right directories to show the
	 * change in the recorded SHA1 for the submodule.
	 */
	hashmap_iter_init(&submodules, &iter);
	while ((entry = hashmap_iter_next(&iter))) {
		if (*entry->left) {
			add_path(&ldir, ldir_len, entry->path);
			ensure_leading_directories(ldir.buf);
			write_file(ldir.buf, "%s", entry->left);
		}
		if (*entry->right) {
			add_path(&rdir, rdir_len, entry->path);
			ensure_leading_directories(rdir.buf);
			write_file(rdir.buf, "%s", entry->right);
		}
	}

	/*
	 * Symbolic links require special treatment.The standard "git diff"
	 * shows only the link itself, not the contents of the link target.
	 * This loop replicates that behavior.
	 */
	hashmap_iter_init(&symlinks2, &iter);
	while ((entry = hashmap_iter_next(&iter))) {
		if (*entry->left) {
			add_path(&ldir, ldir_len, entry->path);
			ensure_leading_directories(ldir.buf);
			write_file(ldir.buf, "%s", entry->left);
		}
		if (*entry->right) {
			add_path(&rdir, rdir_len, entry->path);
			ensure_leading_directories(rdir.buf);
			write_file(rdir.buf, "%s", entry->right);
		}
	}

	strbuf_release(&buf);

	strbuf_setlen(&ldir, ldir_len);
	helper_argv[1] = ldir.buf;
	strbuf_setlen(&rdir, rdir_len);
	helper_argv[2] = rdir.buf;

	if (extcmd) {
		helper_argv[0] = extcmd;
		flags = 0;
	} else
		setenv("GIT_DIFFTOOL_DIRDIFF", "true", 1);
	rc = run_command_v_opt(helper_argv, flags);

	/*
	 * If the diff includes working copy files and those
	 * files were modified during the diff, then the changes
	 * should be copied back to the working tree.
	 * Do not copy back files when symlinks are used and the
	 * external tool did not replace the original link with a file.
	 *
	 * These hashes are loaded lazily since they aren't needed
	 * in the common case of --symlinks and the difftool updating
	 * files through the symlink.
	 */
	hashmap_init(&wt_modified, (hashmap_cmp_fn)path_entry_cmp,
		     NULL, wtindex.cache_nr);
	hashmap_init(&tmp_modified, (hashmap_cmp_fn)path_entry_cmp,
		     NULL, wtindex.cache_nr);

	for (i = 0; i < wtindex.cache_nr; i++) {
		struct hashmap_entry dummy;
		const char *name = wtindex.cache[i]->name;
		struct stat st;

		add_path(&rdir, rdir_len, name);
		if (lstat(rdir.buf, &st))
			continue;

		if ((symlinks && S_ISLNK(st.st_mode)) || !S_ISREG(st.st_mode))
			continue;

		if (!indices_loaded) {
			static struct lock_file lock;
			strbuf_reset(&buf);
			strbuf_addf(&buf, "%s/wtindex", tmpdir);
			if (hold_lock_file_for_update(&lock, buf.buf, 0) < 0 ||
			    write_locked_index(&wtindex, &lock, COMMIT_LOCK)) {
				ret = error("could not write %s", buf.buf);
				rollback_lock_file(&lock);
				goto finish;
			}
			changed_files(&wt_modified, buf.buf, workdir);
			strbuf_setlen(&rdir, rdir_len);
			changed_files(&tmp_modified, buf.buf, rdir.buf);
			add_path(&rdir, rdir_len, name);
			indices_loaded = 1;
		}

		hashmap_entry_init(&dummy, strhash(name));
		if (hashmap_get(&tmp_modified, &dummy, name)) {
			add_path(&wtdir, wtdir_len, name);
			if (hashmap_get(&wt_modified, &dummy, name)) {
				warning(_("both files modified: '%s' and '%s'."),
					wtdir.buf, rdir.buf);
				warning(_("working tree file has been left."));
				warning("%s", "");
				err = 1;
			} else if (unlink(wtdir.buf) ||
				   copy_file(wtdir.buf, rdir.buf, st.st_mode))
				warning_errno(_("could not copy '%s' to '%s'"),
					      rdir.buf, wtdir.buf);
		}
	}

	if (err) {
		warning(_("temporary files exist in '%s'."), tmpdir);
		warning(_("you may want to cleanup or recover these."));
		exit(1);
	} else
		exit_cleanup(tmpdir, rc);

finish:
	if (fp)
		fclose(fp);

	free(lbase_dir);
	free(rbase_dir);
	strbuf_release(&ldir);
	strbuf_release(&rdir);
	strbuf_release(&wtdir);
	strbuf_release(&buf);

	return ret;
}
Beispiel #28
0
/*
 * Looks up or creates a cache entry for the specified key.
 */
static struct fsentry *fscache_get(struct fsentry *key)
{
	struct fsentry *fse, *future, *waiter;

	EnterCriticalSection(&mutex);
	/* check if entry is in cache */
	fse = fscache_get_wait(key);
	if (fse) {
		fsentry_addref(fse);
		LeaveCriticalSection(&mutex);
		return fse;
	}
	/* if looking for a file, check if directory listing is in cache */
	if (!fse && key->list) {
		fse = fscache_get_wait(key->list);
		if (fse) {
			LeaveCriticalSection(&mutex);
			/* dir entry without file entry -> file doesn't exist */
			errno = ENOENT;
			return NULL;
		}
	}

	/* add future entry to indicate that we're loading it */
	future = key->list ? key->list : key;
	future->next = NULL;
	future->refcnt = 0;
	hashmap_add(&map, future);

	/* create the directory listing (outside mutex!) */
	LeaveCriticalSection(&mutex);
	fse = fsentry_create_list(future);
	EnterCriticalSection(&mutex);

	/* remove future entry and signal waiting threads */
	hashmap_remove(&map, future, NULL);
	waiter = future->next;
	while (waiter) {
		HANDLE h = waiter->hwait;
		waiter = waiter->next;
		SetEvent(h);
	}

	/* leave on error (errno set by fsentry_create_list) */
	if (!fse) {
		LeaveCriticalSection(&mutex);
		return NULL;
	}

	/* add directory listing to the cache */
	fscache_add(fse);

	/* lookup file entry if requested (fse already points to directory) */
	if (key->list)
		fse = hashmap_get(&map, key, NULL);

	/* return entry or ENOENT */
	if (fse)
		fsentry_addref(fse);
	else
		errno = ENOENT;

	LeaveCriticalSection(&mutex);
	return fse;
}