示例#1
0
/**
 * Turn LRU deferred writes on or off.
 * @return -1 on error with errno set, 0 if OK.
 */
int
setwdelay(DBM *db, bool on)
{
	struct lru_cache *cache = db->cache;

	if (NULL == cache)
		return init_cache(db, LRU_PAGES, on);

	sdbm_lru_check(cache);

	if (on == cache->write_deferred)
		return 0;

	/*
	 * Value is inverted.
	 */

	if (cache->write_deferred) {
		flush_dirtypag(db);
		cache->write_deferred = FALSE;
	} else {
		cache->write_deferred = TRUE;
	}

	return 0;
}
示例#2
0
/**
 * Close the LRU page cache.
 */
void lru_close(DBM *db)
{
	struct lru_cache *cache = db->cache;

	if (cache) {
		if (!db->is_volatile)
			flush_dirtypag(db);

		if (common_stats)
			log_lrustats(db);

		free_cache(cache);
		WFREE(cache);
	}

	db->cache = NULL;
}
示例#3
0
文件: lru.c 项目: MrJoe/gtk-gnutella
/**
 * Close the LRU page cache.
 */
void
lru_close(DBM *db)
{
	struct lru_cache *cache = db->cache;

	if (cache) {
		sdbm_lru_check(cache);

		if (!db->is_volatile && !(db->flags & DBM_BROKEN))
			flush_dirtypag(db);

		if (common_stats)
			log_lrustats(db);

		free_cache(cache);
		cache->magic = 0;
		WFREE(cache);
	}

	db->cache = NULL;
}
示例#4
0
/**
 * Set the page cache size.
 * @return 0 if OK, -1 on failure with errno set.
 */
int
setcache(DBM *db, long pages)
{
	struct lru_cache *cache = db->cache;
	bool wdelay;

	sdbm_lru_check(cache);

	if (pages <= 0) {
		errno = EINVAL;
		return -1;
	}

	if (NULL == cache)
		return init_cache(db, pages, FALSE);

	/*
	 * Easiest case: the size identical.
	 */

	if (pages == cache->pages)
		return 0;

	/*
	 * Cache size is changed.
	 *
	 * This means the arena will be reallocated, so we must invalidate the
	 * current db->pagbuf pointer, which lies within the old arena.  It is
	 * sufficient to reset db->pagbno, forcing a reload from the upper layers.
	 * Note than when the cache size is enlarged, the old page is still cached
	 * so reloading will be just a matter of recomputing db->pagbuf.  We could
	 * do so here, but cache size changes should only be infrequent.
	 *
	 * We also reset all the cache statistics, since a different cache size
	 * will imply a different set of hit/miss ratio.
	 */

	db->pagbno = -1;		/* Current page address will become invalid */
	db->pagbuf = NULL;

	if (common_stats) {
		s_info("sdbm: \"%s\" LRU cache size %s from %ld page%s to %ld",
			sdbm_name(db), pages > cache->pages ? "increased" : "decreased",
			cache->pages, plural(cache->pages), pages);
		log_lrustats(db);
	}

	cache->rhits = cache->rmisses = 0;
	cache->whits = cache->wmisses = 0;

	/*
	 * Straightforward: the size is increased.
	 */

	if (pages > cache->pages) {
		char *new_arena = vmm_alloc(pages * DBM_PBLKSIZ);
		if (NULL == new_arena)
			return -1;
		memmove(new_arena, cache->arena, cache->pages * DBM_PBLKSIZ);
		vmm_free(cache->arena, cache->pages * DBM_PBLKSIZ);
		cache->arena = new_arena;
		cache->dirty = wrealloc(cache->dirty, cache->pages, pages);
		cache->numpag = wrealloc(cache->numpag,
			cache->pages * sizeof(long), pages * sizeof(long));
		cache->pages = pages;
		return 0;
	}

	/*
	 * Difficult: the size is decreased.
	 *
	 * The current page buffer could point in a cache area that is going
	 * to disappear, and the internal data structures must forget about
	 * all the old indices that are greater than the new limit.
	 *
	 * We do not try to optimize anything here, as this call should happen
	 * only infrequently: we flush the current cache (in case there are
	 * deferred writes), destroy the LRU cache data structures, recreate a
	 * new one and invalidate the current DB page.
	 */

	wdelay = cache->write_deferred;
	flush_dirtypag(db);
	free_cache(cache);
	return setup_cache(cache, pages, wdelay);
}