Commit 9a2e255b23e44ee9e2ae8c1e5d50cf3ccb26ef16

suzuki toshiya 2011-01-09T21:09:58

[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.

diff --git a/ChangeLog b/ChangeLog
index db1db6c..112f18b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,31 @@
 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.
 
 	* src/cache/ftcglyph.c (FTC_GNode_Compare): Conditionalized
diff --git a/src/cache/ftccache.c b/src/cache/ftccache.c
index a5a915e..f28176e 100644
--- a/src/cache/ftccache.c
+++ b/src/cache/ftccache.c
@@ -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;
diff --git a/src/cache/ftccache.h b/src/cache/ftccache.h
index 10830a9..281ff39 100644
--- a/src/cache/ftccache.h
+++ b/src/cache/ftccache.h
@@ -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;                                                   \