tc_hashmap_compact.cpp 74 KB

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