[cache] Deduplicate the code to get the top node by a hash.

There are several duplicated codes getting the top node
from a cache by a given hash, like:

    idx = hash & cache->mask;
    if ( idx < cache->p )
      idx = hash & ( cache->mask * 2 + 1 );
    pnode = cache->buckets + idx;

To deduplicate them, a cpp-macro to do same work
FTC_NODE__TOP_FOR_HASH( cache, hash ) is introduced.
For non-inlined config, non-ftc_get_top_node_for_hash() is
also introduced.

* src/cache/ftccache.h (FTC_NODE__TOP_FOR_HASH): Declare
and implement inlined version.
(FTC_CACHE_LOOKUP_CMP): Use FTC_NODE__TOP_FOR_HASH().
* src/cache/ftccache.c (ftc_get_top_node_for_hash): Non-
inlined version.
(ftc_node_hash_unlink): Use FTC_NODE__TOP_FOR_HASH().
(ftc_node_hash_link): Ditto.
(FTC_Cache_Lookup): Ditto.
This commit is contained in:
suzuki toshiya 2011-01-09 21:09:58 +09:00
parent 52a1e47a5c
commit 9a2e255b23
3 changed files with 62 additions and 28 deletions

View File

@ -1,3 +1,29 @@
2010-01-09 suzuki toshiya <mpsuzuki@hiroshima-u.ac.jp>
[cache] Deduplicate the code to get the top node by a hash.
There are several duplicated codes getting the top node
from a cache by a given hash, like:
idx = hash & cache->mask;
if ( idx < cache->p )
idx = hash & ( cache->mask * 2 + 1 );
pnode = cache->buckets + idx;
To deduplicate them, a cpp-macro to do same work
FTC_NODE__TOP_FOR_HASH( cache, hash ) is introduced.
For non-inlined config, non-ftc_get_top_node_for_hash() is
also introduced.
* src/cache/ftccache.h (FTC_NODE__TOP_FOR_HASH): Declare
and implement inlined version.
(FTC_CACHE_LOOKUP_CMP): Use FTC_NODE__TOP_FOR_HASH().
* src/cache/ftccache.c (ftc_get_top_node_for_hash): Non-
inlined version.
(ftc_node_hash_unlink): Use FTC_NODE__TOP_FOR_HASH().
(ftc_node_hash_link): Ditto.
(FTC_Cache_Lookup): Ditto.
2010-01-09 suzuki toshiya <mpsuzuki@hiroshima-u.ac.jp>
[cache] inline-specific functions are conditionalized.

45
src/cache/ftccache.c vendored
View File

@ -83,6 +83,25 @@
(FTC_MruNode)node );
}
/* get a top bucket for specified hash from cache,
* body for FTC_NODE__TOP_FOR_HASH( cache, hash )
*/
FT_LOCAL_DEF( FTC_Node* )
ftc_get_top_node_for_hash( FTC_Cache cache,
FT_PtrDist hash )
{
FTC_Node* pnode;
FT_UInt idx;
idx = (FT_UInt)( hash & cache->mask );
if ( idx < cache->p )
idx = (FT_UInt)( hash & ( 2 * cache->mask + 1 ) );
pnode = cache->buckets + idx;
return pnode;
}
#endif /* !FTC_INLINE */
@ -202,16 +221,9 @@
ftc_node_hash_unlink( FTC_Node node0,
FTC_Cache cache )
{
FTC_Node *pnode;
FT_UInt idx;
FTC_Node *pnode = FTC_NODE__TOP_FOR_HASH( cache, node0->hash );
idx = (FT_UInt)( node0->hash & cache->mask );
if ( idx < cache->p )
idx = (FT_UInt)( node0->hash & ( 2 * cache->mask + 1 ) );
pnode = cache->buckets + idx;
for (;;)
{
FTC_Node node = *pnode;
@ -242,16 +254,9 @@
ftc_node_hash_link( FTC_Node node,
FTC_Cache cache )
{
FTC_Node *pnode;
FT_UInt idx;
FTC_Node *pnode = FTC_NODE__TOP_FOR_HASH( cache, node->hash );
idx = (FT_UInt)( node->hash & cache->mask );
if ( idx < cache->p )
idx = (FT_UInt)( node->hash & (2 * cache->mask + 1 ) );
pnode = cache->buckets + idx;
node->link = *pnode;
*pnode = node;
@ -481,7 +486,6 @@
FT_Pointer query,
FTC_Node *anode )
{
FT_UFast idx;
FTC_Node* bucket;
FTC_Node* pnode;
FTC_Node node;
@ -493,12 +497,7 @@
if ( cache == NULL || anode == NULL )
return FTC_Err_Invalid_Argument;
idx = hash & cache->mask;
if ( idx < cache->p )
idx = hash & ( cache->mask * 2 + 1 );
bucket = cache->buckets + idx;
pnode = bucket;
bucket = pnode = FTC_NODE__TOP_FOR_HASH( cache, hash );
for (;;)
{
node = *pnode;

19
src/cache/ftccache.h vendored
View File

@ -72,6 +72,19 @@ FT_BEGIN_HEADER
#define FTC_NODE__NEXT( x ) FTC_NODE( (x)->mru.next )
#define FTC_NODE__PREV( x ) FTC_NODE( (x)->mru.prev )
#ifdef FTC_INLINE
#define FTC_NODE__TOP_FOR_HASH( cache, hash ) \
( ( cache )->buckets + \
( ( ( ( hash ) & ( cache )->mask ) < ( cache )->p ) ? \
( ( hash ) & ( ( cache )->mask * 2 + 1 ) ) : \
( ( hash ) & ( cache )->mask ) ) )
#else
FT_LOCAL( FTC_Node* )
ftc_get_top_node_for_hash( FTC_Cache cache,
FT_PtrDist hash );
#define FTC_NODE__TOP_FOR_HASH( cache, hash ) \
ftc_get_top_node_for_hash( ( cache ), ( hash ) )
#endif
#ifdef FT_CONFIG_OPTION_OLD_INTERNALS
FT_BASE( void )
@ -205,16 +218,12 @@ FT_BEGIN_HEADER
FTC_Cache _cache = FTC_CACHE(cache); \
FT_PtrDist _hash = (FT_PtrDist)(hash); \
FTC_Node_CompareFunc _nodcomp = (FTC_Node_CompareFunc)(nodecmp); \
FT_UFast _idx; \
\
\
error = FTC_Err_Ok; \
node = NULL; \
_idx = _hash & _cache->mask; \
if ( _idx < _cache->p ) \
_idx = _hash & ( _cache->mask*2 + 1 ); \
_bucket = _pnode = FTC_NODE__TOP_FOR_HASH( _cache, _hash ); \
\
_bucket = _pnode = _cache->buckets + _idx; \
for (;;) \
{ \
_node = *_pnode; \