home *** CD-ROM | disk | FTP | other *** search
/ ftp.parl.clemson.edu / 2015-02-07.ftp.parl.clemson.edu.tar / ftp.parl.clemson.edu / pub / pvfs2 / orangefs-2.8.3-20110323.tar.gz / orangefs-2.8.3-20110323.tar / orangefs / src / io / trove / trove-dbpf / dbpf-keyval-pcache.c < prev    next >
C/C++ Source or Header  |  2008-09-08  |  6KB  |  252 lines

  1. /*
  2.  * (C) 2002 Clemson University and The University of Chicago
  3.  *
  4.  * See COPYING in top-level directory.
  5.  */
  6.  
  7. #include <stdlib.h>
  8. #include <string.h>
  9. #ifdef HAVE_MALLOC_H
  10. #include <malloc.h>
  11. #endif
  12.  
  13. #include "dbpf-keyval-pcache.h"
  14. #include "quickhash.h"
  15. #include "gossip.h"
  16. #include "pvfs2-internal.h"
  17.  
  18. /* table size must be a multiple of 2 */
  19. #define DBPF_KEYVAL_PCACHE_TABLE_SIZE (1<<10)
  20. #define DBPF_KEYVAL_PCACHE_HARD_LIMIT 51200
  21.  
  22. struct dbpf_keyval_pcache_key
  23. {
  24.     TROVE_handle handle;
  25.     TROVE_ds_position pos;
  26. };
  27.  
  28. struct dbpf_keyval_pcache_entry
  29. {
  30.     TROVE_handle handle;
  31.     TROVE_ds_position pos;
  32.     char keyname[PVFS_NAME_MAX];
  33.     int keylen;
  34. };
  35.  
  36. static int dbpf_keyval_pcache_compare(
  37.     void * key, struct qhash_head * link);
  38. static int dbpf_keyval_pcache_hash(
  39.     void * key, int size);
  40. static int dbpf_keyval_pcache_entry_free(
  41.     void * entry);
  42.  
  43. PINT_dbpf_keyval_pcache * PINT_dbpf_keyval_pcache_initialize(void)
  44. {
  45.     PINT_dbpf_keyval_pcache * cache;
  46.  
  47.     cache = malloc(sizeof(PINT_dbpf_keyval_pcache));
  48.     if(!cache)
  49.     {
  50.         return NULL;
  51.     }
  52.  
  53.     gen_mutex_init(&cache->mutex);
  54.  
  55.     cache->tcache = PINT_tcache_initialize(
  56.         dbpf_keyval_pcache_compare,
  57.         dbpf_keyval_pcache_hash,
  58.         dbpf_keyval_pcache_entry_free,
  59.         DBPF_KEYVAL_PCACHE_TABLE_SIZE);
  60.     if(!cache->tcache)
  61.     {
  62.         return NULL;
  63.     }
  64.  
  65.     PINT_tcache_set_info(cache->tcache,
  66.                          TCACHE_ENABLE_EXPIRATION,
  67.                          0);
  68.     PINT_tcache_set_info(cache->tcache,
  69.                          TCACHE_HARD_LIMIT,
  70.                          DBPF_KEYVAL_PCACHE_HARD_LIMIT);
  71.  
  72.  
  73.     return cache;
  74. }
  75.     
  76. void PINT_dbpf_keyval_pcache_finalize(
  77.     PINT_dbpf_keyval_pcache * cache)
  78. {
  79.     PINT_tcache_finalize(cache->tcache);
  80.     gen_mutex_destroy(&cache->mutex);
  81.     free(cache);
  82. }
  83.  
  84. static int dbpf_keyval_pcache_compare(
  85.     void * key, struct qhash_head * link)
  86. {
  87.     struct dbpf_keyval_pcache_key * key_entry = 
  88.         (struct dbpf_keyval_pcache_key *)key;
  89.     struct dbpf_keyval_pcache_entry * link_entry =
  90.         (struct dbpf_keyval_pcache_entry *)
  91.         (qhash_entry(link, struct PINT_tcache_entry, hash_link))->payload;
  92.  
  93.     if(key_entry->handle == link_entry->handle &&
  94.        key_entry->pos == link_entry->pos) 
  95.         return 1;
  96.     return 0;
  97. }
  98.     
  99. /* hash from http://burtleburtle.net/bob/hash/evahash.html */
  100. #define mix(a,b,c) \
  101. do { \
  102.   a=a-b;  a=a-c;  a=a^(c>>13); \
  103.       b=b-c;  b=b-a;  b=b^(a<<8);  \
  104.       c=c-a;  c=c-b;  c=c^(b>>13); \
  105.       a=a-b;  a=a-c;  a=a^(c>>12); \
  106.       b=b-c;  b=b-a;  b=b^(a<<16); \
  107.       c=c-a;  c=c-b;  c=c^(b>>5);  \
  108.       a=a-b;  a=a-c;  a=a^(c>>3);  \
  109.       b=b-c;  b=b-a;  b=b^(a<<10); \
  110.       c=c-a;  c=c-b;  c=c^(b>>15); \
  111. } while(0)
  112.  
  113. static int dbpf_keyval_pcache_hash(
  114.     void * key, int size)
  115. {
  116.     struct dbpf_keyval_pcache_entry * key_entry =
  117.         (struct dbpf_keyval_pcache_entry *)key;
  118.  
  119.     uint32_t a = (uint32_t)(key_entry->handle >> 32);
  120.     uint32_t b = (uint32_t)(key_entry->handle & 0x00000000FFFFFFFF);
  121.     uint32_t c = (uint32_t)(key_entry->pos);
  122.  
  123.     mix(a,b,c);
  124.     return (int)(c & (DBPF_KEYVAL_PCACHE_TABLE_SIZE-1));
  125. }
  126.  
  127. static int dbpf_keyval_pcache_entry_free(
  128.     void * entry)
  129. {
  130.     free(entry);
  131.     return 0;
  132. }
  133.  
  134. int PINT_dbpf_keyval_pcache_lookup(
  135.     PINT_dbpf_keyval_pcache *pcache,
  136.     TROVE_handle handle,
  137.     TROVE_ds_position pos,
  138.     const void ** keyname,
  139.     int * length)
  140. {
  141.     struct PINT_tcache_entry *entry;
  142.     struct dbpf_keyval_pcache_key key;
  143.     int ret, status;
  144.  
  145.     key.handle = handle;
  146.     key.pos = pos;
  147.     
  148.     gen_mutex_lock(&pcache->mutex);
  149.     ret = PINT_tcache_lookup(pcache->tcache, (void *)&key, &entry, &status);
  150.     if(ret != 0)
  151.     {
  152.         if(ret == -PVFS_ENOENT)
  153.         {
  154.             gossip_debug(GOSSIP_DBPF_KEYVAL_DEBUG,
  155.                          "Trove KeyVal pcache NOTFOUND: "
  156.                          "handle: %llu, pos: %llu\n",
  157.                          llu(handle), llu(pos));
  158.         }
  159.         else
  160.         {
  161.             gossip_debug(GOSSIP_DBPF_KEYVAL_DEBUG,
  162.                          "Trove KeyVal pcache failed: (error %d): "
  163.                          "handle: %llu, pos: %llu\n",
  164.                          ret, llu(handle), llu(pos));
  165.         }
  166.  
  167.         gen_mutex_unlock(&pcache->mutex);
  168.         return ret;
  169.     }
  170.     gen_mutex_unlock(&pcache->mutex);
  171.  
  172.     *keyname = ((struct dbpf_keyval_pcache_entry *)entry->payload)->keyname;
  173.     *length = ((struct dbpf_keyval_pcache_entry *)entry->payload)->keylen;
  174.  
  175.     gossip_debug(GOSSIP_DBPF_KEYVAL_DEBUG,
  176.                  "Trove KeyVal pcache lookup succeeded: "
  177.                  "handle: %llu, pos: %llu\n",
  178.                  llu(handle), llu(pos));
  179.  
  180.     return 0;
  181. }
  182.  
  183. int PINT_dbpf_keyval_pcache_insert( 
  184.     PINT_dbpf_keyval_pcache *pcache,
  185.     TROVE_handle handle,
  186.     TROVE_ds_position pos,
  187.     const char * keyname,
  188.     int length)
  189. {
  190.     struct dbpf_keyval_pcache_entry *entry;
  191.     struct dbpf_keyval_pcache_key key;
  192.     struct PINT_tcache_entry * tentry;
  193.     int lookup_status;
  194.     int ret;
  195.     int removed;
  196.     
  197.     entry = malloc(sizeof(struct dbpf_keyval_pcache_entry));
  198.     if(!entry)
  199.     {
  200.         return -PVFS_ENOMEM;
  201.     }
  202.  
  203.     key.handle = handle;
  204.     key.pos = pos;
  205.  
  206.     gen_mutex_lock(&pcache->mutex);
  207.     if(PINT_tcache_lookup(
  208.             pcache->tcache, (void *)&key, &tentry, &lookup_status) == 0)
  209.     {
  210.         /* remove entry that already exists */
  211.         PINT_tcache_delete(pcache->tcache, tentry);
  212.     }
  213.  
  214.     entry->handle = handle;
  215.     entry->pos = pos;
  216.     memcpy(entry->keyname, keyname, length);
  217.     entry->keylen = length;
  218.  
  219.     ret = PINT_tcache_insert_entry(pcache->tcache,
  220.                                    &key,
  221.                                    entry,
  222.                                    &removed);
  223.     if(ret != 0)
  224.     {
  225.         gossip_debug(GOSSIP_DBPF_KEYVAL_DEBUG,
  226.                      "Trove KeyVal pcache insert failed: (error: %d) "
  227.                      "handle: %llu, pos: %llu\n",
  228.                      ret, llu(handle), llu(pos));
  229.  
  230.         gen_mutex_unlock(&pcache->mutex);
  231.         free(entry);
  232.         return ret;
  233.     }
  234.     gen_mutex_unlock(&pcache->mutex);
  235.  
  236.     gossip_debug(GOSSIP_DBPF_KEYVAL_DEBUG,
  237.                  "Trove KeyVal pcache insert succeeded: "
  238.                  "handle: %llu, pos: %llu\n",
  239.                  llu(handle), llu(pos));
  240.  
  241.     return 0;
  242. }
  243.     
  244. /*
  245.  * Local variables:
  246.  *  c-indent-level: 4
  247.  *  c-basic-offset: 4
  248.  * End:
  249.  *
  250.  * vim: ts=8 sts=4 sw=4 expandtab
  251.  */
  252.