ACE Developer

 找回密码
 用户注册

QQ登录

只需一步,快速开始

查看: 5550|回复: 4

远程hash表,打造比redis更快的nosql内核

[复制链接]
发表于 2012-12-5 18:23:14 | 显示全部楼层 |阅读模式
本帖最后由 serverdev2012 于 2012-12-7 17:29 编辑

hash算法的复杂度是O(n),作用就是计算数据在数组中的下标
而数组操作复杂度是O(1)
也就是hash表的复杂度是O(n)

其实就是胖client瘦server的设计
远程hash表利用将hash计算的任务丢给client做的思想,
将nosql服务器端的hash操作复杂度从O(n)降到O(1),大大提升效率
核心差别就是以下红色部分,设置了远程模式,则不计算hash,直接使用client传递过来的hashValue参数。

实际测试效果是redis dict效率的10倍 md5算法hash表的4倍

RHTable::ELEMENT* RHTable::Find(unsigned char* key, unsigned int size, unsigned int hashValue,  bool bInsert )
{
    BUCKET *pSaveBucket = NULL;
    ELEMENT *pFrontE = NULL;
    ELEMENT *pFindE = NULL;
    unsigned char hashKey[256];
    unsigned int hashSize;
    if ( !m_bRemote ) HashFunction( hashKey, hashSize, key, size );
    unsigned int idx = 0;
    HASH_TABLE *pHashTable = m_pHashTable;
    do

以下是完整代码
RHTable.h
  1. // RHTable.h: interface for the RHTable class.
  2. //
  3. //远程哈稀表
  4. //hash算法可以由远端程序计算好,直接传递int型hash值到hash服务器,
  5. //可实现hash值的分布式计算
  6. //
  7. //不使用远程模式,则与redis内置哈稀表(dict.c/h)类似,但效率更高
  8. //
  9. //使用远程模式实现Nosql服务器,可大大提高查询效率
  10. //        根据选用的hash算法不同,提高效果不同
  11. //        选用md5算法,查询效率为普通模式4倍
  12. //        选用sha1算法,查询效率为普通模式9倍
  13. //
  14. //////////////////////////////////////////////////////////////////////
  15. #ifndef HASHTABLE_H
  16. #define HASHTABLE_H
  17. #include "FixLengthInt.h"
  18. #ifndef NULL
  19. #define NULL 0
  20. #endif
  21. #ifdef WIN32
  22. #include <windows.h>
  23. #else
  24. #endif
  25. #define MAX_HASH_64 0x7fffffffffffffff
  26. #define MAX_HASH_32 0x7fffffff
  27. typedef        void (*pHashFunction)(unsigned char *hashKey, unsigned int &hashSize, unsigned char *key, unsigned int size );
  28. class RHTable  
  29. {
  30.         struct ELEMENT;
  31.         struct HASH_TABLE;
  32. public:
  33. //操作结果
  34. typedef struct OP_R
  35. {
  36.         ELEMENT *pInsert;
  37.         bool bSuccess;
  38. }OP_R;
  39. //迭代器
  40. typedef struct Iterator
  41. {
  42.         Iterator& operator++();
  43.         Iterator& operator++(int);
  44.         Iterator& operator--();
  45.         Iterator& operator--(int);
  46.         bool operator==(Iterator it);
  47.         bool operator!=(Iterator it);
  48.         ELEMENT *pElement;
  49. private:
  50.         friend class RHTable;
  51.         unsigned int idx;
  52.         HASH_TABLE *pHashTable;
  53.         HASH_TABLE *pHeadHashTable;
  54. }Iterator;
  55. private:
  56. //元素
  57. typedef struct ELEMENT
  58. {
  59.         unsigned int hashValue;
  60.         unsigned char *key;
  61.         unsigned short keySize;
  62.         void *value;
  63. private:
  64.         friend class RHTable;
  65.         friend struct Iterator;
  66.         bool isDel;
  67.         ELEMENT *next;//同一个桶内下一个元素
  68. }ELEMENT;
  69. //桶,保存发生hash碰撞的元素
  70. typedef struct BUCKET
  71. {
  72.         ELEMENT *head;//桶中元素链表头
  73. }BUCKET;
  74. //哈稀表
  75. typedef struct HASH_TABLE
  76. {
  77.         BUCKET *buckets;//hash数组
  78.         unsigned long size;//hash数组大小
  79.         unsigned long sizemask;//掩码size的全1表示
  80.         HASH_TABLE *pre;//前一个表
  81.         HASH_TABLE *next;//下一个表(旧hash表)
  82.         unsigned long count;//实际元素数量
  83. }HASH_TABLE;
  84. public:
  85.         RHTable();
  86.         RHTable( unsigned long size );
  87.         virtual ~RHTable();
  88.         void SetHashFunction( pHashFunction hf );
  89.         unsigned int RemoteHash(unsigned char *key, unsigned int size);//远程计算hash,胖client瘦Server模式
  90.         void SetRemoteMode( bool bRemote );
  91.         
  92. public:
  93.         OP_R* Insert(unsigned char *key, unsigned int size, void *value, unsigned int hashValue = 0);
  94.         void* Find(unsigned char *key, unsigned int size, unsigned int hashValue = 0 );
  95.         bool Update(unsigned char *key, unsigned int size, void *value, unsigned int hashValue = 0);
  96.         void Delete(unsigned char *key, unsigned int size, unsigned int hashValue = 0);
  97.         unsigned long Count();
  98.         bool IsEmpty();
  99.         void Clear();
  100.         Iterator Begin();
  101.         Iterator End();
  102. public:
  103.         unsigned long NextPower(unsigned long size);//比size大的最小的2的n次幂数
  104.         unsigned int DJBHash(const unsigned char *buf, int len);//C33算法hash转换函数
  105.         bool KeyCmp( unsigned char *key1, int size1, unsigned char *key2, int size2 );//相同返回true
  106.         bool Expand(unsigned long size);
  107.         ELEMENT* Find(unsigned char *key, unsigned int size, unsigned int hashValue, bool bInsert );
  108.         void ReleaseOldHashTable();//旧hash表如果为null则释放
  109.         void ReleaseHashTable();
  110.         //哈稀算法函数指针(默认md5)
  111.         void (*HashFunction)(unsigned char *hashKey, unsigned int &hashSize,
  112.                 unsigned char *key, unsigned int size );               
  113.         
  114. private:
  115.         HASH_TABLE *m_pHashTable;
  116.         bool m_onBit64;
  117.         unsigned long m_maxHash;
  118.         Iterator m_it;
  119.         bool m_bRemote;
  120. };
  121. #endif // !defined(HASHTABLE_H)
复制代码
RHTable.cpp
  1. // RHTable.cpp: implementation of the RHTable class.
  2. //
  3. //////////////////////////////////////////////////////////////////////
  4. #include "RHTable.h"
  5. #include <cstdio>
  6. #include <cstring>
  7. #include <cstdlib>
  8. #include "md5.h"
  9. //////////////////////////////////////////////////////////////////////
  10. // Construction/Destruction
  11. //////////////////////////////////////////////////////////////////////
  12. RHTable::RHTable()
  13. {
  14.         m_onBit64 = false;
  15.         int *bit = NULL;
  16.         if ( 8 == sizeof(bit) ) m_onBit64 = true;
  17. #if (m_onBit64)
  18.         if ( m_onBit64 ) m_maxHash = MAX_HASH_64;
  19. #else
  20.         m_maxHash = MAX_HASH_32;
  21. #endif
  22.         m_bRemote = false;
  23.         HashFunction = MD5HashFunction;
  24.         m_pHashTable = NULL;
  25.         Expand(0);
  26. }
  27. RHTable::RHTable(unsigned long size)
  28. {
  29.         m_onBit64 = false;
  30.         int *bit = NULL;
  31.         if ( 8 == sizeof(bit) ) m_onBit64 = true;
  32. #if (m_onBit64)
  33.         if ( m_onBit64 ) m_maxHash = MAX_HASH_64;
  34. #else
  35.         m_maxHash = MAX_HASH_32;
  36. #endif
  37.         m_bRemote = false;
  38.         HashFunction = MD5HashFunction;
  39.         m_pHashTable = NULL;
  40.         Expand(size);
  41. }
  42. RHTable::~RHTable()
  43. {
  44.         ReleaseHashTable();
  45. }
  46. void RHTable::SetHashFunction( pHashFunction hf )
  47. {
  48.         HashFunction = hf;
  49. }
  50. unsigned long RHTable::NextPower(unsigned long size)
  51. {
  52.     unsigned long i = 8;
  53.         if (size >= m_maxHash) return m_maxHash;
  54.         while(1)
  55.         {
  56.         if (i >= size) return i;
  57.         i *= 2;
  58.     }
  59. }
  60. unsigned int RHTable::DJBHash(const unsigned char *buf, int len)
  61. {
  62.     unsigned int hash = 5381;
  63.     while (len--)
  64.         {
  65.         hash = ((hash << 5) + hash) + (*buf++); /* hash * 33 + c */
  66.         }
  67.     return hash;
  68. }
  69. bool RHTable::KeyCmp( unsigned char *key1, int size1, unsigned char *key2, int size2 )
  70. {
  71.         if ( size1 != size2 ) return false;
  72.         int i = 0;
  73.         for ( i = 0; i < size1; i++ )
  74.         {
  75.                 if ( key1[i] != key2[i] ) return false;
  76.         }
  77.         
  78.         return true;
  79. }
  80. bool RHTable::Expand(unsigned long size)
  81. {
  82.         HASH_TABLE *pHashTable = new HASH_TABLE;
  83.         if ( NULL == pHashTable ) return false;
  84.         memset( pHashTable, 0, sizeof(HASH_TABLE) );
  85.         size = NextPower(size);
  86.         if ( NULL != m_pHashTable && m_pHashTable->size >= size )
  87.         {
  88.                 if ( m_pHashTable->size * 16 > m_maxHash ) size = m_maxHash;
  89.                 else size = m_pHashTable->size * 16;
  90.         }
  91.         
  92.         pHashTable->size = size;
  93.         pHashTable->sizemask = size - 1;
  94.         pHashTable->buckets = (BUCKET*)malloc(sizeof(BUCKET)*size);
  95.         if ( NULL == pHashTable->buckets )
  96.         {
  97.                 delete pHashTable;
  98.                 return false;
  99.         }
  100.         memset(pHashTable->buckets, 0, sizeof(BUCKET)*size);
  101.         pHashTable->next = m_pHashTable;
  102.         pHashTable->pre = NULL;
  103.         if ( NULL != m_pHashTable )
  104.         {
  105.                 m_pHashTable->pre = pHashTable;
  106.         }
  107.         m_pHashTable = pHashTable;
  108.         
  109.         return true;
  110. }
  111. void RHTable::SetRemoteMode( bool bRemote )
  112. {
  113.         m_bRemote = bRemote;
  114. }
  115. unsigned int RHTable::RemoteHash( unsigned char *key, unsigned int size )
  116. {
  117.         unsigned char hashKey[256];
  118.         unsigned int hashSize;
  119.         HashFunction( hashKey, hashSize, key, size );
  120.         return DJBHash( hashKey, hashSize );
  121. }
  122. RHTable::ELEMENT* RHTable::Find(unsigned char* key, unsigned int size, unsigned int hashValue,  bool bInsert )
  123. {
  124.         BUCKET *pSaveBucket = NULL;
  125.         ELEMENT *pFrontE = NULL;
  126.         ELEMENT *pFindE = NULL;
  127.         unsigned char hashKey[256];
  128.         unsigned int hashSize;
  129.         if ( !m_bRemote ) HashFunction( hashKey, hashSize, key, size );
  130.         unsigned int idx = 0;
  131.         HASH_TABLE *pHashTable = m_pHashTable;
  132.         do
  133.         {
  134.                 idx = hashValue&pHashTable->sizemask;
  135.                 if (NULL == pSaveBucket) pSaveBucket = &pHashTable->buckets[idx];
  136.                 pFindE = pHashTable->buckets[idx].head;
  137.                 while ( NULL != pFindE )
  138.                 {
  139.                         if ( pFindE->isDel
  140.                                 || hashValue != pFindE->hashValue
  141.                                 || !KeyCmp( pFindE->key, pFindE->keySize, key, size ) )
  142.                         {
  143.                                 pFrontE = pFindE;
  144.                                 pFindE = pFindE->next;
  145.                                 continue;
  146.                         }
  147.                         break;
  148.                 }
  149.                 if ( NULL != pFindE ) break;//找到对象
  150.                 pHashTable = pHashTable->next;//旧表中查询
  151.         }
  152.         while (NULL != pHashTable);
  153.         if ( NULL == pFindE  ) //没有找到
  154.         {
  155.                 if ( !bInsert ) return NULL;
  156.                 ELEMENT *pNew = pSaveBucket->head;
  157.                 while ( NULL != pNew )
  158.                 {
  159.                         if ( pNew->isDel ) break;
  160.                         pNew = pNew->next;
  161.                 }
  162.                 bool bNew = false;
  163.                 if ( NULL == pNew )
  164.                 {
  165.                         pNew = new ELEMENT;
  166.                         if ( NULL == pNew ) return NULL;
  167.                         pNew->next = pSaveBucket->head;
  168.                         bNew = true;
  169.                 }
  170.                 pNew->value = NULL;
  171.                 pNew->key = new unsigned char[size];
  172.                 if ( NULL == pNew->key )
  173.                 {
  174.                         delete pNew;
  175.                         return NULL;
  176.                 }
  177.                 pNew->hashValue = hashValue;
  178.                 memcpy( pNew->key, key, size );
  179.                 pNew->keySize = size;
  180.                 pNew->isDel = false;
  181.                 if ( bNew ) pSaveBucket->head = pNew;
  182.                 return pNew;
  183.         }
  184.         if ( pSaveBucket == &pHashTable->buckets[idx] ) return pFindE;
  185.         //数据迁移
  186.         if ( pHashTable->buckets[idx].head == pFindE ) pHashTable->buckets[idx].head = pFindE->next;
  187.         else pFrontE->next = pFindE->next;
  188.         pFindE->next = pSaveBucket->head;
  189.         pSaveBucket->head = pFindE;
  190.         pHashTable->count--;
  191.         m_pHashTable->count++;
  192.         if ( 0 == pHashTable->count ) ReleaseOldHashTable();
  193.         return pFindE;
  194. }
  195. void RHTable::ReleaseOldHashTable()
  196. {
  197.         HASH_TABLE *pEmpty = NULL;
  198.         HASH_TABLE *pHashTable = m_pHashTable;
  199.         while ( NULL != pHashTable->next )
  200.         {
  201.                 if ( 0 < pHashTable->next->count )
  202.                 {
  203.                         pHashTable = pHashTable->next;
  204.                         continue;
  205.                 }
  206.                 pEmpty = pHashTable->next;
  207.                 if ( NULL != pHashTable->next->next )
  208.                 {
  209.                         pHashTable->next->next->pre = pHashTable->next->pre;
  210.                 }
  211.                 pHashTable->next = pHashTable->next->next;
  212.                 /*
  213.                         不用遍历buckets中head
  214.                         因为使count减小到 = 0的操作只有1种,就是3参数的Find(key,size,insert)
  215.                         而Find就会将旧hash表中元素移到新表
  216.                         所以count = 0就一定是所有head指针=NULL
  217.                  */
  218.                 delete pEmpty->buckets;
  219.                 delete pEmpty;
  220.         }
  221. }
  222. RHTable::OP_R* RHTable::Insert(unsigned char *key, unsigned int size, void *value, unsigned int hashValue)
  223. {
  224.         static OP_R res;
  225.         res.bSuccess = false;
  226.         res.pInsert = Find( key, size, hashValue, true );
  227.         if ( NULL == res.pInsert ) return &res;
  228.         if ( NULL != res.pInsert->value ) return &res;
  229.         res.pInsert->value = value;
  230.         res.bSuccess = true;
  231.         m_pHashTable->count++;
  232.         if ( 5 <= m_pHashTable->count / m_pHashTable->size )Expand(0);//平均碰撞最大容忍为5
  233.         return &res;
  234. }
  235. void* RHTable::Find(unsigned char *key, unsigned int size, unsigned int hashValue )
  236. {
  237.         ELEMENT *pFindE = Find( key, size, hashValue, false );
  238.         if ( NULL == pFindE ) return NULL;
  239.         return pFindE->value;
  240. }
  241. bool RHTable::Update(unsigned char *key, unsigned int size, void *value, unsigned int hashValue)
  242. {
  243.         ELEMENT *pFindE = Find( key, size, hashValue, false );
  244.         if ( NULL == pFindE ) return false;
  245.         pFindE->value = value;
  246.         return true;
  247. }
  248. void RHTable::Delete(unsigned char *key, unsigned int size, unsigned int hashValue)
  249. {
  250.         ELEMENT *pFindE = Find( key, size, hashValue, false );
  251.         if ( NULL == pFindE ) return;
  252.         pFindE->isDel = true;
  253.         pFindE->value = NULL;
  254.         delete pFindE->key;
  255.         pFindE->key = NULL;
  256.         pFindE->keySize = 0;
  257.         m_pHashTable->count--;
  258.         return;
  259. }
  260. unsigned long RHTable::Count()
  261. {
  262.         unsigned long count = 0;
  263.         HASH_TABLE *pHashTable = m_pHashTable;
  264.         for ( ; NULL != pHashTable; pHashTable = pHashTable->next )
  265.         {
  266.                 count += pHashTable->count;
  267.         }
  268.         
  269.         return count;
  270. }
  271. bool RHTable::IsEmpty()
  272. {
  273.         return 0 == Count();
  274. }
  275. RHTable::Iterator RHTable::Begin()
  276. {
  277.         m_it.pHeadHashTable = m_pHashTable;
  278.         m_it.pHashTable = m_pHashTable;
  279.         m_it.pElement = NULL;
  280.         m_it.idx = 0;
  281.         
  282.         while ( NULL != m_it.pHashTable )
  283.         {
  284.                 for ( ; m_it.idx < m_it.pHashTable->size; m_it.idx++ )
  285.                 {
  286.                         m_it.pElement = m_it.pHashTable->buckets[m_it.idx].head;
  287.                         while ( NULL != m_it.pElement )
  288.                         {
  289.                                 if ( m_it.pElement->isDel )
  290.                                 {
  291.                                         m_it.pElement = m_it.pElement->next;
  292.                                         continue;
  293.                                 }
  294.                                 return m_it;
  295.                         }
  296.                 }
  297.                 m_it.idx = 0;
  298.                 m_it.pHashTable = m_it.pHashTable->next;
  299.                 m_it.pElement = NULL;
  300.         }
  301.         
  302.         return m_it;
  303. }
  304. RHTable::Iterator RHTable::End()
  305. {
  306.         m_it.pHeadHashTable = m_pHashTable;
  307.         m_it.pHashTable = NULL;
  308.         m_it.pElement = NULL;
  309.         m_it.idx = 0;
  310.         return m_it;
  311. }
  312. void RHTable::Clear()
  313. {
  314.         HASH_TABLE *pHashTable = m_pHashTable;
  315.         ELEMENT *pElement = NULL;
  316.         unsigned int idx = 0;
  317.         
  318.         while ( NULL != pHashTable )
  319.         {
  320.                 for ( ; idx < pHashTable->size; idx++ )
  321.                 {
  322.                         pElement = pHashTable->buckets[idx].head;
  323.                         while ( NULL != pElement )
  324.                         {
  325.                                 if ( !pElement->isDel )
  326.                                 {
  327.                                         pElement->isDel = true;
  328.                                         pElement->value = NULL;
  329.                                         delete pElement->key;
  330.                                         pElement->key = NULL;
  331.                                         pElement->keySize = 0;
  332.                                         pHashTable->count--;
  333.                                 }
  334.                                 pElement = pElement->next;
  335.                         }
  336.                 }
  337.                 idx = 0;
  338.                 pHashTable = pHashTable->next;
  339.         }
  340.         
  341.         return;
  342. }
  343. void RHTable::ReleaseHashTable()
  344. {
  345.         HASH_TABLE *pEmpty = NULL;
  346.         unsigned int i = 0;
  347.         ELEMENT *pDelE = NULL;
  348.         ELEMENT *pHead = NULL;
  349.         while ( NULL != m_pHashTable )
  350.         {
  351.                 for ( i = 0; i < m_pHashTable->size; i++ )
  352.                 {
  353.                         pHead = m_pHashTable->buckets[i].head;
  354.                         while ( NULL != pHead )
  355.                         {
  356.                                 if ( NULL != pHead->key )
  357.                                 {
  358.                                         delete pHead->key;
  359.                                         pHead->key = NULL;
  360.                                 }
  361.                                 pDelE = pHead;
  362.                                 pHead = pHead->next;
  363.                                 delete pDelE;
  364.                                 pDelE = NULL;
  365.                         }
  366.                 }
  367.                 pEmpty = m_pHashTable;
  368.                 m_pHashTable = m_pHashTable->next;
  369.                 delete pEmpty->buckets;
  370.                 delete pEmpty;
  371.         }
  372. }
  373. RHTable::Iterator& RHTable::Iterator::operator++(int)
  374. {
  375.         ++(*this);
  376.         return *this;
  377. }
  378. RHTable::Iterator& RHTable::Iterator::operator++()
  379. {
  380.         if ( NULL == pElement ) return *this;
  381.         pElement = pElement->next;
  382.         while ( NULL != pHashTable )
  383.         {
  384.                 for ( ; idx < pHashTable->size; )
  385.                 {
  386.                         while ( NULL != pElement )
  387.                         {
  388.                                 if ( pElement->isDel )
  389.                                 {
  390.                                         pElement = pElement->next;
  391.                                         continue;
  392.                                 }
  393.                                 return *this;
  394.                         }
  395.                         idx++;
  396.                         pElement = pHashTable->buckets[idx].head;
  397.                 }
  398.                 idx = 0;
  399.                 pElement = NULL;
  400.                 pHashTable = pHashTable->next;
  401.                 if ( NULL == pHashTable ) break;
  402.                 pElement = pHashTable->buckets[idx].head;
  403.         }
  404.         return *this;
  405. }
  406. RHTable::Iterator& RHTable::Iterator::operator--(int)
  407. {
  408.         --(*this);
  409.         return *this;
  410. }
  411. RHTable::Iterator& RHTable::Iterator::operator--()
  412. {
  413.         unsigned int i = idx;
  414.         HASH_TABLE *pCurTable = pHashTable;
  415.         if ( NULL == pElement && 0 == idx && NULL == pHashTable )
  416.         {
  417.                 pCurTable = pHeadHashTable;
  418.                 while ( NULL != pCurTable->next ) pCurTable = pCurTable->next;
  419.                 i = pCurTable->sizemask;
  420.         }
  421.         ELEMENT *pCur = pCurTable->buckets[i].head;
  422.         ELEMENT *pPre = NULL;
  423.         while ( NULL != pCurTable )
  424.         {
  425.                 for ( ; 0 <= i && i < pCurTable->size; )
  426.                 {
  427.                         while ( NULL != pCur && pCur != pElement )
  428.                         {
  429.                                 if ( !pCur->isDel ) pPre = pCur;
  430.                                 pCur = pCur->next;
  431.                         }
  432.                         if ( NULL != pPre || 0 == i ) break;
  433.                         i--;
  434.                         pCur = pCurTable->buckets[i].head;
  435.                 }
  436.                 if ( NULL != pPre || NULL == pCurTable->pre ) break;
  437.                 pCurTable = pCurTable->pre;
  438.                 i = pCurTable->sizemask;
  439.                 pCur = pCurTable->buckets[i].head;
  440.         }
  441.         if ( NULL != pPre )
  442.         {
  443.                 pHashTable = pCurTable;
  444.                 pElement = pPre;
  445.                 idx = i;
  446.         }
  447.         return *this;
  448. }
  449. bool RHTable::Iterator::operator==(RHTable::Iterator it)
  450. {
  451.         if ( pElement != it.pElement ) return false;
  452.         if ( idx != it.idx ) return false;
  453.         if ( pHashTable != it.pHashTable ) return false;
  454.         return true;
  455. }
  456. bool RHTable::Iterator::operator!=(Iterator it)
  457. {
  458.         if ( pElement != it.pElement ) return true;
  459.         if ( idx != it.idx ) return true;
  460.         if ( pHashTable != it.pHashTable ) return true;
  461.         return false;
  462. }
复制代码
FixLengthInt.h
  1. //  Copyright [2012] <xiaoxie820125@sina.com>
  2. #ifndef MDK_FIXLENGTHINT_H
  3. #define MDK_FIXLENGTHINT_H
  4. #ifndef WIN32
  5. #include <sys/types.h>
  6. #endif
  7. namespace mdk
  8. {
  9.         
  10.         typedef char                                int8;
  11.         typedef unsigned char                uint8;
  12.         typedef short                                int16;
  13.         typedef unsigned short                uint16;
  14.         typedef int                                        int32;
  15.         typedef unsigned int                uint32;
  16. #ifdef WIN32
  17.         typedef __int64                                int64;
  18.         typedef unsigned __int64        uint64;
  19. #else
  20. #include <sys/types.h>
  21.         typedef int64_t                                int64;
  22.         typedef u_int64_t                        uint64;
  23. #endif
  24. }//namespace mdk
  25.          
  26. #endif  // MDK_FIXLENGTHINT_H
复制代码

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?用户注册

x
发表于 2012-12-5 19:30:35 | 显示全部楼层
不错!支持这种研究,非常有益。

点评

其实就一点小动作而已 真正提高nosql效率,光这点还不够,io这个大头在哪里摆着 以下自吹不喜者请无视 虽然是小动作,不过很多时候决定胜负的其实就是一个简简单单的小动作  详情 回复 发表于 2012-12-5 20:08
 楼主| 发表于 2012-12-5 20:08:21 | 显示全部楼层
winston 发表于 2012-12-5 19:30
不错!支持这种研究,非常有益。

其实就一点小动作而已:lol
真正提高nosql效率,光这点还不够,io这个大头在哪里摆着

以下自吹不喜者请无视
虽然是小动作,不过很多时候决定胜负的其实就是一个简简单单的小动作:lol
发表于 2012-12-5 22:10:36 | 显示全部楼层
serverdev2012 发表于 2012-12-5 20:08
其实就一点小动作而已
真正提高nosql效率,光这点还不够,io这个大头在哪里摆着

细节是魔鬼。

点评

严重同意,魔鬼就是要让对手意想不到,而不是多高超  详情 回复 发表于 2012-12-6 08:40
 楼主| 发表于 2012-12-6 08:40:57 | 显示全部楼层
winston 发表于 2012-12-5 22:10
细节是魔鬼。

严重同意,魔鬼就是要让对手意想不到,而不是多高超
您需要登录后才可以回帖 登录 | 用户注册

本版积分规则

Archiver|手机版|小黑屋|ACE Developer ( 京ICP备06055248号 )

GMT+8, 2023-2-9 07:48 , Processed in 0.014839 second(s), 8 queries , Redis On.

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表