summaryrefslogtreecommitdiffstats
path: root/src/H5AC.c
diff options
context:
space:
mode:
authorQuincey Koziol <koziol@hdfgroup.org>2000-06-01 23:45:11 (GMT)
committerQuincey Koziol <koziol@hdfgroup.org>2000-06-01 23:45:11 (GMT)
commitae69e30f76aff9cee3a948d38505fdb33d63a242 (patch)
tree16c9fe3d9ecf886d619e6d91b38a9593cd3ec85b /src/H5AC.c
parentecb52e75d3394f8f373ae37ff2487228997b43a4 (diff)
downloadhdf5-ae69e30f76aff9cee3a948d38505fdb33d63a242.zip
hdf5-ae69e30f76aff9cee3a948d38505fdb33d63a242.tar.gz
hdf5-ae69e30f76aff9cee3a948d38505fdb33d63a242.tar.bz2
[svn-r2318] Rearranged metadata caching to put caching information in the objects being
cached instead of in separate structures. This reduces the amount of memory the hash table uses by about half. This is the initial step along the path of speeding up the metadata caching.
Diffstat (limited to 'src/H5AC.c')
-rw-r--r--src/H5AC.c271
1 files changed, 149 insertions, 122 deletions
diff --git a/src/H5AC.c b/src/H5AC.c
index dbe8ab1..722b709 100644
--- a/src/H5AC.c
+++ b/src/H5AC.c
@@ -80,12 +80,18 @@ H5AC_create(H5F_t *f, intn size_hint)
"memory allocation failed");
}
cache->nslots = size_hint;
- cache->slot = H5MM_calloc(cache->nslots*sizeof(H5AC_slot_t));
+ cache->slot = H5MM_calloc(cache->nslots*sizeof(H5AC_info_t *));
if (NULL==cache->slot) {
- f->shared->cache = H5MM_xfree (f->shared->cache);
- HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL,
- "memory allocation failed");
+ f->shared->cache = H5MM_xfree (f->shared->cache);
+ HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
}
+#ifdef H5AC_DEBUG
+ if ((cache->prot = H5MM_calloc(cache->nslots*sizeof(H5AC_prot_t)))==NULL) {
+ cache->slot = H5MM_xfree (cache->slot);
+ f->shared->cache = H5MM_xfree (f->shared->cache);
+ HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
+ }
+#endif /* H5AC_DEBUG */
FUNC_LEAVE(size_hint);
}
@@ -125,10 +131,11 @@ H5AC_dest(H5F_t *f)
{
uintn i;
for (i=0; i<cache->nslots; i++) {
- cache->slot[i].prot = H5MM_xfree(cache->slot[i].prot);
- cache->slot[i].aprots = 0;
- cache->slot[i].nprots = 0;
+ cache->prot[i].slot = H5MM_xfree(cache->prot[i].slot);
+ cache->prot[i].aprots = 0;
+ cache->prot[i].nprots = 0;
}
+ cache->prot = H5MM_xfree(cache->prot);
}
#endif
@@ -190,8 +197,8 @@ H5AC_find_f(H5F_t *f, const H5AC_class_t *type, haddr_t addr,
unsigned idx;
herr_t status;
void *thing = NULL;
- herr_t (*flush) (H5F_t *, hbool_t, haddr_t, void*) = NULL;
- H5AC_slot_t *slot = NULL;
+ H5AC_flush_func_t flush;
+ H5AC_info_t **info = NULL;
H5AC_t *cache = NULL;
FUNC_ENTER(H5AC_find, NULL);
@@ -204,14 +211,14 @@ H5AC_find_f(H5F_t *f, const H5AC_class_t *type, haddr_t addr,
assert(H5F_addr_defined(addr));
idx = H5AC_HASH(f, addr);
cache = f->shared->cache;
- slot = cache->slot + idx;
+ info = cache->slot + idx;
/*
* Return right away if the item is in the cache.
*/
- if (slot->type == type && H5F_addr_eq(slot->addr, addr)) {
+ if ((*info) && (*info)->type == type && H5F_addr_eq((*info)->addr, addr)) {
cache->diagnostics[type->id].nhits++;
- HRETURN(slot->thing);
+ HRETURN(*info);
}
cache->diagnostics[type->id].nmisses++;
@@ -219,7 +226,7 @@ H5AC_find_f(H5F_t *f, const H5AC_class_t *type, haddr_t addr,
* Fail if the item in the cache is at the correct address but is
* of the wrong type.
*/
- if (slot->type && slot->type != type && H5F_addr_eq(slot->addr, addr)) {
+ if ((*info) && (*info)->type && (*info)->type != type && H5F_addr_eq((*info)->addr, addr)) {
HRETURN_ERROR(H5E_CACHE, H5E_BADTYPE, NULL,
"internal error (correct address, wrong type)");
}
@@ -230,12 +237,15 @@ H5AC_find_f(H5F_t *f, const H5AC_class_t *type, haddr_t addr,
* H5AC_protect() function.
*/
{
+ H5AC_prot_t *prot = NULL;
intn i;
- for (i = 0; i < slot->nprots; i++) {
- assert(H5F_addr_ne(addr, slot->prot[i].addr));
+
+ prot = cache->prot + idx;
+ for (i = 0; i < prot->nprots; i++) {
+ assert(H5F_addr_ne(addr, prot->slot[i]->addr));
}
}
-#endif
+#endif /* H5AC_DEBUG */
/*
* Load a new thing. If it can't be loaded, then return an error
@@ -247,9 +257,9 @@ H5AC_find_f(H5F_t *f, const H5AC_class_t *type, haddr_t addr,
/*
* Free the previous cache entry if there is one.
*/
- if (slot->type) {
- flush = slot->type->flush;
- status = (flush)(f, TRUE, slot->addr, slot->thing);
+ if (*info) {
+ flush = (*info)->type->flush;
+ status = (flush)(f, TRUE, (*info)->addr, (*info));
if (status < 0) {
/*
* The old thing could not be removed from the stack.
@@ -262,14 +272,14 @@ H5AC_find_f(H5F_t *f, const H5AC_class_t *type, haddr_t addr,
HRETURN_ERROR(H5E_CACHE, H5E_CANTFLUSH, NULL,
"unable to flush existing cached object");
}
- cache->diagnostics[slot->type->id].nflushes++;
+ cache->diagnostics[(*info)->type->id].nflushes++;
}
/*
* Make the cache point to the new thing.
*/
- slot->type = type;
- slot->addr = addr;
- slot->thing = thing;
+ (*info)=thing;
+ (*info)->type = type;
+ (*info)->addr = addr;
FUNC_LEAVE(thing);
}
@@ -301,17 +311,17 @@ H5AC_compare(const void *_a, const void *_b)
assert(current_cache_g);
- if (NULL == current_cache_g->slot[a].type) {
- if (NULL == current_cache_g->slot[b].type) {
+ if (NULL == current_cache_g->slot[a]->type) {
+ if (NULL == current_cache_g->slot[b]->type) {
return 0;
} else {
return -1;
}
- } else if (NULL == current_cache_g->slot[b].type) {
+ } else if (NULL == current_cache_g->slot[b]->type) {
return 1;
- } else if (current_cache_g->slot[a].addr < current_cache_g->slot[b].addr) {
+ } else if (current_cache_g->slot[a]->addr < current_cache_g->slot[b]->addr) {
return -1;
- } else if (current_cache_g->slot[a].addr > current_cache_g->slot[b].addr) {
+ } else if (current_cache_g->slot[a]->addr > current_cache_g->slot[b]->addr) {
return 1;
}
return 0;
@@ -349,8 +359,8 @@ H5AC_flush(H5F_t *f, const H5AC_class_t *type, haddr_t addr, hbool_t destroy)
{
uintn i;
herr_t status;
- herr_t (*flush)(H5F_t *, hbool_t, haddr_t, void*) = NULL;
- H5AC_slot_t *slot;
+ H5AC_flush_func_t flush=NULL;
+ H5AC_info_t **info;
intn *map = NULL;
uintn nslots;
H5AC_t *cache = NULL;
@@ -373,7 +383,7 @@ H5AC_flush(H5F_t *f, const H5AC_class_t *type, haddr_t addr, hbool_t destroy)
"memory allocation failed");
}
for (i = nslots = 0; i < cache->nslots; i++) {
- if (cache->slot[i].type)
+ if (cache->slot[i]!=NULL)
map[nslots++] = i;
}
assert(NULL == current_cache_g);
@@ -382,7 +392,7 @@ H5AC_flush(H5F_t *f, const H5AC_class_t *type, haddr_t addr, hbool_t destroy)
current_cache_g = NULL;
#ifdef NDEBUG
for (i = 1; i < nslots; i++) {
- assert(H5F_addr_lt(cache->slot[i - 1].addr, cache->slot[i].addr));
+ assert(H5F_addr_lt(cache->slot[i - 1]->addr, cache->slot[i]->addr));
}
#endif
#else
@@ -394,23 +404,25 @@ H5AC_flush(H5F_t *f, const H5AC_class_t *type, haddr_t addr, hbool_t destroy)
*/
for (i = 0; i < nslots; i++) {
#ifdef H5AC_SORT_BY_ADDR
- slot = cache->slot + map[i];
- if (NULL == slot->type) break; /*the rest are empty */
+ info = cache->slot + map[i];
+ if (NULL == (*info))
+ break; /*the rest are empty */
#else
- slot = cache->slot + i;
- if (NULL == slot->type) continue;
+ info = cache->slot + i;
+ if (NULL == (*info))
+ continue;
#endif
- if (!type || type == slot->type) {
- flush = slot->type->flush;
- status = (flush)(f, destroy, slot->addr, slot->thing);
+ if ((*info) || type == (*info)->type) {
+ flush = (*info)->type->flush;
+ status = (flush)(f, destroy, (*info)->addr, (*info));
if (status < 0) {
map = H5MM_xfree(map);
HRETURN_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL,
"unable to flush cache");
}
- cache->diagnostics[slot->type->id].nflushes++;
+ cache->diagnostics[(*info)->type->id].nflushes++;
if (destroy)
- slot->type = NULL;
+ (*info)= NULL;
}
}
map = H5MM_xfree(map);
@@ -425,21 +437,21 @@ H5AC_flush(H5F_t *f, const H5AC_class_t *type, haddr_t addr, hbool_t destroy)
}
} else {
i = H5AC_HASH(f, addr);
- if ((!type || cache->slot[i].type == type) &&
- H5F_addr_eq(cache->slot[i].addr, addr)) {
+ if (cache->slot[i] && (!type || cache->slot[i]->type == type) &&
+ H5F_addr_eq(cache->slot[i]->addr, addr)) {
/*
* Flush just this entry.
*/
- flush = cache->slot[i].type->flush;
- status = (flush)(f, destroy, cache->slot[i].addr,
- cache->slot[i].thing);
+ flush = cache->slot[i]->type->flush;
+ status = (flush)(f, destroy, cache->slot[i]->addr,
+ cache->slot[i]);
if (status < 0) {
HRETURN_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL,
"unable to flush object");
}
- cache->diagnostics[cache->slot[i].type->id].nflushes++;
+ cache->diagnostics[cache->slot[i]->type->id].nflushes++;
if (destroy)
- cache->slot[i].type = NULL;
+ cache->slot[i]= NULL;
}
}
@@ -472,8 +484,8 @@ H5AC_set(H5F_t *f, const H5AC_class_t *type, haddr_t addr, void *thing)
{
herr_t status;
uintn idx;
- herr_t (*flush)(H5F_t *, hbool_t, haddr_t, void*) = NULL;
- H5AC_slot_t *slot = NULL;
+ H5AC_flush_func_t flush=NULL;
+ H5AC_info_t **info = NULL;
H5AC_t *cache = NULL;
FUNC_ENTER(H5AC_set, FAIL);
@@ -486,30 +498,33 @@ H5AC_set(H5F_t *f, const H5AC_class_t *type, haddr_t addr, void *thing)
assert(thing);
idx = H5AC_HASH(f, addr);
cache = f->shared->cache;
- slot = cache->slot + idx;
+ info = cache->slot + idx;
#ifdef H5AC_DEBUG
{
+ H5AC_prot_t *prot = NULL;
intn i;
- for (i = 0; i < slot->nprots; i++) {
- assert(H5F_addr_ne(addr, slot->prot[i].addr));
+
+ prot = cache->prot + idx;
+ for (i = 0; i < prot->nprots; i++) {
+ assert(H5F_addr_ne(addr, prot->slot[i]->addr));
}
}
#endif
- if (slot->type) {
- flush = slot->type->flush;
- status = (flush)(f, TRUE, slot->addr, slot->thing);
+ if ((*info)) {
+ flush = (*info)->type->flush;
+ status = (flush)(f, TRUE, (*info)->addr, (*info));
if (status < 0) {
HRETURN_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL,
"unable to flush object");
}
- cache->diagnostics[slot->type->id].nflushes++;
+ cache->diagnostics[(*info)->type->id].nflushes++;
}
- slot->type = type;
- slot->addr = addr;
- slot->thing = thing;
+ (*info)=thing;
+ (*info)->type = type;
+ (*info)->addr = addr;
cache->diagnostics[type->id].ninits++;
FUNC_LEAVE(SUCCEED);
@@ -541,7 +556,7 @@ H5AC_rename(H5F_t *f, const H5AC_class_t *type, haddr_t old_addr,
haddr_t new_addr)
{
uintn old_idx, new_idx;
- herr_t (*flush)(H5F_t *, hbool_t, haddr_t, void*);
+ H5AC_flush_func_t flush=NULL;
herr_t status;
H5AC_t *cache = NULL;
@@ -556,13 +571,16 @@ H5AC_rename(H5F_t *f, const H5AC_class_t *type, haddr_t old_addr,
#ifdef H5AC_DEBUG
{
+ H5AC_prot_t *prot = NULL;
int i;
- for (i = 0; i < cache->slot[old_idx].nprots; i++) {
- assert(H5F_addr_ne(old_addr, cache->slot[old_idx].prot[i].addr));
+ prot = cache->prot + old_idx;
+ for (i = 0; i < prot->nprots; i++) {
+ assert(H5F_addr_ne(old_addr, prot->slot[i]->addr));
}
- for (i = 0; i < cache->slot[new_idx].nprots; i++) {
- assert(H5F_addr_ne(new_addr, cache->slot[new_idx].prot[i].addr));
+ prot = cache->prot + new_idx;
+ for (i = 0; i < prot->nprots; i++) {
+ assert(H5F_addr_ne(new_addr, prot->slot[i]->addr));
}
}
#endif
@@ -571,34 +589,34 @@ H5AC_rename(H5F_t *f, const H5AC_class_t *type, haddr_t old_addr,
* We don't need to do anything if the object isn't cached or if the
* new hash value is the same as the old one.
*/
- if (cache->slot[old_idx].type != type ||
- H5F_addr_ne(cache->slot[old_idx].addr, old_addr)) {
+ if (cache->slot[old_idx]->type != type ||
+ H5F_addr_ne(cache->slot[old_idx]->addr, old_addr)) {
HRETURN(SUCCEED);
}
if (old_idx == new_idx) {
- cache->slot[old_idx].addr = new_addr;
+ cache->slot[old_idx]->addr = new_addr;
HRETURN(SUCCEED);
}
/*
* Free the item from the destination cache line.
*/
- if (cache->slot[new_idx].type) {
- flush = cache->slot[new_idx].type->flush;
- status = (flush)(f, TRUE, cache->slot[new_idx].addr,
- cache->slot[new_idx].thing);
+ if (cache->slot[new_idx]) {
+ flush = cache->slot[new_idx]->type->flush;
+ status = (flush)(f, TRUE, cache->slot[new_idx]->addr,
+ cache->slot[new_idx]);
if (status < 0) {
HRETURN_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL,
"unable to flush object");
}
- cache->diagnostics[cache->slot[new_idx].type->id].nflushes++;
+ cache->diagnostics[cache->slot[new_idx]->type->id].nflushes++;
}
/*
* Move the source to the destination (it might not be cached)
*/
- cache->slot[new_idx].type = cache->slot[old_idx].type;
- cache->slot[new_idx].addr = new_addr;
- cache->slot[new_idx].thing = cache->slot[old_idx].thing;
- cache->slot[old_idx].type = NULL;
+ cache->slot[new_idx]= cache->slot[old_idx];
+ cache->slot[new_idx]->type = cache->slot[old_idx]->type;
+ cache->slot[new_idx]->addr = new_addr;
+ cache->slot[old_idx]= NULL;
FUNC_LEAVE(SUCCEED);
}
@@ -637,9 +655,11 @@ H5AC_protect(H5F_t *f, const H5AC_class_t *type, haddr_t addr,
int idx;
void *thing = NULL;
H5AC_t *cache = NULL;
- H5AC_slot_t *slot = NULL;
+ H5AC_info_t **info = NULL;
#ifdef H5AC_DEBUG
+ H5AC_prot_t *prot = NULL;
+
static int ncalls = 0;
if (0 == ncalls++) {
if (H5DEBUG(AC)) {
@@ -661,19 +681,22 @@ H5AC_protect(H5F_t *f, const H5AC_class_t *type, haddr_t addr,
assert(H5F_addr_defined(addr));
idx = H5AC_HASH(f, addr);
cache = f->shared->cache;
- slot = cache->slot + idx;
+ info = cache->slot + idx;
+#ifdef H5AC_DEBUG
+ prot = cache->prot + idx;
+#endif /* H5AC_DEBUG */
- if (slot->type == type && H5F_addr_eq(slot->addr, addr)) {
+ if ((*info) && (*info)->type == type && H5F_addr_eq((*info)->addr, addr)) {
/*
* The object is already cached; simply remove it from the cache.
*/
- cache->diagnostics[slot->type->id].nhits++;
- thing = slot->thing;
- slot->type = NULL;
- slot->addr = HADDR_UNDEF;
- slot->thing = NULL;
+ cache->diagnostics[(*info)->type->id].nhits++;
+ thing = (*info);
+ (*info)->type = NULL;
+ (*info)->addr = HADDR_UNDEF;
+ (*info)= NULL;
- } else if (slot->type && H5F_addr_eq(slot->addr, addr)) {
+ } else if ((*info) && (*info)->type && H5F_addr_eq((*info)->addr, addr)) {
/*
* Right address but wrong object type.
*/
@@ -688,10 +711,11 @@ H5AC_protect(H5F_t *f, const H5AC_class_t *type, haddr_t addr,
* H5AC_protect() function.
*/
intn i;
- for (i = 0; i < slot->nprots; i++) {
- assert(H5F_addr_ne(addr, slot->prot[i].addr));
+
+ for (i = 0; i < prot->nprots; i++) {
+ assert(H5F_addr_ne(addr, prot->slot[i]->addr));
}
-#endif
+#endif /* H5AC_DEBUG */
/*
* Load a new thing. If it can't be loaded, then return an error
@@ -709,22 +733,22 @@ H5AC_protect(H5F_t *f, const H5AC_class_t *type, haddr_t addr,
* Add the protected object to the protect debugging fields of the
* cache.
*/
- if (slot->nprots >= slot->aprots) {
- size_t na = slot->aprots + 10;
- H5AC_prot_t *x = H5MM_realloc(slot->prot,
- na * sizeof(H5AC_prot_t));
- if (NULL==x) {
- HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL,
- "memory allocation failed");
- }
- slot->aprots = (intn)na;
- slot->prot = x;
+ if (prot->nprots >= prot->aprots) {
+ size_t na = prot->aprots + 10;
+ H5AC_info_t **x = H5MM_realloc(prot->slot,
+ na * sizeof(H5AC_info_t *));
+ if (NULL==x) {
+ HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL,
+ "memory allocation failed");
+ }
+ prot->aprots = (intn)na;
+ prot->slot = x;
}
- slot->prot[slot->nprots].type = type;
- slot->prot[slot->nprots].addr = addr;
- slot->prot[slot->nprots].thing = thing;
- slot->nprots += 1;
-#endif
+ prot->slot[prot->nprots]= thing;
+ prot->slot[prot->nprots]->type = type;
+ prot->slot[prot->nprots]->addr = addr;
+ prot->nprots += 1;
+#endif /* H5AC_DEBUG */
cache->nprots += 1;
FUNC_LEAVE(thing);
@@ -758,9 +782,9 @@ H5AC_unprotect(H5F_t *f, const H5AC_class_t *type, haddr_t addr, void *thing)
{
herr_t status;
uintn idx;
- herr_t (*flush)(H5F_t*, hbool_t, haddr_t, void*) = NULL;
+ H5AC_flush_func_t flush=NULL;
H5AC_t *cache = NULL;
- H5AC_slot_t *slot = NULL;
+ H5AC_info_t **info = NULL;
FUNC_ENTER(H5AC_unprotect, FAIL);
@@ -773,21 +797,21 @@ H5AC_unprotect(H5F_t *f, const H5AC_class_t *type, haddr_t addr, void *thing)
assert(thing);
idx = H5AC_HASH(f, addr);
cache = f->shared->cache;
- slot = cache->slot + idx;
+ info = cache->slot + idx;
/*
* Flush any object already in the cache at that location. It had
* better not be another copy of the protected object.
*/
- if (slot->type) {
- assert(H5F_addr_ne(slot->addr, addr));
- flush = slot->type->flush;
- status = (flush)(f, TRUE, slot->addr, slot->thing);
+ if ((*info)) {
+ assert(H5F_addr_ne((*info)->addr, addr));
+ flush = (*info)->type->flush;
+ status = (flush)(f, TRUE, (*info)->addr, (*info));
if (status < 0) {
HRETURN_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL,
"unable to flush object");
}
- cache->diagnostics[slot->type->id].nflushes++;
+ cache->diagnostics[(*info)->type->id].nflushes++;
}
#ifdef H5AC_DEBUG
/*
@@ -795,26 +819,29 @@ H5AC_unprotect(H5F_t *f, const H5AC_class_t *type, haddr_t addr, void *thing)
* protected.
*/
{
+ H5AC_prot_t *prot = NULL;
int found, i;
- for (i = 0, found = FALSE; i < slot->nprots && !found; i++) {
- if (H5F_addr_eq(addr, slot->prot[i].addr)) {
- assert(slot->prot[i].type == type);
- HDmemmove(slot->prot + i, slot->prot + i + 1,
- ((slot->nprots - i) - 1) * sizeof(H5AC_prot_t));
- slot->nprots -= 1;
+
+ prot = cache->prot + idx;
+ for (i = 0, found = FALSE; i < prot->nprots && !found; i++) {
+ if (H5F_addr_eq(addr, prot->slot[i]->addr)) {
+ assert(prot->slot[i]->type == type);
+ HDmemmove(prot->slot + i, prot->slot + i + 1,
+ ((prot->nprots - i) - 1) * sizeof(H5AC_info_t *));
+ prot->nprots -= 1;
found = TRUE;
}
}
assert(found);
}
-#endif
+#endif /* H5AC_DEBUG */
/*
* Insert the object back into the cache; it is no longer protected.
*/
- slot->type = type;
- slot->addr = addr;
- slot->thing = thing;
+ (*info)=thing;
+ (*info)->type = type;
+ (*info)->addr = addr;
cache->nprots -= 1;
FUNC_LEAVE(SUCCEED);