tc_hashmap.cpp 65 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595
  1. /**
  2. * Tencent is pleased to support the open source community by making Tars available.
  3. *
  4. * Copyright (C) 2016THL A29 Limited, a Tencent company. All rights reserved.
  5. *
  6. * Licensed under the BSD 3-Clause License (the "License"); you may not use this file except
  7. * in compliance with the License. You may obtain a copy of the License at
  8. *
  9. * https://opensource.org/licenses/BSD-3-Clause
  10. *
  11. * Unless required by applicable law or agreed to in writing, software distributed
  12. * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
  13. * CONDITIONS OF ANY KIND, either express or implied. See the License for the
  14. * specific language governing permissions and limitations under the License.
  15. */
  16. #include "util/tc_hashmap.h"
  17. #include "util/tc_pack.h"
  18. #include "util/tc_common.h"
  19. namespace tars
  20. {
  21. int TC_HashMap::Block::getBlockData(TC_HashMap::BlockData &data)
  22. {
  23. data._dirty = isDirty();
  24. data._synct = getSyncTime();
  25. string s;
  26. int ret = get(s);
  27. if(ret != TC_HashMap::RT_OK)
  28. {
  29. return ret;
  30. }
  31. try
  32. {
  33. TC_PackOut po(s.c_str(), s.length());
  34. po >> data._key;
  35. //如果不是只有Key
  36. if(!isOnlyKey())
  37. {
  38. po >> data._value;
  39. }
  40. else
  41. {
  42. return TC_HashMap::RT_ONLY_KEY;
  43. }
  44. }
  45. catch(exception &ex)
  46. {
  47. ret = TC_HashMap::RT_DECODE_ERR;
  48. }
  49. return ret;
  50. }
  51. size_t TC_HashMap::Block::getLastBlockHead()
  52. {
  53. size_t iHead = _iHead;
  54. while(getBlockHead(iHead)->_iBlockNext != 0)
  55. {
  56. iHead = getBlockHead(iHead)->_iBlockNext;
  57. }
  58. return iHead;
  59. }
  60. int TC_HashMap::Block::get(void *pData, size_t &iDataLen)
  61. {
  62. //没有下一个chunk, 一个chunk就可以装下数据了
  63. if(!getBlockHead()->_bNextChunk)
  64. {
  65. memcpy(pData, getBlockHead()->_cData, min(getBlockHead()->_iDataLen, iDataLen));
  66. iDataLen = getBlockHead()->_iDataLen;
  67. return TC_HashMap::RT_OK;
  68. }
  69. else
  70. {
  71. size_t iUseSize = getBlockHead()->_iSize - sizeof(tagBlockHead);
  72. size_t iCopyLen = min(iUseSize, iDataLen);
  73. //copy到当前的block中
  74. memcpy(pData, getBlockHead()->_cData, iCopyLen);
  75. if (iDataLen < iUseSize)
  76. {
  77. return TC_HashMap::RT_NOTALL_ERR; //copy数据不完全
  78. }
  79. //已经copy长度
  80. size_t iHasLen = iCopyLen;
  81. //最大剩余长度
  82. size_t iLeftLen = iDataLen - iCopyLen;
  83. tagChunkHead *pChunk = getChunkHead(getBlockHead()->_iNextChunk);
  84. while(iHasLen < iDataLen)
  85. {
  86. iUseSize = pChunk->_iSize - sizeof(tagChunkHead);
  87. if(!pChunk->_bNextChunk)
  88. {
  89. //copy到当前的chunk中
  90. size_t iCopyLen = min(pChunk->_iDataLen, iLeftLen);
  91. memcpy((char*)pData + iHasLen, pChunk->_cData, iCopyLen);
  92. iDataLen = iHasLen + iCopyLen;
  93. if(iLeftLen < pChunk->_iDataLen)
  94. {
  95. return TC_HashMap::RT_NOTALL_ERR; //copy不完全
  96. }
  97. return TC_HashMap::RT_OK;
  98. }
  99. else
  100. {
  101. size_t iCopyLen = min(iUseSize, iLeftLen);
  102. //copy当前的chunk
  103. memcpy((char*)pData + iHasLen, pChunk->_cData, iCopyLen);
  104. // 这里有bug, = 的时候正好可以,不能返回出错!
  105. //if (iLeftLen <= iUseSize)
  106. if (iLeftLen < iUseSize)
  107. {
  108. iDataLen = iHasLen + iCopyLen;
  109. return TC_HashMap::RT_NOTALL_ERR; //copy不完全
  110. }
  111. //copy当前chunk完全
  112. iHasLen += iCopyLen;
  113. iLeftLen -= iCopyLen;
  114. pChunk = getChunkHead(pChunk->_iNextChunk);
  115. }
  116. }
  117. }
  118. return TC_HashMap::RT_OK;
  119. }
  120. int TC_HashMap::Block::get(string &s)
  121. {
  122. size_t iLen = getDataLen();
  123. char *cData = new char[iLen];
  124. size_t iGetLen = iLen;
  125. int ret = get(cData, iGetLen);
  126. if(ret == TC_HashMap::RT_OK)
  127. {
  128. s.assign(cData, iGetLen);
  129. }
  130. delete[] cData;
  131. return ret;
  132. }
  133. int TC_HashMap::Block::set(const void *pData, size_t iDataLen, bool bOnlyKey, vector<TC_HashMap::BlockData> &vtData)
  134. {
  135. //首先分配刚刚够的长度, 不能多一个chunk, 也不能少一个chunk
  136. int ret = allocate(iDataLen, vtData);
  137. if(ret != TC_HashMap::RT_OK)
  138. {
  139. return ret;
  140. }
  141. if(bOnlyKey)
  142. {
  143. //原始数据是脏数据
  144. if(getBlockHead()->_bDirty)
  145. {
  146. _pMap->delDirtyCount();
  147. }
  148. //数据被修改, 设置为脏数据
  149. getBlockHead()->_bDirty = false;
  150. //原始数据不是OnlyKey数据
  151. if(!getBlockHead()->_bOnlyKey)
  152. {
  153. _pMap->incOnlyKeyCount();
  154. }
  155. }
  156. else
  157. {
  158. //原始数据不是脏数据
  159. if(!getBlockHead()->_bDirty)
  160. {
  161. _pMap->incDirtyCount();
  162. }
  163. //数据被修改, 设置为脏数据
  164. getBlockHead()->_bDirty = true;
  165. //原始数据是OnlyKey数据
  166. if(getBlockHead()->_bOnlyKey)
  167. {
  168. _pMap->delOnlyKeyCount();
  169. }
  170. }
  171. //设置是否只有Key
  172. getBlockHead()->_bOnlyKey = bOnlyKey;
  173. size_t iUseSize = getBlockHead()->_iSize - sizeof(tagBlockHead);
  174. //没有下一个chunk, 一个chunk就可以装下数据了
  175. if(!getBlockHead()->_bNextChunk)
  176. {
  177. memcpy(getBlockHead()->_cData, (char*)pData, iDataLen);
  178. //先copy数据, 再复制数据长度
  179. getBlockHead()->_iDataLen = iDataLen;
  180. }
  181. else
  182. {
  183. //copy到当前的block中
  184. memcpy(getBlockHead()->_cData, (char*)pData, iUseSize);
  185. //剩余程度
  186. size_t iLeftLen = iDataLen - iUseSize;
  187. size_t iCopyLen = iUseSize;
  188. tagChunkHead *pChunk = getChunkHead(getBlockHead()->_iNextChunk);
  189. while(true)
  190. {
  191. //计算chunk的可用大小
  192. iUseSize = pChunk->_iSize - sizeof(tagChunkHead);
  193. if(!pChunk->_bNextChunk)
  194. {
  195. assert(iUseSize >= iLeftLen);
  196. //copy到当前的chunk中
  197. memcpy(pChunk->_cData, (char*)pData + iCopyLen, iLeftLen);
  198. //最后一个chunk, 才有数据长度, 先copy数据再赋值长度
  199. pChunk->_iDataLen = iLeftLen;
  200. iCopyLen += iLeftLen;
  201. iLeftLen -= iLeftLen;
  202. break;
  203. }
  204. else
  205. {
  206. //copy到当前的chunk中
  207. memcpy(pChunk->_cData, (char*)pData + iCopyLen, iUseSize);
  208. iCopyLen += iUseSize;
  209. iLeftLen -= iUseSize;
  210. pChunk = getChunkHead(pChunk->_iNextChunk);
  211. }
  212. }
  213. assert(iLeftLen == 0);
  214. }
  215. _pMap->doUpdate(true);
  216. return TC_HashMap::RT_OK;
  217. }
  218. void TC_HashMap::Block::setDirty(bool b)
  219. {
  220. if(getBlockHead()->_bDirty != b)
  221. {
  222. if (b)
  223. {
  224. _pMap->incDirtyCount();
  225. }
  226. else
  227. {
  228. _pMap->delDirtyCount();
  229. }
  230. _pMap->update(&getBlockHead()->_bDirty, b);
  231. _pMap->doUpdate(true);
  232. }
  233. }
  234. bool TC_HashMap::Block::nextBlock()
  235. {
  236. _iHead = getBlockHead()->_iBlockNext;
  237. return _iHead != 0;
  238. }
  239. bool TC_HashMap::Block::prevBlock()
  240. {
  241. _iHead = getBlockHead()->_iBlockPrev;
  242. return _iHead != 0;
  243. }
  244. void TC_HashMap::Block::deallocate()
  245. {
  246. vector<size_t> v;
  247. v.push_back(_iHead);
  248. if(getBlockHead()->_bNextChunk)
  249. {
  250. deallocate(getBlockHead()->_iNextChunk);
  251. }
  252. _pMap->_pDataAllocator->deallocateMemBlock(v);
  253. }
  254. void TC_HashMap::Block::makeNew(size_t index, size_t iAllocSize)
  255. {
  256. getBlockHead()->_iSize = (uint32_t)iAllocSize;
  257. getBlockHead()->_iIndex = (uint32_t)index;
  258. getBlockHead()->_iSetNext = 0;
  259. getBlockHead()->_iSetPrev = 0;
  260. getBlockHead()->_iGetNext = 0;
  261. getBlockHead()->_iGetPrev = 0;
  262. getBlockHead()->_iSyncTime = 0;
  263. getBlockHead()->_iBlockNext = 0;
  264. getBlockHead()->_iBlockPrev = 0;
  265. getBlockHead()->_bNextChunk = false;
  266. getBlockHead()->_iDataLen = 0;
  267. getBlockHead()->_bDirty = true;
  268. getBlockHead()->_bOnlyKey = false;
  269. _pMap->incDirtyCount();
  270. _pMap->incElementCount();
  271. _pMap->incListCount((uint32_t)index);
  272. //挂在block链表上
  273. if(_pMap->item(index)->_iBlockAddr == 0)
  274. {
  275. //当前hash桶没有元素
  276. _pMap->update(&_pMap->item(index)->_iBlockAddr, _iHead);
  277. _pMap->update(&getBlockHead()->_iBlockNext, (size_t)0);
  278. _pMap->update(&getBlockHead()->_iBlockPrev, (size_t)0);
  279. }
  280. else
  281. {
  282. //当然hash桶有元素, 挂在桶开头
  283. _pMap->update(&getBlockHead(_pMap->item(index)->_iBlockAddr)->_iBlockPrev, _iHead);
  284. _pMap->update(&getBlockHead()->_iBlockNext, _pMap->item(index)->_iBlockAddr);
  285. _pMap->update(&_pMap->item(index)->_iBlockAddr, _iHead);
  286. _pMap->update(&getBlockHead()->_iBlockPrev, (size_t)0);
  287. }
  288. //挂在Set链表的头部
  289. if(_pMap->_pHead->_iSetHead == 0)
  290. {
  291. assert(_pMap->_pHead->_iSetTail == 0);
  292. _pMap->update(&_pMap->_pHead->_iSetHead, _iHead);
  293. _pMap->update(&_pMap->_pHead->_iSetTail, _iHead);
  294. }
  295. else
  296. {
  297. assert(_pMap->_pHead->_iSetTail != 0);
  298. _pMap->update(&getBlockHead()->_iSetNext, _pMap->_pHead->_iSetHead);
  299. _pMap->update(&getBlockHead(_pMap->_pHead->_iSetHead)->_iSetPrev, _iHead);
  300. _pMap->update(&_pMap->_pHead->_iSetHead, _iHead);
  301. }
  302. //挂在Get链表头部
  303. if(_pMap->_pHead->_iGetHead == 0)
  304. {
  305. assert(_pMap->_pHead->_iGetTail == 0);
  306. _pMap->update(&_pMap->_pHead->_iGetHead, _iHead);
  307. _pMap->update(&_pMap->_pHead->_iGetTail, _iHead);
  308. }
  309. else
  310. {
  311. assert(_pMap->_pHead->_iGetTail != 0);
  312. _pMap->update(&getBlockHead()->_iGetNext, _pMap->_pHead->_iGetHead);
  313. _pMap->update(&getBlockHead(_pMap->_pHead->_iGetHead)->_iGetPrev, _iHead);
  314. _pMap->update(&_pMap->_pHead->_iGetHead, _iHead);
  315. }
  316. //一次写更新操作
  317. _pMap->doUpdate(true);
  318. }
  319. void TC_HashMap::Block::erase()
  320. {
  321. //////////////////修改脏数据链表/////////////
  322. if(_pMap->_pHead->_iDirtyTail == _iHead)
  323. {
  324. _pMap->update(&_pMap->_pHead->_iDirtyTail, getBlockHead()->_iSetPrev);
  325. }
  326. //////////////////修改回写数据链表/////////////
  327. if(_pMap->_pHead->_iSyncTail == _iHead)
  328. {
  329. _pMap->update(&_pMap->_pHead->_iSyncTail, getBlockHead()->_iSetPrev);
  330. }
  331. //////////////////修改备份数据链表/////////////
  332. if(_pMap->_pHead->_iBackupTail == _iHead)
  333. {
  334. _pMap->update(&_pMap->_pHead->_iBackupTail, getBlockHead()->_iGetPrev);
  335. }
  336. ////////////////////修改Set链表的数据//////////
  337. {
  338. bool bHead = (_pMap->_pHead->_iSetHead == _iHead);
  339. bool bTail = (_pMap->_pHead->_iSetTail == _iHead);
  340. if(!bHead)
  341. {
  342. if(bTail)
  343. {
  344. assert(getBlockHead()->_iSetNext == 0);
  345. //是尾部, 尾部指针指向上一个元素
  346. _pMap->update(&_pMap->_pHead->_iSetTail, getBlockHead()->_iSetPrev);
  347. _pMap->update(&getBlockHead(getBlockHead()->_iSetPrev)->_iSetNext, (size_t)0);
  348. }
  349. else
  350. {
  351. //不是头部也不是尾部
  352. assert(getBlockHead()->_iSetNext != 0);
  353. _pMap->update(&getBlockHead(getBlockHead()->_iSetPrev)->_iSetNext, getBlockHead()->_iSetNext);
  354. _pMap->update(&getBlockHead(getBlockHead()->_iSetNext)->_iSetPrev, getBlockHead()->_iSetPrev);
  355. }
  356. }
  357. else
  358. {
  359. if(bTail)
  360. {
  361. assert(getBlockHead()->_iSetNext == 0);
  362. assert(getBlockHead()->_iSetPrev == 0);
  363. //头部也是尾部, 指针都设置为0
  364. _pMap->update(&_pMap->_pHead->_iSetHead, (size_t)0);
  365. _pMap->update(&_pMap->_pHead->_iSetTail, (size_t)0);
  366. }
  367. else
  368. {
  369. //头部不是尾部, 头部指针指向下一个元素
  370. assert(getBlockHead()->_iSetNext != 0);
  371. _pMap->update(&_pMap->_pHead->_iSetHead, getBlockHead()->_iSetNext);
  372. //下一个元素上指针为0
  373. _pMap->update(&getBlockHead(getBlockHead()->_iSetNext)->_iSetPrev, (size_t)0);
  374. }
  375. }
  376. }
  377. ////////////////////修改Get链表的数据//////////
  378. //
  379. {
  380. bool bHead = (_pMap->_pHead->_iGetHead == _iHead);
  381. bool bTail = (_pMap->_pHead->_iGetTail == _iHead);
  382. if(!bHead)
  383. {
  384. if(bTail)
  385. {
  386. assert(getBlockHead()->_iGetNext == 0);
  387. //是尾部, 尾部指针指向上一个元素
  388. _pMap->update(&_pMap->_pHead->_iGetTail, getBlockHead()->_iGetPrev);
  389. _pMap->update(&getBlockHead(getBlockHead()->_iGetPrev)->_iGetNext, (size_t)0);
  390. }
  391. else
  392. {
  393. //不是头部也不是尾部
  394. assert(getBlockHead()->_iGetNext != 0);
  395. _pMap->update(&getBlockHead(getBlockHead()->_iGetPrev)->_iGetNext, getBlockHead()->_iGetNext);
  396. _pMap->update(&getBlockHead(getBlockHead()->_iGetNext)->_iGetPrev, getBlockHead()->_iGetPrev);
  397. }
  398. }
  399. else
  400. {
  401. if(bTail)
  402. {
  403. assert(getBlockHead()->_iGetNext == 0);
  404. assert(getBlockHead()->_iGetPrev == 0);
  405. //头部也是尾部, 指针都设置为0
  406. _pMap->update(&_pMap->_pHead->_iGetHead, (size_t)0);
  407. _pMap->update(&_pMap->_pHead->_iGetTail, (size_t)0);
  408. }
  409. else
  410. {
  411. //头部不是尾部, 头部指针指向下一个元素
  412. assert(getBlockHead()->_iGetNext != 0);
  413. _pMap->update(&_pMap->_pHead->_iGetHead, getBlockHead()->_iGetNext);
  414. //下一个元素上指针为0
  415. _pMap->update(&getBlockHead(getBlockHead()->_iGetNext)->_iGetPrev, (size_t)0);
  416. }
  417. }
  418. }
  419. ///////////////////从block链表中去掉///////////
  420. //
  421. //上一个block指向下一个block
  422. if(getBlockHead()->_iBlockPrev != 0)
  423. {
  424. _pMap->update(&getBlockHead(getBlockHead()->_iBlockPrev)->_iBlockNext, getBlockHead()->_iBlockNext);
  425. }
  426. //下一个block指向上一个
  427. if(getBlockHead()->_iBlockNext != 0)
  428. {
  429. _pMap->update(&getBlockHead(getBlockHead()->_iBlockNext)->_iBlockPrev, getBlockHead()->_iBlockPrev);
  430. }
  431. //////////////////如果是hash头部, 需要修改hash索引数据指针//////
  432. //
  433. _pMap->delListCount(getBlockHead()->_iIndex);
  434. if(getBlockHead()->_iBlockPrev == 0)
  435. {
  436. //如果是hash桶的头部, 则还需要处理
  437. TC_HashMap::tagHashItem *pItem = _pMap->item(getBlockHead()->_iIndex);
  438. assert(pItem->_iBlockAddr == _iHead);
  439. if(pItem->_iBlockAddr == _iHead)
  440. {
  441. _pMap->update(&pItem->_iBlockAddr, getBlockHead()->_iBlockNext);
  442. }
  443. }
  444. //////////////////脏数据///////////////////
  445. //
  446. if (isDirty())
  447. {
  448. _pMap->delDirtyCount();
  449. }
  450. if(isOnlyKey())
  451. {
  452. _pMap->delOnlyKeyCount();
  453. }
  454. //元素个数减少
  455. _pMap->delElementCount();
  456. //一次写更新操作
  457. _pMap->doUpdate(true);
  458. //归还到内存中
  459. deallocate();
  460. }
  461. void TC_HashMap::Block::refreshSetList()
  462. {
  463. assert(_pMap->_pHead->_iSetHead != 0);
  464. assert(_pMap->_pHead->_iSetTail != 0);
  465. //修改同步链表
  466. if(_pMap->_pHead->_iSyncTail == _iHead && _pMap->_pHead->_iSetHead != _iHead)
  467. {
  468. _pMap->update(&_pMap->_pHead->_iSyncTail, getBlockHead()->_iSetPrev);
  469. }
  470. //修改脏数据尾部链表指针, 不仅一个元素
  471. if(_pMap->_pHead->_iDirtyTail == _iHead && _pMap->_pHead->_iSetHead != _iHead)
  472. {
  473. //脏数据尾部位置前移
  474. _pMap->update(&_pMap->_pHead->_iDirtyTail, getBlockHead()->_iSetPrev);
  475. }
  476. else if (_pMap->_pHead->_iDirtyTail == 0)
  477. {
  478. //原来没有脏数据
  479. _pMap->update(&_pMap->_pHead->_iDirtyTail, _iHead);
  480. }
  481. //是头部数据或者set新数据时走到这个分支
  482. if(_pMap->_pHead->_iSetHead == _iHead)
  483. {
  484. _pMap->doUpdate(true);
  485. //刷新Get链
  486. refreshGetList();
  487. return;
  488. }
  489. size_t iPrev = getBlockHead()->_iSetPrev;
  490. size_t iNext = getBlockHead()->_iSetNext;
  491. assert(iPrev != 0);
  492. //挂在链表头部
  493. _pMap->update(&getBlockHead()->_iSetNext, _pMap->_pHead->_iSetHead);
  494. _pMap->update(&getBlockHead(_pMap->_pHead->_iSetHead)->_iSetPrev, _iHead);
  495. _pMap->update(&_pMap->_pHead->_iSetHead, _iHead);
  496. _pMap->update(&getBlockHead()->_iSetPrev, (size_t)0);
  497. //上一个元素的Next指针指向下一个元素
  498. _pMap->update(&getBlockHead(iPrev)->_iSetNext, iNext);
  499. //下一个元素的Prev指向上一个元素
  500. if (iNext != 0)
  501. {
  502. _pMap->update(&getBlockHead(iNext)->_iSetPrev, iPrev);
  503. }
  504. else
  505. {
  506. //改变尾部指针
  507. assert(_pMap->_pHead->_iSetTail == _iHead);
  508. _pMap->update(&_pMap->_pHead->_iSetTail, iPrev);
  509. }
  510. _pMap->doUpdate(true);
  511. //刷新Get链
  512. refreshGetList();
  513. }
  514. void TC_HashMap::Block::refreshGetList()
  515. {
  516. assert(_pMap->_pHead->_iGetHead != 0);
  517. assert(_pMap->_pHead->_iGetTail != 0);
  518. //是头部数据
  519. if(_pMap->_pHead->_iGetHead == _iHead)
  520. {
  521. return;
  522. }
  523. size_t iPrev = getBlockHead()->_iGetPrev;
  524. size_t iNext = getBlockHead()->_iGetNext;
  525. assert(iPrev != 0);
  526. //是正在备份的数据
  527. if(_pMap->_pHead->_iBackupTail == _iHead)
  528. {
  529. _pMap->update(&_pMap->_pHead->_iBackupTail, iPrev);
  530. }
  531. //挂在链表头部
  532. _pMap->update(&getBlockHead()->_iGetNext, _pMap->_pHead->_iGetHead);
  533. _pMap->update(&getBlockHead(_pMap->_pHead->_iGetHead)->_iGetPrev, _iHead);
  534. _pMap->update(&_pMap->_pHead->_iGetHead, _iHead);
  535. _pMap->update(&getBlockHead()->_iGetPrev, (size_t)0);
  536. //上一个元素的Next指针指向下一个元素
  537. _pMap->update(&getBlockHead(iPrev)->_iGetNext, iNext);
  538. //下一个元素的Prev指向上一个元素
  539. if (iNext != 0)
  540. {
  541. _pMap->update(&getBlockHead(iNext)->_iGetPrev, iPrev);
  542. }
  543. else
  544. {
  545. //改变尾部指针
  546. assert(_pMap->_pHead->_iGetTail == _iHead);
  547. _pMap->update(&_pMap->_pHead->_iGetTail, iPrev);
  548. }
  549. _pMap->doUpdate(true);
  550. }
  551. void TC_HashMap::Block::deallocate(size_t iChunk)
  552. {
  553. tagChunkHead *pChunk = getChunkHead(iChunk);
  554. vector<size_t> v;
  555. v.push_back(iChunk);
  556. //获取所有后续的chunk地址
  557. while(true)
  558. {
  559. if(pChunk->_bNextChunk)
  560. {
  561. v.push_back(pChunk->_iNextChunk);
  562. pChunk = getChunkHead(pChunk->_iNextChunk);
  563. }
  564. else
  565. {
  566. break;
  567. }
  568. }
  569. //空间全部释放掉
  570. _pMap->_pDataAllocator->deallocateMemBlock(v);
  571. }
  572. int TC_HashMap::Block::allocate(size_t iDataLen, vector<TC_HashMap::BlockData> &vtData)
  573. {
  574. size_t fn = 0;
  575. //一个块的真正的数据容量
  576. fn = getBlockHead()->_iSize - sizeof(tagBlockHead);
  577. if(fn >= iDataLen)
  578. {
  579. //一个block就可以了, 后续的chunk都要释放掉
  580. if(getBlockHead()->_bNextChunk)
  581. {
  582. size_t iNextChunk = getBlockHead()->_iNextChunk;
  583. //先修改自己的区块
  584. _pMap->update(&getBlockHead()->_bNextChunk, false);
  585. _pMap->update(&getBlockHead()->_iDataLen, (size_t)0);
  586. _pMap->doUpdate(true);
  587. //修改成功后再释放区块, 从而保证, 不会core的时候导致整个内存块不可用
  588. deallocate(iNextChunk);
  589. }
  590. return TC_HashMap::RT_OK;
  591. }
  592. //计算还需要多少长度
  593. fn = iDataLen - fn;
  594. if(getBlockHead()->_bNextChunk)
  595. {
  596. tagChunkHead *pChunk = getChunkHead(getBlockHead()->_iNextChunk);
  597. while(true)
  598. {
  599. if(fn <= (pChunk->_iSize - sizeof(tagChunkHead)))
  600. {
  601. //已经不需要chunk了, 释放多余的chunk
  602. if(pChunk->_bNextChunk)
  603. {
  604. size_t iNextChunk = pChunk->_iNextChunk;
  605. _pMap->update(&pChunk->_bNextChunk, false);
  606. _pMap->doUpdate(true);
  607. //一旦异常core, 最坏的情况就是少了可用的区块, 但是整个内存结构还是可用的
  608. deallocate(iNextChunk);
  609. }
  610. return TC_HashMap::RT_OK ;
  611. }
  612. //计算, 还需要多少长度
  613. fn -= pChunk->_iSize - sizeof(tagChunkHead);
  614. if(pChunk->_bNextChunk)
  615. {
  616. pChunk = getChunkHead(pChunk->_iNextChunk);
  617. }
  618. else
  619. {
  620. //没有后续chunk了, 需要新分配fn的空间
  621. vector<size_t> chunks;
  622. int ret = allocateChunk(fn, chunks, vtData);
  623. if(ret != TC_HashMap::RT_OK)
  624. {
  625. //没有内存可以分配
  626. return ret;
  627. }
  628. _pMap->update(&pChunk->_bNextChunk, true);
  629. _pMap->update(&pChunk->_iNextChunk, chunks[0]);
  630. //chunk指向分配的第一个chunk
  631. pChunk = getChunkHead(chunks[0]);
  632. //修改第一个chunk的属性, 保证异常core的时候, chunk链表不会有问题
  633. _pMap->update(&pChunk->_bNextChunk, false);
  634. _pMap->update(&pChunk->_iDataLen, (size_t)0);
  635. _pMap->doUpdate(true);
  636. //连接每个chunk
  637. return joinChunk(pChunk, chunks);
  638. }
  639. }
  640. }
  641. else
  642. {
  643. //没有后续chunk了, 需要新分配fn空间
  644. vector<size_t> chunks;
  645. int ret = allocateChunk(fn, chunks, vtData);
  646. if(ret != TC_HashMap::RT_OK)
  647. {
  648. //没有内存可以分配
  649. return ret;
  650. }
  651. _pMap->update(&getBlockHead()->_bNextChunk, true);
  652. _pMap->update(&getBlockHead()->_iNextChunk, chunks[0]);
  653. //chunk指向分配的第一个chunk
  654. tagChunkHead *pChunk = getChunkHead(chunks[0]);
  655. //修改第一个chunk的属性, 保证异常core的时候, chunk链表不会有问题
  656. _pMap->update(&pChunk->_bNextChunk, false);
  657. _pMap->update(&pChunk->_iDataLen, (size_t)0);
  658. _pMap->doUpdate(true);
  659. //连接每个chunk
  660. return joinChunk(pChunk, chunks);
  661. }
  662. return TC_HashMap::RT_OK;
  663. }
  664. int TC_HashMap::Block::joinChunk(tagChunkHead *pChunk, const vector<size_t> chunks)
  665. {
  666. for (size_t i = 0; i < chunks.size(); ++i)
  667. {
  668. if (i == chunks.size() - 1)
  669. {
  670. _pMap->update(&pChunk->_bNextChunk, false);
  671. _pMap->doUpdate(true);
  672. return TC_HashMap::RT_OK;
  673. }
  674. else
  675. {
  676. _pMap->update(&pChunk->_bNextChunk, true);
  677. _pMap->update(&pChunk->_iNextChunk, chunks[i+1]);
  678. pChunk = getChunkHead(chunks[i+1]);
  679. _pMap->update(&pChunk->_bNextChunk, false);
  680. _pMap->update(&pChunk->_iDataLen, (size_t)0);
  681. _pMap->doUpdate(true);
  682. }
  683. }
  684. return TC_HashMap::RT_OK;
  685. }
  686. int TC_HashMap::Block::allocateChunk(size_t fn, vector<size_t> &chunks, vector<TC_HashMap::BlockData> &vtData)
  687. {
  688. assert(fn > 0);
  689. while(true)
  690. {
  691. size_t iAllocSize = fn;
  692. //分配空间
  693. size_t t = _pMap->_pDataAllocator->allocateChunk(_iHead, iAllocSize, vtData);
  694. if (t == 0)
  695. {
  696. //没有内存可以分配了, 先把分配的归还
  697. _pMap->_pDataAllocator->deallocateMemBlock(chunks);
  698. chunks.clear();
  699. return TC_HashMap::RT_NO_MEMORY;
  700. }
  701. //设置分配的数据块的大小
  702. getChunkHead(t)->_iSize = (uint32_t)iAllocSize;
  703. chunks.push_back(t);
  704. //分配够了
  705. if(fn <= (iAllocSize - sizeof(tagChunkHead)))
  706. {
  707. break;
  708. }
  709. //还需要多少空间
  710. fn -= iAllocSize - sizeof(tagChunkHead);
  711. }
  712. return TC_HashMap::RT_OK;
  713. }
  714. size_t TC_HashMap::Block::getDataLen()
  715. {
  716. size_t n = 0;
  717. if(!getBlockHead()->_bNextChunk)
  718. {
  719. n += getBlockHead()->_iDataLen;
  720. return n;
  721. }
  722. //当前块的大小
  723. n += getBlockHead()->_iSize - sizeof(tagBlockHead);
  724. tagChunkHead *pChunk = getChunkHead(getBlockHead()->_iNextChunk);
  725. while (true)
  726. {
  727. if(pChunk->_bNextChunk)
  728. {
  729. //当前块的大小
  730. n += pChunk->_iSize - sizeof(tagChunkHead);
  731. pChunk = getChunkHead(pChunk->_iNextChunk);
  732. }
  733. else
  734. {
  735. n += pChunk->_iDataLen;
  736. break;
  737. }
  738. }
  739. return n;
  740. }
  741. ////////////////////////////////////////////////////////
  742. size_t TC_HashMap::BlockAllocator::allocateMemBlock(size_t index, size_t &iAllocSize, vector<TC_HashMap::BlockData> &vtData)
  743. {
  744. begin:
  745. void *pAddr = _pChunkAllocator->allocate(iAllocSize, iAllocSize);
  746. if(pAddr == NULL)
  747. {
  748. size_t ret = _pMap->eraseExcept(0, vtData);
  749. if(ret == 0)
  750. return 0; //没有空间可以释放了
  751. goto begin;
  752. }
  753. //分配的新的MemBlock, 初始化一下
  754. size_t iAddr = _pMap->getRelative(pAddr);
  755. Block block(_pMap, iAddr);
  756. block.makeNew(index, iAllocSize);
  757. _pMap->incChunkCount();
  758. return iAddr;
  759. }
  760. size_t TC_HashMap::BlockAllocator::allocateChunk(size_t iAddr, size_t &iAllocSize, vector<TC_HashMap::BlockData> &vtData)
  761. {
  762. begin:
  763. void *pAddr = _pChunkAllocator->allocate(iAllocSize, iAllocSize);
  764. if(pAddr == NULL)
  765. {
  766. size_t ret = _pMap->eraseExcept(iAddr, vtData);
  767. if(ret == 0)
  768. return 0; //没有空间可以释放了
  769. goto begin;
  770. }
  771. _pMap->incChunkCount();
  772. return _pMap->getRelative(pAddr);
  773. }
  774. void TC_HashMap::BlockAllocator::deallocateMemBlock(const vector<size_t> &v)
  775. {
  776. for(size_t i = 0; i < v.size(); i++)
  777. {
  778. _pChunkAllocator->deallocate(_pMap->getAbsolute(v[i]));
  779. _pMap->delChunkCount();
  780. }
  781. }
  782. void TC_HashMap::BlockAllocator::deallocateMemBlock(size_t v)
  783. {
  784. _pChunkAllocator->deallocate(_pMap->getAbsolute(v));
  785. _pMap->delChunkCount();
  786. }
  787. ///////////////////////////////////////////////////////////////////
  788. TC_HashMap::HashMapLockItem::HashMapLockItem(TC_HashMap *pMap, size_t iAddr)
  789. : _pMap(pMap)
  790. , _iAddr(iAddr)
  791. {
  792. }
  793. TC_HashMap::HashMapLockItem::HashMapLockItem(const HashMapLockItem &mcmdi)
  794. : _pMap(mcmdi._pMap)
  795. , _iAddr(mcmdi._iAddr)
  796. {
  797. }
  798. TC_HashMap::HashMapLockItem &TC_HashMap::HashMapLockItem::operator=(const TC_HashMap::HashMapLockItem &mcmdi)
  799. {
  800. if(this != &mcmdi)
  801. {
  802. _pMap = mcmdi._pMap;
  803. _iAddr = mcmdi._iAddr;
  804. }
  805. return (*this);
  806. }
  807. bool TC_HashMap::HashMapLockItem::operator==(const TC_HashMap::HashMapLockItem &mcmdi)
  808. {
  809. return _pMap == mcmdi._pMap && _iAddr == mcmdi._iAddr;
  810. }
  811. bool TC_HashMap::HashMapLockItem::operator!=(const TC_HashMap::HashMapLockItem &mcmdi)
  812. {
  813. return _pMap != mcmdi._pMap || _iAddr != mcmdi._iAddr;
  814. }
  815. bool TC_HashMap::HashMapLockItem::isDirty()
  816. {
  817. Block block(_pMap, _iAddr);
  818. return block.isDirty();
  819. }
  820. bool TC_HashMap::HashMapLockItem::isOnlyKey()
  821. {
  822. Block block(_pMap, _iAddr);
  823. return block.isOnlyKey();
  824. }
  825. time_t TC_HashMap::HashMapLockItem::getSyncTime()
  826. {
  827. Block block(_pMap, _iAddr);
  828. return block.getSyncTime();
  829. }
  830. int TC_HashMap::HashMapLockItem::get(string& k, string& v)
  831. {
  832. string s;
  833. Block block(_pMap, _iAddr);
  834. int ret = block.get(s);
  835. if(ret != TC_HashMap::RT_OK)
  836. {
  837. return ret;
  838. }
  839. try
  840. {
  841. TC_PackOut po(s.c_str(), s.length());
  842. po >> k;
  843. if(!block.isOnlyKey())
  844. {
  845. po >> v;
  846. }
  847. else
  848. {
  849. v = "";
  850. return TC_HashMap::RT_ONLY_KEY;
  851. }
  852. }
  853. catch ( exception &ex )
  854. {
  855. return TC_HashMap::RT_EXCEPTION_ERR;
  856. }
  857. return TC_HashMap::RT_OK;
  858. }
  859. int TC_HashMap::HashMapLockItem::get(string& k)
  860. {
  861. string s;
  862. Block block(_pMap, _iAddr);
  863. int ret = block.get(s);
  864. if(ret != TC_HashMap::RT_OK)
  865. {
  866. return ret;
  867. }
  868. try
  869. {
  870. TC_PackOut po(s.c_str(), s.length());
  871. po >> k;
  872. }
  873. catch ( exception &ex )
  874. {
  875. return TC_HashMap::RT_EXCEPTION_ERR;
  876. }
  877. return TC_HashMap::RT_OK;
  878. }
  879. int TC_HashMap::HashMapLockItem::set(const string& k, const string& v, vector<TC_HashMap::BlockData> &vtData)
  880. {
  881. Block block(_pMap, _iAddr);
  882. TC_PackIn pi;
  883. pi << k;
  884. pi << v;
  885. return block.set(pi.topacket().c_str(), pi.topacket().length(), false, vtData);
  886. }
  887. int TC_HashMap::HashMapLockItem::set(const string& k, vector<TC_HashMap::BlockData> &vtData)
  888. {
  889. Block block(_pMap, _iAddr);
  890. TC_PackIn pi;
  891. pi << k;
  892. return block.set(pi.topacket().c_str(), pi.topacket().length(), true, vtData);
  893. }
  894. bool TC_HashMap::HashMapLockItem::equal(const string &k, string &v, int &ret)
  895. {
  896. string k1;
  897. ret = get(k1, v);
  898. if ((ret == TC_HashMap::RT_OK || ret == TC_HashMap::RT_ONLY_KEY) && k == k1)
  899. {
  900. return true;
  901. }
  902. return false;
  903. }
  904. bool TC_HashMap::HashMapLockItem::equal(const string& k, int &ret)
  905. {
  906. string k1;
  907. ret = get(k1);
  908. if (ret == TC_HashMap::RT_OK && k == k1)
  909. {
  910. return true;
  911. }
  912. return false;
  913. }
  914. void TC_HashMap::HashMapLockItem::nextItem(int iType)
  915. {
  916. Block block(_pMap, _iAddr);
  917. if(iType == HashMapLockIterator::IT_BLOCK)
  918. {
  919. size_t index = block.getBlockHead()->_iIndex;
  920. //当前block链表有元素
  921. if(block.nextBlock())
  922. {
  923. _iAddr = block.getHead();
  924. return;
  925. }
  926. index += 1;
  927. while(index < _pMap->_hash.size())
  928. {
  929. //当前的hash桶也没有数据
  930. if (_pMap->item(index)->_iBlockAddr == 0)
  931. {
  932. ++index;
  933. continue;
  934. }
  935. _iAddr = _pMap->item(index)->_iBlockAddr;
  936. return;
  937. }
  938. _iAddr = 0; //到尾部了
  939. }
  940. else if(iType == HashMapLockIterator::IT_SET)
  941. {
  942. _iAddr = block.getBlockHead()->_iSetNext;
  943. }
  944. else if(iType == HashMapLockIterator::IT_GET)
  945. {
  946. _iAddr = block.getBlockHead()->_iGetNext;
  947. }
  948. }
  949. void TC_HashMap::HashMapLockItem::prevItem(int iType)
  950. {
  951. Block block(_pMap, _iAddr);
  952. if(iType == HashMapLockIterator::IT_BLOCK)
  953. {
  954. size_t index = block.getBlockHead()->_iIndex;
  955. if(block.prevBlock())
  956. {
  957. _iAddr = block.getHead();
  958. return;
  959. }
  960. while(index > 0)
  961. {
  962. //当前的hash桶也没有数据
  963. if (_pMap->item(index-1)->_iBlockAddr == 0)
  964. {
  965. --index;
  966. continue;
  967. }
  968. //需要到这个桶的末尾
  969. Block tmp(_pMap, _pMap->item(index-1)->_iBlockAddr);
  970. _iAddr = tmp.getLastBlockHead();
  971. return;
  972. }
  973. _iAddr = 0; //到尾部了
  974. }
  975. else if(iType == HashMapLockIterator::IT_SET)
  976. {
  977. _iAddr = block.getBlockHead()->_iSetPrev;
  978. }
  979. else if(iType == HashMapLockIterator::IT_GET)
  980. {
  981. _iAddr = block.getBlockHead()->_iGetPrev;
  982. }
  983. }
  984. ///////////////////////////////////////////////////////////////////
  985. TC_HashMap::HashMapLockIterator::HashMapLockIterator()
  986. : _pMap(NULL), _iItem(NULL, 0), _iType(IT_BLOCK), _iOrder(IT_NEXT)
  987. {
  988. }
  989. TC_HashMap::HashMapLockIterator::HashMapLockIterator(TC_HashMap *pMap, size_t iAddr, int iType, int iOrder)
  990. : _pMap(pMap), _iItem(_pMap, iAddr), _iType(iType), _iOrder(iOrder)
  991. {
  992. }
  993. TC_HashMap::HashMapLockIterator::HashMapLockIterator(const HashMapLockIterator &it)
  994. : _pMap(it._pMap),_iItem(it._iItem), _iType(it._iType), _iOrder(it._iOrder)
  995. {
  996. }
  997. TC_HashMap::HashMapLockIterator& TC_HashMap::HashMapLockIterator::operator=(const HashMapLockIterator &it)
  998. {
  999. if(this != &it)
  1000. {
  1001. _pMap = it._pMap;
  1002. _iItem = it._iItem;
  1003. _iType = it._iType;
  1004. _iOrder = it._iOrder;
  1005. }
  1006. return (*this);
  1007. }
  1008. bool TC_HashMap::HashMapLockIterator::operator==(const HashMapLockIterator& mcmi)
  1009. {
  1010. if (_iItem.getAddr() != 0 || mcmi._iItem.getAddr() != 0)
  1011. {
  1012. return _pMap == mcmi._pMap
  1013. && _iItem == mcmi._iItem
  1014. && _iType == mcmi._iType
  1015. && _iOrder == mcmi._iOrder;
  1016. }
  1017. return _pMap == mcmi._pMap;
  1018. }
  1019. bool TC_HashMap::HashMapLockIterator::operator!=(const HashMapLockIterator& mcmi)
  1020. {
  1021. if (_iItem.getAddr() != 0 || mcmi._iItem.getAddr() != 0 )
  1022. {
  1023. return _pMap != mcmi._pMap
  1024. || _iItem != mcmi._iItem
  1025. || _iType != mcmi._iType
  1026. || _iOrder != mcmi._iOrder;
  1027. }
  1028. return _pMap != mcmi._pMap;
  1029. }
  1030. TC_HashMap::HashMapLockIterator& TC_HashMap::HashMapLockIterator::operator++()
  1031. {
  1032. if(_iOrder == IT_NEXT)
  1033. {
  1034. _iItem.nextItem(_iType);
  1035. }
  1036. else
  1037. {
  1038. _iItem.prevItem(_iType);
  1039. }
  1040. return (*this);
  1041. }
  1042. TC_HashMap::HashMapLockIterator TC_HashMap::HashMapLockIterator::operator++(int)
  1043. {
  1044. HashMapLockIterator it(*this);
  1045. if(_iOrder == IT_NEXT)
  1046. {
  1047. _iItem.nextItem(_iType);
  1048. }
  1049. else
  1050. {
  1051. _iItem.prevItem(_iType);
  1052. }
  1053. return it;
  1054. }
  1055. ///////////////////////////////////////////////////////////////////
  1056. TC_HashMap::HashMapItem::HashMapItem(TC_HashMap *pMap, size_t iIndex)
  1057. : _pMap(pMap)
  1058. , _iIndex(iIndex)
  1059. {
  1060. }
  1061. TC_HashMap::HashMapItem::HashMapItem(const HashMapItem &mcmdi)
  1062. : _pMap(mcmdi._pMap)
  1063. , _iIndex(mcmdi._iIndex)
  1064. {
  1065. }
  1066. TC_HashMap::HashMapItem &TC_HashMap::HashMapItem::operator=(const TC_HashMap::HashMapItem &mcmdi)
  1067. {
  1068. if(this != &mcmdi)
  1069. {
  1070. _pMap = mcmdi._pMap;
  1071. _iIndex = mcmdi._iIndex;
  1072. }
  1073. return (*this);
  1074. }
  1075. bool TC_HashMap::HashMapItem::operator==(const TC_HashMap::HashMapItem &mcmdi)
  1076. {
  1077. return _pMap == mcmdi._pMap && _iIndex == mcmdi._iIndex;
  1078. }
  1079. bool TC_HashMap::HashMapItem::operator!=(const TC_HashMap::HashMapItem &mcmdi)
  1080. {
  1081. return _pMap != mcmdi._pMap || _iIndex != mcmdi._iIndex;
  1082. }
  1083. void TC_HashMap::HashMapItem::get(vector<TC_HashMap::BlockData> &vtData)
  1084. {
  1085. size_t iAddr = _pMap->item(_iIndex)->_iBlockAddr;
  1086. while(iAddr != 0)
  1087. {
  1088. Block block(_pMap, iAddr);
  1089. TC_HashMap::BlockData data;
  1090. int ret = block.getBlockData(data);
  1091. if(ret == TC_HashMap::RT_OK)
  1092. {
  1093. vtData.push_back(data);
  1094. }
  1095. iAddr = block.getBlockHead()->_iBlockNext;
  1096. }
  1097. }
  1098. void TC_HashMap::HashMapItem::nextItem()
  1099. {
  1100. if(_iIndex == (size_t)(-1))
  1101. {
  1102. return;
  1103. }
  1104. if(_iIndex >= _pMap->getHashCount() - 1)
  1105. {
  1106. _iIndex = (size_t)(-1);
  1107. return;
  1108. }
  1109. _iIndex++;
  1110. }
  1111. int TC_HashMap::HashMapItem::setDirty()
  1112. {
  1113. if(_pMap->getMapHead()._bReadOnly) return RT_READONLY;
  1114. size_t iAddr = _pMap->item(_iIndex)->_iBlockAddr;
  1115. while(iAddr != 0)
  1116. {
  1117. Block block(_pMap, iAddr);
  1118. if(!block.isOnlyKey())
  1119. {
  1120. _pMap->doUpdate();
  1121. block.setDirty(true);
  1122. block.refreshSetList();
  1123. }
  1124. iAddr = block.getBlockHead()->_iBlockNext;
  1125. }
  1126. return RT_OK;
  1127. }
  1128. ///////////////////////////////////////////////////////////////////
  1129. TC_HashMap::HashMapIterator::HashMapIterator()
  1130. : _pMap(NULL), _iItem(NULL, 0)
  1131. {
  1132. }
  1133. TC_HashMap::HashMapIterator::HashMapIterator(TC_HashMap *pMap, size_t iIndex)
  1134. : _pMap(pMap), _iItem(_pMap, iIndex)
  1135. {
  1136. }
  1137. TC_HashMap::HashMapIterator::HashMapIterator(const HashMapIterator &it)
  1138. : _pMap(it._pMap),_iItem(it._iItem)
  1139. {
  1140. }
  1141. TC_HashMap::HashMapIterator& TC_HashMap::HashMapIterator::operator=(const HashMapIterator &it)
  1142. {
  1143. if(this != &it)
  1144. {
  1145. _pMap = it._pMap;
  1146. _iItem = it._iItem;
  1147. }
  1148. return (*this);
  1149. }
  1150. bool TC_HashMap::HashMapIterator::operator==(const HashMapIterator& mcmi)
  1151. {
  1152. if (_iItem.getIndex() != -1 || mcmi._iItem.getIndex() != -1)
  1153. {
  1154. return _pMap == mcmi._pMap && _iItem == mcmi._iItem;
  1155. }
  1156. return _pMap == mcmi._pMap;
  1157. }
  1158. bool TC_HashMap::HashMapIterator::operator!=(const HashMapIterator& mcmi)
  1159. {
  1160. if (_iItem.getIndex() != -1 || mcmi._iItem.getIndex() != -1 )
  1161. {
  1162. return _pMap != mcmi._pMap || _iItem != mcmi._iItem;
  1163. }
  1164. return _pMap != mcmi._pMap;
  1165. }
  1166. TC_HashMap::HashMapIterator& TC_HashMap::HashMapIterator::operator++()
  1167. {
  1168. _iItem.nextItem();
  1169. return (*this);
  1170. }
  1171. TC_HashMap::HashMapIterator TC_HashMap::HashMapIterator::operator++(int)
  1172. {
  1173. HashMapIterator it(*this);
  1174. _iItem.nextItem();
  1175. return it;
  1176. }
  1177. //////////////////////////////////////////////////////////////////////////////////
  1178. void TC_HashMap::init(void *pAddr)
  1179. {
  1180. _pHead = static_cast<tagMapHead*>(pAddr);
  1181. _pstModifyHead = static_cast<tagModifyHead*>((void*)((char*)pAddr + sizeof(tagMapHead)));
  1182. }
  1183. void TC_HashMap::initDataBlockSize(size_t iMinDataSize, size_t iMaxDataSize, float fFactor)
  1184. {
  1185. _iMinDataSize = iMinDataSize;
  1186. _iMaxDataSize = iMaxDataSize;
  1187. _fFactor = fFactor;
  1188. }
  1189. void TC_HashMap::create(void *pAddr, size_t iSize)
  1190. {
  1191. if(sizeof(tagHashItem) * 1
  1192. + sizeof(tagMapHead)
  1193. + sizeof(tagModifyHead)
  1194. + sizeof(TC_MemMultiChunkAllocator::tagChunkAllocatorHead)
  1195. + 10 > iSize)
  1196. {
  1197. throw TC_HashMap_Exception("[TC_HashMap::create] mem size not enougth.");
  1198. }
  1199. if(_iMinDataSize == 0 || _iMaxDataSize == 0 || _fFactor < 1.0)
  1200. {
  1201. throw TC_HashMap_Exception("[TC_HashMap::create] init data size error:" + TC_Common::tostr(_iMinDataSize) + "|" + TC_Common::tostr(_iMaxDataSize) + "|" + TC_Common::tostr(_fFactor));
  1202. }
  1203. init(pAddr);
  1204. _pHead->_cMaxVersion = MAX_VERSION;
  1205. _pHead->_cMinVersion = MIN_VERSION;
  1206. _pHead->_bReadOnly = false;
  1207. _pHead->_bAutoErase = true;
  1208. _pHead->_cEraseMode = ERASEBYGET;
  1209. _pHead->_iMemSize = iSize;
  1210. _pHead->_iMinDataSize = _iMinDataSize;
  1211. _pHead->_iMaxDataSize = _iMaxDataSize;
  1212. _pHead->_fFactor = _fFactor;
  1213. _pHead->_fRadio = _fRadio;
  1214. _pHead->_iElementCount = 0;
  1215. _pHead->_iEraseCount = 10;
  1216. _pHead->_iSetHead = 0;
  1217. _pHead->_iSetTail = 0;
  1218. _pHead->_iGetHead = 0;
  1219. _pHead->_iGetTail = 0;
  1220. _pHead->_iDirtyCount = 0;
  1221. _pHead->_iDirtyTail = 0;
  1222. _pHead->_iSyncTime = 60 * 10; //缺省十分钟回写一次
  1223. _pHead->_iUsedChunk = 0;
  1224. _pHead->_iGetCount = 0;
  1225. _pHead->_iHitCount = 0;
  1226. _pHead->_iBackupTail = 0;
  1227. _pHead->_iSyncTail = 0;
  1228. //计算平均block大小
  1229. size_t iBlockSize = (_pHead->_iMinDataSize + _pHead->_iMaxDataSize)/2 + sizeof(Block::tagBlockHead);
  1230. //Hash个数
  1231. size_t iHashCount = (iSize - sizeof(TC_MemChunkAllocator::tagChunkAllocatorHead)) / ((size_t)(iBlockSize*_fRadio) + sizeof(tagHashItem));
  1232. //采用最近的素数作为hash值
  1233. iHashCount = getMinPrimeNumber(iHashCount);
  1234. void *pHashAddr = (char*)_pHead + sizeof(tagMapHead) + sizeof(tagModifyHead);
  1235. size_t iHashMemSize = TC_MemVector<tagHashItem>::calcMemSize(iHashCount);
  1236. _hash.create(pHashAddr, iHashMemSize);
  1237. void *pDataAddr = (char*)pHashAddr + _hash.getMemSize();
  1238. _pDataAllocator->create(pDataAddr, iSize - ((char*)pDataAddr - (char*)_pHead), sizeof(Block::tagBlockHead) + _pHead->_iMinDataSize, sizeof(Block::tagBlockHead) + _pHead->_iMaxDataSize, _pHead->_fFactor);
  1239. }
  1240. void TC_HashMap::connect(void *pAddr, size_t iSize)
  1241. {
  1242. init(pAddr);
  1243. if(_pHead->_cMaxVersion != MAX_VERSION || _pHead->_cMinVersion != MIN_VERSION)
  1244. {
  1245. ostringstream os;
  1246. os << (int)_pHead->_cMaxVersion << "." << (int)_pHead->_cMinVersion << " != " << ((int)MAX_VERSION) << "." << ((int)MIN_VERSION);
  1247. throw TC_HashMap_Exception("[TC_HashMap::connect] hash map version not equal:" + os.str() + " (data != code)");
  1248. }
  1249. if(_pHead->_iMemSize != iSize)
  1250. {
  1251. throw TC_HashMap_Exception("[TC_HashMap::connect] hash map size not equal:" + TC_Common::tostr(_pHead->_iMemSize) + "!=" + TC_Common::tostr(iSize));
  1252. }
  1253. void *pHashAddr = (char*)_pHead + sizeof(tagMapHead) + sizeof(tagModifyHead);
  1254. _hash.connect(pHashAddr);
  1255. void *pDataAddr = (char*)pHashAddr + _hash.getMemSize();
  1256. _pDataAllocator->connect(pDataAddr);
  1257. _iMinDataSize = _pHead->_iMinDataSize;
  1258. _iMaxDataSize = _pHead->_iMaxDataSize;
  1259. _fFactor = _pHead->_fFactor;
  1260. _fRadio = _pHead->_fRadio;
  1261. }
  1262. int TC_HashMap::append(void *pAddr, size_t iSize)
  1263. {
  1264. if(iSize <= _pHead->_iMemSize)
  1265. {
  1266. return -1;
  1267. }
  1268. init(pAddr);
  1269. if(_pHead->_cMaxVersion != MAX_VERSION || _pHead->_cMinVersion != MIN_VERSION)
  1270. {
  1271. ostringstream os;
  1272. os << (int)_pHead->_cMaxVersion << "." << (int)_pHead->_cMinVersion << " != " << ((int)MAX_VERSION) << "." << ((int)MIN_VERSION);
  1273. throw TC_HashMap_Exception("[TC_HashMap::append] hash map version not equal:" + os.str() + " (data != code)");
  1274. }
  1275. _pHead->_iMemSize = iSize;
  1276. void *pHashAddr = (char*)_pHead + sizeof(tagMapHead) + sizeof(tagModifyHead);
  1277. _hash.connect(pHashAddr);
  1278. void *pDataAddr = (char*)pHashAddr + _hash.getMemSize();
  1279. _pDataAllocator->append(pDataAddr, iSize - ((size_t)pDataAddr - (size_t)pAddr));
  1280. _iMinDataSize = _pHead->_iMinDataSize;
  1281. _iMaxDataSize = _pHead->_iMaxDataSize;
  1282. _fFactor = _pHead->_fFactor;
  1283. _fRadio = _pHead->_fRadio;
  1284. return 0;
  1285. }
  1286. void TC_HashMap::clear()
  1287. {
  1288. assert(_pHead);
  1289. _pHead->_iElementCount = 0;
  1290. _pHead->_iSetHead = 0;
  1291. _pHead->_iSetTail = 0;
  1292. _pHead->_iGetHead = 0;
  1293. _pHead->_iGetTail = 0;
  1294. _pHead->_iDirtyCount = 0;
  1295. _pHead->_iDirtyTail = 0;
  1296. _pHead->_iUsedChunk = 0;
  1297. _pHead->_iGetCount = 0;
  1298. _pHead->_iHitCount = 0;
  1299. _pHead->_iBackupTail = 0;
  1300. _pHead->_iSyncTail = 0;
  1301. _hash.clear();
  1302. _pDataAllocator->rebuild();
  1303. }
  1304. int TC_HashMap::dump2file(const string &sFile)
  1305. {
  1306. FILE *fp = fopen(sFile.c_str(), "wb");
  1307. if(fp == NULL)
  1308. {
  1309. return RT_DUMP_FILE_ERR;
  1310. }
  1311. size_t ret = fwrite((void*)_pHead, 1, _pHead->_iMemSize, fp);
  1312. fclose(fp);
  1313. if(ret == _pHead->_iMemSize)
  1314. {
  1315. return RT_OK;
  1316. }
  1317. return RT_DUMP_FILE_ERR;
  1318. }
  1319. int TC_HashMap::load5file(const string &sFile)
  1320. {
  1321. FILE *fp = fopen(sFile.c_str(), "rb");
  1322. if(fp == NULL)
  1323. {
  1324. return RT_LOAL_FILE_ERR;
  1325. }
  1326. fseek(fp, 0L, SEEK_END);
  1327. size_t fs = ftell(fp);
  1328. if(fs != _pHead->_iMemSize)
  1329. {
  1330. fclose(fp);
  1331. return RT_LOAL_FILE_ERR;
  1332. }
  1333. fseek(fp, 0L, SEEK_SET);
  1334. size_t iSize = 1024*1024*10;
  1335. size_t iLen = 0;
  1336. char *pBuffer = new char[iSize];
  1337. bool bEof = false;
  1338. while(true)
  1339. {
  1340. int ret = fread(pBuffer, 1, iSize, fp);
  1341. if(ret != (int)iSize)
  1342. {
  1343. if(feof(fp))
  1344. {
  1345. bEof = true;
  1346. }
  1347. else
  1348. {
  1349. fclose(fp);
  1350. delete[] pBuffer;
  1351. return RT_LOAL_FILE_ERR;
  1352. }
  1353. }
  1354. //检查版本
  1355. if(iLen == 0)
  1356. {
  1357. if(pBuffer[0] != MAX_VERSION || pBuffer[1] != MIN_VERSION)
  1358. {
  1359. fclose(fp);
  1360. delete[] pBuffer;
  1361. return RT_VERSION_MISMATCH_ERR;
  1362. }
  1363. }
  1364. memcpy((char*)_pHead + iLen, pBuffer, ret);
  1365. iLen += ret;
  1366. if(bEof)
  1367. break;
  1368. }
  1369. fclose(fp);
  1370. delete[] pBuffer;
  1371. if(iLen == _pHead->_iMemSize)
  1372. {
  1373. return RT_OK;
  1374. }
  1375. return RT_LOAL_FILE_ERR;
  1376. }
  1377. int TC_HashMap::recover(size_t i, bool bRepair)
  1378. {
  1379. doUpdate();
  1380. if( i >= _hash.size())
  1381. {
  1382. return 0;
  1383. }
  1384. size_t e = 0;
  1385. check:
  1386. size_t iAddr = item(i)->_iBlockAddr;
  1387. Block block(this, iAddr);
  1388. while(block.getHead() != 0)
  1389. {
  1390. BlockData data;
  1391. int ret = block.getBlockData(data);
  1392. if(ret != TC_HashMap::RT_OK && ret != TC_HashMap::RT_ONLY_KEY)
  1393. {
  1394. //增加删除block数
  1395. ++e;
  1396. if(bRepair)
  1397. {
  1398. block.erase();
  1399. goto check;
  1400. }
  1401. }
  1402. if(!block.nextBlock())
  1403. {
  1404. break;
  1405. }
  1406. }
  1407. return e;
  1408. }
  1409. int TC_HashMap::checkDirty(const string &k)
  1410. {
  1411. doUpdate();
  1412. incGetCount();
  1413. int ret = TC_HashMap::RT_OK;
  1414. size_t index = hashIndex(k);
  1415. lock_iterator it= find(k, index, ret);
  1416. if(ret != TC_HashMap::RT_OK)
  1417. {
  1418. return ret;
  1419. }
  1420. //没有数据
  1421. if(it == end())
  1422. {
  1423. return TC_HashMap::RT_NO_DATA;
  1424. }
  1425. //只有Key
  1426. if(it->isOnlyKey())
  1427. {
  1428. return TC_HashMap::RT_ONLY_KEY;
  1429. }
  1430. Block block(this, it->getAddr());
  1431. if (block.isDirty())
  1432. {
  1433. return TC_HashMap::RT_DIRTY_DATA;
  1434. }
  1435. return TC_HashMap::RT_OK;
  1436. }
  1437. int TC_HashMap::setDirty(const string& k)
  1438. {
  1439. doUpdate();
  1440. if(_pHead->_bReadOnly) return RT_READONLY;
  1441. incGetCount();
  1442. int ret = TC_HashMap::RT_OK;
  1443. size_t index = hashIndex(k);
  1444. lock_iterator it= find(k, index, ret);
  1445. if(ret != TC_HashMap::RT_OK)
  1446. {
  1447. return ret;
  1448. }
  1449. //没有数据或只有Key
  1450. if(it == end())
  1451. {
  1452. return TC_HashMap::RT_NO_DATA;
  1453. }
  1454. //只有Key
  1455. if(it->isOnlyKey())
  1456. {
  1457. return TC_HashMap::RT_ONLY_KEY;
  1458. }
  1459. Block block(this, it->getAddr());
  1460. block.setDirty(true);
  1461. block.refreshSetList();
  1462. return TC_HashMap::RT_OK;
  1463. }
  1464. int TC_HashMap::setDirtyAfterSync(const string& k)
  1465. {
  1466. doUpdate();
  1467. if(_pHead->_bReadOnly) return RT_READONLY;
  1468. incGetCount();
  1469. int ret = TC_HashMap::RT_OK;
  1470. size_t index = hashIndex(k);
  1471. lock_iterator it= find(k, index, ret);
  1472. if(ret != TC_HashMap::RT_OK)
  1473. {
  1474. return ret;
  1475. }
  1476. //没有数据或只有Key
  1477. if(it == end())
  1478. {
  1479. return TC_HashMap::RT_NO_DATA;
  1480. }
  1481. //只有Key
  1482. if(it->isOnlyKey())
  1483. {
  1484. return TC_HashMap::RT_ONLY_KEY;
  1485. }
  1486. Block block(this, it->getAddr());
  1487. block.setDirty(true);
  1488. if(_pHead->_iDirtyTail == block.getBlockHead()->_iSetPrev)
  1489. {
  1490. _pHead->_iDirtyTail = block.getHead();
  1491. }
  1492. return TC_HashMap::RT_OK;
  1493. }
  1494. int TC_HashMap::setClean(const string& k)
  1495. {
  1496. doUpdate();
  1497. if(_pHead->_bReadOnly) return RT_READONLY;
  1498. incGetCount();
  1499. int ret = TC_HashMap::RT_OK;
  1500. size_t index = hashIndex(k);
  1501. lock_iterator it= find(k, index, ret);
  1502. if(ret != TC_HashMap::RT_OK)
  1503. {
  1504. return ret;
  1505. }
  1506. //没有数据或只有Key
  1507. if(it == end())
  1508. {
  1509. return TC_HashMap::RT_NO_DATA;
  1510. }
  1511. //只有Key
  1512. if(it->isOnlyKey())
  1513. {
  1514. return TC_HashMap::RT_ONLY_KEY;
  1515. }
  1516. Block block(this, it->getAddr());
  1517. block.setDirty(false);
  1518. block.refreshSetList();
  1519. doUpdate(true);
  1520. return TC_HashMap::RT_OK;
  1521. }
  1522. int TC_HashMap::get(const string& k, string &v, time_t &iSyncTime)
  1523. {
  1524. doUpdate();
  1525. incGetCount();
  1526. int ret = TC_HashMap::RT_OK;
  1527. size_t index = hashIndex(k);
  1528. lock_iterator it = find(k, index, v, ret);
  1529. if(ret != TC_HashMap::RT_OK && ret != TC_HashMap::RT_ONLY_KEY)
  1530. {
  1531. return ret;
  1532. }
  1533. //没有数据
  1534. if(it == end())
  1535. {
  1536. return TC_HashMap::RT_NO_DATA;
  1537. }
  1538. //只有Key
  1539. if(it->isOnlyKey())
  1540. {
  1541. return TC_HashMap::RT_ONLY_KEY;
  1542. }
  1543. Block block(this, it->getAddr());
  1544. iSyncTime = block.getSyncTime();
  1545. //如果只读, 则不刷新get链表
  1546. if(!_pHead->_bReadOnly)
  1547. {
  1548. block.refreshGetList();
  1549. }
  1550. return TC_HashMap::RT_OK;
  1551. }
  1552. int TC_HashMap::get(const string& k, string &v)
  1553. {
  1554. time_t iSyncTime;
  1555. return get(k, v, iSyncTime);
  1556. }
  1557. int TC_HashMap::set(const string& k, const string& v, bool bDirty, vector<BlockData> &vtData)
  1558. {
  1559. doUpdate();
  1560. incGetCount();
  1561. if(_pHead->_bReadOnly) return RT_READONLY;
  1562. int ret = TC_HashMap::RT_OK;
  1563. size_t index = hashIndex(k);
  1564. lock_iterator it = find(k, index, ret);
  1565. bool bNewBlock = false;
  1566. if(ret != TC_HashMap::RT_OK)
  1567. {
  1568. return ret;
  1569. }
  1570. if(it == end())
  1571. {
  1572. TC_PackIn pi;
  1573. pi << k;
  1574. pi << v;
  1575. size_t iAllocSize = sizeof(Block::tagBlockHead) + pi.length();
  1576. //先分配空间, 并获得淘汰的数据
  1577. size_t iAddr = _pDataAllocator->allocateMemBlock(index, iAllocSize, vtData);
  1578. if(iAddr == 0)
  1579. {
  1580. return TC_HashMap::RT_NO_MEMORY;
  1581. }
  1582. it = HashMapLockIterator(this, iAddr, HashMapLockIterator::IT_BLOCK, HashMapLockIterator::IT_NEXT);
  1583. bNewBlock = true;
  1584. }
  1585. ret = it->set(k, v, vtData);
  1586. if(ret != TC_HashMap::RT_OK)
  1587. {
  1588. //新记录, 写失败了, 要删除该块
  1589. if(bNewBlock)
  1590. {
  1591. Block block(this, it->getAddr());
  1592. block.erase();
  1593. }
  1594. return ret;
  1595. }
  1596. Block block(this, it->getAddr());
  1597. if(bNewBlock)
  1598. {
  1599. block.setSyncTime(time(NULL));
  1600. }
  1601. block.setDirty(bDirty);
  1602. block.refreshSetList();
  1603. return TC_HashMap::RT_OK;
  1604. }
  1605. int TC_HashMap::set(const string& k, vector<BlockData> &vtData)
  1606. {
  1607. doUpdate();
  1608. incGetCount();
  1609. if(_pHead->_bReadOnly) return RT_READONLY;
  1610. int ret = TC_HashMap::RT_OK;
  1611. size_t index = hashIndex(k);
  1612. lock_iterator it = find(k, index, ret);
  1613. bool bNewBlock = false;
  1614. if(ret != TC_HashMap::RT_OK)
  1615. {
  1616. return ret;
  1617. }
  1618. if(it == end())
  1619. {
  1620. TC_PackIn pi;
  1621. pi << k;
  1622. size_t iAllocSize = sizeof(Block::tagBlockHead) + pi.length();
  1623. //先分配空间, 并获得淘汰的数据
  1624. size_t iAddr = _pDataAllocator->allocateMemBlock(index, iAllocSize, vtData);
  1625. if(iAddr == 0)
  1626. {
  1627. return TC_HashMap::RT_NO_MEMORY;
  1628. }
  1629. it = HashMapLockIterator(this, iAddr, HashMapLockIterator::IT_BLOCK, HashMapLockIterator::IT_NEXT);
  1630. bNewBlock = true;
  1631. }
  1632. ret = it->set(k, vtData);
  1633. if(ret != TC_HashMap::RT_OK)
  1634. {
  1635. //新记录, 写失败了, 要删除该块
  1636. if(bNewBlock)
  1637. {
  1638. Block block(this, it->getAddr());
  1639. block.erase();
  1640. }
  1641. return ret;
  1642. }
  1643. Block block(this, it->getAddr());
  1644. if(bNewBlock)
  1645. {
  1646. block.setSyncTime(time(NULL));
  1647. }
  1648. block.refreshSetList();
  1649. return TC_HashMap::RT_OK;
  1650. }
  1651. int TC_HashMap::del(const string& k, BlockData &data)
  1652. {
  1653. doUpdate();
  1654. incGetCount();
  1655. if(_pHead->_bReadOnly) return RT_READONLY;
  1656. int ret = TC_HashMap::RT_OK;
  1657. size_t index = hashIndex(k);
  1658. data._key = k;
  1659. lock_iterator it = find(k, index, data._value, ret);
  1660. if(ret != TC_HashMap::RT_OK && ret != TC_HashMap::RT_ONLY_KEY)
  1661. {
  1662. return ret;
  1663. }
  1664. if(it == end())
  1665. {
  1666. return TC_HashMap::RT_NO_DATA;
  1667. }
  1668. Block block(this, it->getAddr());
  1669. ret = block.getBlockData(data);
  1670. block.erase();
  1671. return ret;
  1672. }
  1673. int TC_HashMap::erase(int radio, BlockData &data, bool bCheckDirty)
  1674. {
  1675. doUpdate();
  1676. if(_pHead->_bReadOnly) return RT_READONLY;
  1677. if(radio <= 0) radio = 1;
  1678. if(radio >= 100) radio = 100;
  1679. size_t iAddr = _pHead->_iGetTail;
  1680. //到链表头部
  1681. if(iAddr == 0)
  1682. {
  1683. return RT_OK;
  1684. }
  1685. //删除到指定比率了
  1686. if((_pHead->_iUsedChunk * 100. / allBlockChunkCount()) < radio)
  1687. {
  1688. return RT_OK;
  1689. }
  1690. Block block(this, iAddr);
  1691. if(bCheckDirty)
  1692. {
  1693. if(block.isDirty())
  1694. {
  1695. if(_pHead->_iDirtyTail == 0)
  1696. {
  1697. _pHead->_iDirtyTail = iAddr;
  1698. }
  1699. // 将脏数据移动到get链的头部,使可以继续淘汰
  1700. if(_pHead->_iGetHead == iAddr)
  1701. {
  1702. // 既是头也是尾,只有一个元素了
  1703. return RT_OK;
  1704. }
  1705. if(block._pMap->_pHead->_iBackupTail == block._iHead)
  1706. {
  1707. update(&block._pMap->_pHead->_iBackupTail, block.getBlockHead()->_iGetPrev);
  1708. }
  1709. // 将GetTail上移
  1710. update(&_pHead->_iGetTail, block.getBlockHead()->_iGetPrev);
  1711. // 从Get尾部移除
  1712. update(&block.getBlockHead(block.getBlockHead()->_iGetPrev)->_iGetNext, (size_t)0);
  1713. update(&block.getBlockHead()->_iGetPrev, (size_t)0);
  1714. // 移到Get头部
  1715. update(&block.getBlockHead()->_iGetNext, _pHead->_iGetHead);
  1716. update(&block.getBlockHead(_pHead->_iGetHead)->_iGetPrev, iAddr);
  1717. update(&_pHead->_iGetHead, iAddr);
  1718. doUpdate(true);
  1719. return RT_DIRTY_DATA;
  1720. }
  1721. }
  1722. int ret = block.getBlockData(data);
  1723. block.erase();
  1724. if(ret == TC_HashMap::RT_OK)
  1725. {
  1726. return TC_HashMap::RT_ERASE_OK;
  1727. }
  1728. return ret;
  1729. }
  1730. void TC_HashMap::sync()
  1731. {
  1732. doUpdate();
  1733. _pHead->_iSyncTail = _pHead->_iDirtyTail;
  1734. }
  1735. int TC_HashMap::sync(time_t iNowTime, BlockData &data)
  1736. {
  1737. doUpdate();
  1738. size_t iAddr = _pHead->_iSyncTail;
  1739. //到链表头部了, 返回RT_OK
  1740. if(iAddr == 0)
  1741. {
  1742. return RT_OK;
  1743. }
  1744. Block block(this, iAddr);
  1745. _pHead->_iSyncTail = block.getBlockHead()->_iSetPrev;
  1746. //当前数据是干净数据
  1747. if( !block.isDirty())
  1748. {
  1749. if(_pHead->_iDirtyTail == iAddr)
  1750. {
  1751. _pHead->_iDirtyTail = block.getBlockHead()->_iSetPrev;
  1752. }
  1753. return RT_NONEED_SYNC;
  1754. }
  1755. int ret = block.getBlockData(data);
  1756. if(ret != TC_HashMap::RT_OK)
  1757. {
  1758. //没有获取完整的记录
  1759. if(_pHead->_iDirtyTail == iAddr)
  1760. {
  1761. _pHead->_iDirtyTail = block.getBlockHead()->_iSetPrev;
  1762. }
  1763. return ret;
  1764. }
  1765. //脏数据且超过_pHead->_iSyncTime没有回写, 需要回写
  1766. if(_pHead->_iSyncTime + data._synct < iNowTime && block.isDirty())
  1767. {
  1768. block.setDirty(false);
  1769. block.setSyncTime(iNowTime);
  1770. if(_pHead->_iDirtyTail == iAddr)
  1771. {
  1772. _pHead->_iDirtyTail = block.getBlockHead()->_iSetPrev;
  1773. }
  1774. return RT_NEED_SYNC;
  1775. }
  1776. //脏数据, 但是不需要回写, 脏链表不往前推
  1777. return RT_NONEED_SYNC;
  1778. }
  1779. void TC_HashMap::backup(bool bForceFromBegin)
  1780. {
  1781. doUpdate();
  1782. if(bForceFromBegin || _pHead->_iBackupTail == 0)
  1783. {
  1784. //移动备份指针到Get链尾部, 准备开始备份数据
  1785. _pHead->_iBackupTail = _pHead->_iGetTail;
  1786. }
  1787. }
  1788. int TC_HashMap::backup(BlockData &data)
  1789. {
  1790. doUpdate();
  1791. size_t iAddr = _pHead->_iBackupTail;
  1792. //到链表头部了, 返回RT_OK
  1793. if(iAddr == 0)
  1794. {
  1795. return RT_OK;
  1796. }
  1797. Block block(this, iAddr);
  1798. int ret = block.getBlockData(data);
  1799. //迁移一次
  1800. _pHead->_iBackupTail = block.getBlockHead()->_iGetPrev;
  1801. doUpdate(true);
  1802. if(ret == TC_HashMap::RT_OK)
  1803. {
  1804. return TC_HashMap::RT_NEED_BACKUP;
  1805. }
  1806. return ret;
  1807. }
  1808. TC_HashMap::lock_iterator TC_HashMap::find(const string& k)
  1809. {
  1810. size_t index = hashIndex(k);
  1811. int ret = TC_HashMap::RT_OK;
  1812. doUpdate();
  1813. if(item(index)->_iBlockAddr == 0)
  1814. {
  1815. return end();
  1816. }
  1817. Block mb(this, item(index)->_iBlockAddr);
  1818. while(true)
  1819. {
  1820. HashMapLockItem mcmdi(this, mb.getHead());
  1821. if(mcmdi.equal(k, ret))
  1822. {
  1823. incHitCount();
  1824. return lock_iterator(this, mb.getHead(), lock_iterator::IT_BLOCK, lock_iterator::IT_NEXT);
  1825. }
  1826. if (!mb.nextBlock())
  1827. {
  1828. return end();
  1829. }
  1830. }
  1831. return end();
  1832. }
  1833. TC_HashMap::lock_iterator TC_HashMap::begin()
  1834. {
  1835. doUpdate();
  1836. for(size_t i = 0; i < _hash.size(); i++)
  1837. {
  1838. tagHashItem &hashItem = _hash[i];
  1839. if(hashItem._iBlockAddr != 0)
  1840. {
  1841. return lock_iterator(this, hashItem._iBlockAddr, lock_iterator::IT_BLOCK, lock_iterator::IT_NEXT);
  1842. }
  1843. }
  1844. return end();
  1845. }
  1846. TC_HashMap::lock_iterator TC_HashMap::rbegin()
  1847. {
  1848. doUpdate();
  1849. for(size_t i = _hash.size(); i > 0; i--)
  1850. {
  1851. tagHashItem &hashItem = _hash[i-1];
  1852. if(hashItem._iBlockAddr != 0)
  1853. {
  1854. Block block(this, hashItem._iBlockAddr);
  1855. return lock_iterator(this, block.getLastBlockHead(), lock_iterator::IT_BLOCK, lock_iterator::IT_PREV);
  1856. }
  1857. }
  1858. return end();
  1859. }
  1860. TC_HashMap::lock_iterator TC_HashMap::beginSetTime()
  1861. {
  1862. doUpdate();
  1863. return lock_iterator(this, _pHead->_iSetHead, lock_iterator::IT_SET, lock_iterator::IT_NEXT);
  1864. }
  1865. TC_HashMap::lock_iterator TC_HashMap::rbeginSetTime()
  1866. {
  1867. doUpdate();
  1868. return lock_iterator(this, _pHead->_iSetTail, lock_iterator::IT_SET, lock_iterator::IT_PREV);
  1869. }
  1870. TC_HashMap::lock_iterator TC_HashMap::beginGetTime()
  1871. {
  1872. doUpdate();
  1873. return lock_iterator(this, _pHead->_iGetHead, lock_iterator::IT_GET, lock_iterator::IT_NEXT);
  1874. }
  1875. TC_HashMap::lock_iterator TC_HashMap::rbeginGetTime()
  1876. {
  1877. doUpdate();
  1878. return lock_iterator(this, _pHead->_iGetTail, lock_iterator::IT_GET, lock_iterator::IT_PREV);
  1879. }
  1880. TC_HashMap::lock_iterator TC_HashMap::beginDirty()
  1881. {
  1882. doUpdate();
  1883. return lock_iterator(this, _pHead->_iDirtyTail, lock_iterator::IT_SET, lock_iterator::IT_PREV);
  1884. }
  1885. TC_HashMap::hash_iterator TC_HashMap::hashBegin()
  1886. {
  1887. doUpdate();
  1888. return hash_iterator(this, 0);
  1889. }
  1890. TC_HashMap::hash_iterator TC_HashMap::hashIndex(size_t iIndex)
  1891. {
  1892. doUpdate();
  1893. return hash_iterator(this, iIndex);
  1894. }
  1895. /////////////////////////////////////////////////////////////////////////////////////////////////////////
  1896. string TC_HashMap::desc()
  1897. {
  1898. ostringstream s;
  1899. {
  1900. s << "[Version = " << (int)_pHead->_cMaxVersion << "." << (int)_pHead->_cMinVersion << "]" << endl;
  1901. s << "[ReadOnly = " << _pHead->_bReadOnly << "]" << endl;
  1902. s << "[AutoErase = " << _pHead->_bAutoErase << "]" << endl;
  1903. s << "[MemSize = " << _pHead->_iMemSize << "]" << endl;
  1904. s << "[Capacity = " << _pDataAllocator->getCapacity() << "]" << endl;
  1905. s << "[SingleBlockCount = " << TC_Common::tostr(singleBlockChunkCount()) << "]" << endl;
  1906. s << "[AllBlockChunk = " << allBlockChunkCount() << "]" << endl;
  1907. s << "[UsedChunk = " << _pHead->_iUsedChunk << "]" << endl;
  1908. s << "[FreeChunk = " << allBlockChunkCount() - _pHead->_iUsedChunk << "]" << endl;
  1909. s << "[MinDataSize = " << _pHead->_iMinDataSize << "]" << endl;
  1910. s << "[MaxDataSize = " << _pHead->_iMaxDataSize << "]" << endl;
  1911. s << "[HashCount = " << _hash.size() << "]" << endl;
  1912. s << "[HashRadio = " << _pHead->_fRadio << "]" << endl;
  1913. s << "[ElementCount = " << _pHead->_iElementCount << "]" << endl;
  1914. s << "[SetHead = " << _pHead->_iSetHead << "]" << endl;
  1915. s << "[SetTail = " << _pHead->_iSetTail << "]" << endl;
  1916. s << "[GetHead = " << _pHead->_iGetHead << "]" << endl;
  1917. s << "[GetTail = " << _pHead->_iGetTail << "]" << endl;
  1918. s << "[DirtyTail = " << _pHead->_iDirtyTail << "]" << endl;
  1919. s << "[SyncTail = " << _pHead->_iSyncTail << "]" << endl;
  1920. s << "[SyncTime = " << _pHead->_iSyncTime << "]" << endl;
  1921. s << "[BackupTail = " << _pHead->_iBackupTail << "]" << endl;
  1922. s << "[DirtyCount = " << _pHead->_iDirtyCount << "]" << endl;
  1923. s << "[GetCount = " << _pHead->_iGetCount << "]" << endl;
  1924. s << "[HitCount = " << _pHead->_iHitCount << "]" << endl;
  1925. s << "[ModifyStatus = " << (int)_pstModifyHead->_cModifyStatus << "]" << endl;
  1926. s << "[ModifyIndex = " << _pstModifyHead->_iNowIndex << "]" << endl;
  1927. s << "[OnlyKeyCount = " << _pHead->_iOnlyKeyCount << "]" << endl;
  1928. }
  1929. uint32_t iMaxHash;
  1930. uint32_t iMinHash;
  1931. float fAvgHash;
  1932. analyseHash(iMaxHash, iMinHash, fAvgHash);
  1933. {
  1934. s << "[MaxHash = " << iMaxHash << "]" << endl;
  1935. s << "[MinHash = " << iMinHash << "]" << endl;
  1936. s << "[AvgHash = " << fAvgHash << "]" << endl;
  1937. }
  1938. vector<TC_MemChunk::tagChunkHead> vChunkHead = _pDataAllocator->getBlockDetail();
  1939. s << "*************************************************************************" << endl;
  1940. s << "[DiffBlockCount = " << vChunkHead.size() << "]" << endl;
  1941. for(size_t i = 0; i < vChunkHead.size(); i++)
  1942. {
  1943. s << "[BlockSize = " << vChunkHead[i]._iBlockSize << "]";
  1944. s << "[BlockCount = " << vChunkHead[i]._iBlockCount << "]";
  1945. s << "[BlockAvailable = " << vChunkHead[i]._blockAvailable << "]" << endl;
  1946. }
  1947. return s.str();
  1948. }
  1949. size_t TC_HashMap::eraseExcept(size_t iNowAddr, vector<BlockData> &vtData)
  1950. {
  1951. //不能被淘汰
  1952. if(!_pHead->_bAutoErase) return 0;
  1953. size_t n = _pHead->_iEraseCount;
  1954. if(n == 0) n = 10;
  1955. size_t d = n;
  1956. while (d != 0)
  1957. {
  1958. size_t iAddr;
  1959. //判断按照哪种方式淘汰
  1960. if(_pHead->_cEraseMode == TC_HashMap::ERASEBYSET)
  1961. {
  1962. iAddr = _pHead->_iSetTail;
  1963. }
  1964. else
  1965. {
  1966. iAddr = _pHead->_iGetTail;
  1967. }
  1968. if (iAddr == 0)
  1969. {
  1970. break;
  1971. }
  1972. Block block(this, iAddr);
  1973. //当前block正在分配空间, 不能删除, 移到上一个数据
  1974. if (iNowAddr == iAddr)
  1975. {
  1976. if(_pHead->_cEraseMode == TC_HashMap::ERASEBYSET)
  1977. {
  1978. iAddr = block.getBlockHead()->_iSetPrev;
  1979. }
  1980. else
  1981. {
  1982. iAddr = block.getBlockHead()->_iGetPrev;
  1983. }
  1984. }
  1985. if(iAddr == 0)
  1986. {
  1987. break;
  1988. }
  1989. Block block1(this, iAddr);
  1990. BlockData data;
  1991. int ret = block1.getBlockData(data);
  1992. if(ret == TC_HashMap::RT_OK)
  1993. {
  1994. vtData.push_back(data);
  1995. d--;
  1996. }
  1997. else if(ret == TC_HashMap::RT_NO_DATA)
  1998. {
  1999. d--;
  2000. }
  2001. //删除数据
  2002. block1.erase();
  2003. }
  2004. return n-d;
  2005. }
  2006. size_t TC_HashMap::hashIndex(const string& k)
  2007. {
  2008. return _hashf(k) % _hash.size();
  2009. }
  2010. TC_HashMap::lock_iterator TC_HashMap::find(const string& k, size_t index, string &v, int &ret)
  2011. {
  2012. ret = TC_HashMap::RT_OK;
  2013. if(item(index)->_iBlockAddr == 0)
  2014. {
  2015. return end();
  2016. }
  2017. Block mb(this, item(index)->_iBlockAddr);
  2018. while(true)
  2019. {
  2020. HashMapLockItem mcmdi(this, mb.getHead());
  2021. if(mcmdi.equal(k, v, ret))
  2022. {
  2023. incHitCount();
  2024. return lock_iterator(this, mb.getHead(), lock_iterator::IT_BLOCK, lock_iterator::IT_NEXT);
  2025. }
  2026. if (!mb.nextBlock())
  2027. {
  2028. return end();
  2029. }
  2030. }
  2031. return end();
  2032. }
  2033. TC_HashMap::lock_iterator TC_HashMap::find(const string& k, size_t index, int &ret)
  2034. {
  2035. ret = TC_HashMap::RT_OK;
  2036. if(item(index)->_iBlockAddr == 0)
  2037. {
  2038. return end();
  2039. }
  2040. Block mb(this, item(index)->_iBlockAddr);
  2041. while(true)
  2042. {
  2043. HashMapLockItem mcmdi(this, mb.getHead());
  2044. if(mcmdi.equal(k, ret))
  2045. {
  2046. incHitCount();
  2047. return lock_iterator(this, mb.getHead(), lock_iterator::IT_BLOCK, lock_iterator::IT_NEXT);
  2048. }
  2049. if (!mb.nextBlock())
  2050. {
  2051. return end();
  2052. }
  2053. }
  2054. return end();
  2055. }
  2056. void TC_HashMap::analyseHash(uint32_t &iMaxHash, uint32_t &iMinHash, float &fAvgHash)
  2057. {
  2058. iMaxHash = 0;
  2059. iMinHash = (uint32_t)-1;
  2060. fAvgHash = 0;
  2061. uint32_t n = 0;
  2062. for(uint32_t i = 0; i < _hash.size(); i++)
  2063. {
  2064. iMaxHash = max(_hash[i]._iListCount, iMaxHash);
  2065. iMinHash = min(_hash[i]._iListCount, iMinHash);
  2066. //平均值只统计非0的
  2067. if(_hash[i]._iListCount != 0)
  2068. {
  2069. n++;
  2070. fAvgHash += _hash[i]._iListCount;
  2071. }
  2072. }
  2073. if(n != 0)
  2074. {
  2075. fAvgHash = fAvgHash / n;
  2076. }
  2077. }
  2078. void TC_HashMap::doUpdate(bool bUpdate)
  2079. {
  2080. if(bUpdate)
  2081. {
  2082. _pstModifyHead->_cModifyStatus = 2;
  2083. }
  2084. //==1, copy过程中, 程序失败, 需要清除状态
  2085. if(_pstModifyHead->_cModifyStatus == 1)
  2086. {
  2087. _pstModifyHead->_iNowIndex = 0;
  2088. for(size_t i = 0; i < sizeof(_pstModifyHead->_stModifyData) / sizeof(tagModifyData); i++)
  2089. {
  2090. _pstModifyHead->_stModifyData[i]._iModifyAddr = 0;
  2091. _pstModifyHead->_stModifyData[i]._cBytes = 0;
  2092. _pstModifyHead->_stModifyData[i]._iModifyValue = 0;
  2093. }
  2094. _pstModifyHead->_cModifyStatus = 0;
  2095. }
  2096. //==2, 已经修改成功, 但是没有copy到内存中, 需要更新到内存中
  2097. else if(_pstModifyHead->_cModifyStatus == 2)
  2098. {
  2099. for(size_t i = 0; i < _pstModifyHead->_iNowIndex; i++)
  2100. {
  2101. if(_pstModifyHead->_stModifyData[i]._cBytes == sizeof(size_t))
  2102. {
  2103. *(size_t*)((char*)_pHead + _pstModifyHead->_stModifyData[i]._iModifyAddr) = _pstModifyHead->_stModifyData[i]._iModifyValue;
  2104. }
  2105. #if __WORDSIZE == 64 || defined _WIN64
  2106. else if(_pstModifyHead->_stModifyData[i]._cBytes == sizeof(uint32_t))
  2107. {
  2108. *(uint32_t*)((char*)_pHead + _pstModifyHead->_stModifyData[i]._iModifyAddr) = (uint32_t)_pstModifyHead->_stModifyData[i]._iModifyValue;
  2109. }
  2110. #endif
  2111. else if(_pstModifyHead->_stModifyData[i]._cBytes == sizeof(bool))
  2112. {
  2113. *(bool*)((char*)_pHead + _pstModifyHead->_stModifyData[i]._iModifyAddr) = (bool)_pstModifyHead->_stModifyData[i]._iModifyValue;
  2114. }
  2115. else
  2116. {
  2117. assert(true);
  2118. }
  2119. }
  2120. _pstModifyHead->_iNowIndex = 0;
  2121. _pstModifyHead->_cModifyStatus = 0;
  2122. }
  2123. //==0, 正常状态
  2124. else if(_pstModifyHead->_cModifyStatus == 0)
  2125. {
  2126. return;
  2127. }
  2128. }
  2129. void TC_HashMap::update(void* iModifyAddr, size_t iModifyValue)
  2130. {
  2131. _pstModifyHead->_cModifyStatus = 1;
  2132. _pstModifyHead->_stModifyData[_pstModifyHead->_iNowIndex]._iModifyAddr = getRelative(iModifyAddr);
  2133. _pstModifyHead->_stModifyData[_pstModifyHead->_iNowIndex]._iModifyValue = iModifyValue;
  2134. _pstModifyHead->_stModifyData[_pstModifyHead->_iNowIndex]._cBytes = sizeof(iModifyValue);
  2135. _pstModifyHead->_iNowIndex++;
  2136. assert(_pstModifyHead->_iNowIndex < sizeof(_pstModifyHead->_stModifyData) / sizeof(tagModifyData));
  2137. }
  2138. #if __WORDSIZE == 64 || defined _WIN64
  2139. void TC_HashMap::update(void* iModifyAddr, uint32_t iModifyValue)
  2140. {
  2141. _pstModifyHead->_cModifyStatus = 1;
  2142. _pstModifyHead->_stModifyData[_pstModifyHead->_iNowIndex]._iModifyAddr = getRelative(iModifyAddr);
  2143. _pstModifyHead->_stModifyData[_pstModifyHead->_iNowIndex]._iModifyValue = iModifyValue;
  2144. _pstModifyHead->_stModifyData[_pstModifyHead->_iNowIndex]._cBytes = sizeof(iModifyValue);
  2145. _pstModifyHead->_iNowIndex++;
  2146. assert(_pstModifyHead->_iNowIndex < sizeof(_pstModifyHead->_stModifyData) / sizeof(tagModifyData));
  2147. }
  2148. #endif
  2149. void TC_HashMap::update(void* iModifyAddr, bool bModifyValue)
  2150. {
  2151. _pstModifyHead->_cModifyStatus = 1;
  2152. _pstModifyHead->_stModifyData[_pstModifyHead->_iNowIndex]._iModifyAddr = getRelative(iModifyAddr);
  2153. _pstModifyHead->_stModifyData[_pstModifyHead->_iNowIndex]._iModifyValue = bModifyValue;
  2154. _pstModifyHead->_stModifyData[_pstModifyHead->_iNowIndex]._cBytes = sizeof(bModifyValue);
  2155. _pstModifyHead->_iNowIndex++;
  2156. assert(_pstModifyHead->_iNowIndex < sizeof(_pstModifyHead->_stModifyData) / sizeof(tagModifyData));
  2157. }
  2158. size_t TC_HashMap::getMinPrimeNumber(size_t n)
  2159. {
  2160. while(true)
  2161. {
  2162. if(TC_Common::isPrimeNumber(n))
  2163. {
  2164. return n;
  2165. }
  2166. ++n;
  2167. }
  2168. return 3;
  2169. }
  2170. }