tc_multi_hashmap.h 76 KB

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