hide ugly multimap code behind interface
This was SVN commit r1022.
This commit is contained in:
parent
e6324c95d6
commit
f94ecbd6d7
@ -349,11 +349,57 @@ static int free_idx(i32 idx)
|
|||||||
// speed up h_find (called every h_alloc)
|
// speed up h_find (called every h_alloc)
|
||||||
// multimap, because we want to add handles of differing type but same key
|
// multimap, because we want to add handles of differing type but same key
|
||||||
// (e.g. a VFile and Tex object for the same underlying filename hash key)
|
// (e.g. a VFile and Tex object for the same underlying filename hash key)
|
||||||
|
//
|
||||||
|
// store index because it's smaller and Handle can easily be reconstructed
|
||||||
typedef STL_HASH_MULTIMAP<uintptr_t, i32> Key2Idx;
|
typedef STL_HASH_MULTIMAP<uintptr_t, i32> Key2Idx;
|
||||||
typedef Key2Idx::iterator It;
|
typedef Key2Idx::iterator It;
|
||||||
static Key2Idx key2idx;
|
static Key2Idx key2idx;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static Handle find_key(uintptr_t key, H_Type type, bool remove = false)
|
||||||
|
{
|
||||||
|
It it = key2idx.find(key);
|
||||||
|
// not found in mapping
|
||||||
|
if(it == key2idx.end())
|
||||||
|
return -1;
|
||||||
|
It end = key2idx.upper_bound(key);
|
||||||
|
for(; it != end; ++it)
|
||||||
|
{
|
||||||
|
i32 idx = it->second;
|
||||||
|
HDATA* hd = h_data(idx);
|
||||||
|
// found match
|
||||||
|
if(hd && hd->type == type && hd->key == key)
|
||||||
|
{
|
||||||
|
if(remove)
|
||||||
|
key2idx.erase(it);
|
||||||
|
return handle(idx, hd->tag);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// key is in the mapping, but it's of the wrong type.
|
||||||
|
// this happens when called by h_alloc to check if
|
||||||
|
// e.g. a Tex object already exists; at that time,
|
||||||
|
// only the corresponding VFile exists.
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void add_key(uintptr_t key, Handle h)
|
||||||
|
{
|
||||||
|
const i32 idx = h_idx(h);
|
||||||
|
key2idx.insert(std::make_pair(key, idx));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void remove_key(uintptr_t key, H_Type type)
|
||||||
|
{
|
||||||
|
Handle ret = find_key(key, type, true);
|
||||||
|
assert(ret > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int h_free(Handle& h, H_Type type)
|
int h_free(Handle& h, H_Type type)
|
||||||
{
|
{
|
||||||
HDATA* hd = h_data(h, type);
|
HDATA* hd = h_data(h, type);
|
||||||
@ -385,24 +431,7 @@ int h_free(Handle& h, H_Type type)
|
|||||||
vtbl->dtor(hd->user);
|
vtbl->dtor(hd->user);
|
||||||
|
|
||||||
if(hd->key)
|
if(hd->key)
|
||||||
{
|
remove_key(hd->key, type);
|
||||||
It it = key2idx.find(hd->key);
|
|
||||||
// not found in mapping
|
|
||||||
if(it == key2idx.end())
|
|
||||||
debug_warn("h_free: not in key2idx");
|
|
||||||
It end = key2idx.upper_bound(hd->key);
|
|
||||||
for(; it != end; ++it)
|
|
||||||
{
|
|
||||||
i32 idx = it->second;
|
|
||||||
HDATA* hd2 = h_data(idx);
|
|
||||||
// found match
|
|
||||||
if(hd2 && hd2->type == type && hd2->key == hd->key)
|
|
||||||
{
|
|
||||||
key2idx.erase(it);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
free((void*)hd->fn);
|
free((void*)hd->fn);
|
||||||
|
|
||||||
@ -532,7 +561,7 @@ skip_alloc:
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(key)
|
if(key)
|
||||||
key2idx.insert(std::make_pair(key, idx));
|
add_key(key, h);
|
||||||
|
|
||||||
// one-time init
|
// one-time init
|
||||||
hd->tag = tag;
|
hd->tag = tag;
|
||||||
@ -665,25 +694,7 @@ int h_reload(const char* fn)
|
|||||||
|
|
||||||
Handle h_find(H_Type type, uintptr_t key)
|
Handle h_find(H_Type type, uintptr_t key)
|
||||||
{
|
{
|
||||||
It it = key2idx.find(key);
|
return find_key(key, type);
|
||||||
// not found in mapping
|
|
||||||
if(it == key2idx.end())
|
|
||||||
return -1;
|
|
||||||
It end = key2idx.upper_bound(key);
|
|
||||||
for(; it != end; ++it)
|
|
||||||
{
|
|
||||||
i32 idx = it->second;
|
|
||||||
HDATA* hd = h_data(idx);
|
|
||||||
// found match
|
|
||||||
if(hd && hd->type == type && hd->key == key)
|
|
||||||
return handle(idx, hd->tag);
|
|
||||||
}
|
|
||||||
|
|
||||||
// key is in the mapping, but it's of the wrong type.
|
|
||||||
// this happens when called by h_alloc to check if
|
|
||||||
// e.g. a Tex object already exists; at that time,
|
|
||||||
// only the corresponding VFile exists.
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user