jmem_hashmap.h 65 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339
  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 _JMEM_HASHMAP_H
  17. #define _JMEM_HASHMAP_H
  18. #include "util/tc_hashmap.h"
  19. #include "util/tc_autoptr.h"
  20. #include "jmem/jmem_policy.h"
  21. #include "tup/Tars.h"
  22. namespace tars
  23. {
  24. /************************************************************************
  25. 基本说明如下:
  26. 基于Tars协议的内存hashmap
  27. 编解码出错则抛出TarsDecodeException和TarsEncodeException
  28. 可以对锁策略和存储策略进行组合, 例如:
  29. 基于信号量锁, 文件存储的hashmap:
  30. TarsHashMap<Test::QueueElement, SemLockPolicy, FileStorePolicy>
  31. 基于信号量锁, 共享内存存储的hashmap
  32. TarsHashMap<Test::QueueElement, SemLockPolicy, ShmStorePolicy>
  33. 基于线程锁, 内存存储的hashmap
  34. TarsHashMap<Test::QueueElement, ThreadLockPolicy, MemStorePolicy>
  35. 使用上, 不同的组合, 初始化函数不完全一样
  36. 初始化函数有:
  37. SemLockPolicy::initLock(key_t)
  38. ShmStorePolicy::initStore(key_t, size_t)
  39. FileStorePolicy::initStore(const char *file, size_t)
  40. 等, 具体参见jmem_policy.h
  41. ***********************************************************************
  42. 基本特性说明:
  43. > 内存数据的map, 根据最后Get时间的顺序淘汰数据;
  44. > 支持缓写/dump到文件/在线备份;
  45. > 支持不同大小内存块的配置, 提供内存的使用率;
  46. > 支持回收到指定空闲比率的空间;
  47. > 支持仅设置Key的操作, 即数据无value, 只有Key, 类似与stl::set;
  48. > 支持自定义hash算法;
  49. > hash数可以根据内存块比率设置, 并优化有素数, 提高hash的散列性;
  50. > 支持几种方式的遍历, 通常遍历时需要对map加锁;
  51. > 对于hash方式的遍历, 遍历时可以不需要对map加锁, 推荐使用;
  52. > 支持自定义操作对象设置, 可以非常快速实现相关的接口;
  53. > 支持自动编解码, Key和Value的结构都通过tars2cpp生成;
  54. > tars协议支持自动扩展字段, 因此该hashmap支持自动扩展字段(Key和Value都必须是通过tars编码的);
  55. > map支持只读模式, 只读模式下set/erase/del等修改数据的操作不能使用, get/回写/在线备份正常使用
  56. > 支持自动淘汰, set时, 内存满则自动淘汰, 在非自动淘汰时, 内存满直接返回RT_READONLY
  57. > 对于mmap文件, 支持自动扩展文件, 即内存不够了, 可以自动扩展文件大小(注意hash的数量不变, 因此开始就需要考虑hash的数量), 而且不能跨JHashmap对象(即两个hashmap对象访问同一块文件,通知一个hashmap扩展以后,另外一个对象并不知道扩展了)
  58. ***********************************************************************
  59. hashmap链说明:
  60. hashmap链一共包括了如下几种链表:
  61. > Set时间链: 任何Set操作都会修改该链表, Set后数据被设置为脏数据, 且移动到Set链表头部;
  62. > Get时间链: 任何Get操作都会修改该链表, 除非链表只读, 注意Set链同时也会修改Get链
  63. > Dirty时间链: dirty链是Set链的一部分, 用于回写数据用
  64. > Backup链:备份链是Get链的一部分, 当备份数据时, 顺着Get链从尾部到头部开始备份;
  65. ***********************************************************************
  66. 相关操作说明:
  67. > 可以设置map只读, 则所有写操作返回RT_READONLY, 此时Get操作不修改链表
  68. > 可以设置知否自动淘汰, 默认是自动淘汰的.如果不自动淘汰,则set时,无内存空间返回:RT_NO_MEMORY
  69. > 可以更改hash的算法, 调用setHashFunctor即可
  70. > 可以将某条数据设置为干净, 此时移出到Dirty链表指Dirty尾部的下一个元素;
  71. > 可以将某条数据设置为脏, 此时会移动到Set链表头部;
  72. > 每个数据都有一个上次回写时间(SyncTime), 如果启动回写操作, 则在一定时间内会回写;
  73. > 可以dump到文件或者从文件中load, 这个时候会对map加锁
  74. > 可以调用erase批量淘汰数据直到内存空闲率到一定比例
  75. > 可以调用sync进行数据回写, 保证一定时间内没有回写的数据会回写, map回写时间通过setSyncTime设置, 默认10分钟
  76. > 可以setToDoFunctor设置操作类, 以下是操作触发的情况:
  77. ***********************************************************************
  78. ToDoFunctor的函数说明:
  79. > 通常继承ToDoFunctor, 实现相关函数就可以了, 可以实现以下功能:Get数据, 淘汰数据, 删除数据, 回写数据, 备份数据
  80. > ToDoFunctor::erase, 当调用map.erase时, 该函数会被调用
  81. > ToDoFunctor::del, 当调用map.del时, 该函数会被调用, 注意删除时数据可能都不在cache中;
  82. > ToDoFunctor::sync, 当调用map.sync时, 会触发每条需要回写的数据该函数都被调用一次, 在该函数中处理回写请求;
  83. > ToDoFunctor::backup, 当调用map.backup时, 会触发需要备份的数据该函数会被调用一次, 在该函数中处理备份请求;
  84. > ToDoFunctor::get, 当调用map.get时, 如果map中无数据, 则该函数被调用, 该函数从db中获取数据, 并返回RT_OK, 如果db无数据则返回RT_NO_DATA;
  85. > ToDoFunctor所有接口被调用时, 都不会对map加锁, 因此可以操作map
  86. ***********************************************************************
  87. map的重要函数说明:
  88. > set, 设置数据到map中, 会更新set链表
  89. 如果满了, 且可以自动淘汰, 则根据Get链淘汰数据, 此时ToDoFunctor的sync会被调用
  90. 如果满了, 且可以不能自动淘汰, 则返回RT_NO_MEMORY
  91. > get, 从map获取数据, 如果有数据, 则直接从map获取数据并返回RT_OK;
  92. 如果没有数据, 则调用ToDoFunctor::get函数, 此时get函数需要返回RT_OK, 同时会设置到map中, 并返回数据;
  93. 如果没有数据, 则ToDoFunctor::get函数也无数据, 则需要返回RT_NO_DATA, 此时只会把Key设置到map中, 并返回RT_ONLY_KEY;
  94. 在上面情况下, 如果再有get请求, 则不再调用ToDoFunctor::get, 直接返回RT_ONLY_KEY;
  95. > del, 删除数据, 无论cache是否有数据, ToDoFunctor::del都会被调用;
  96. 如果只有Key, 则该数据也会被删除;
  97. > erase, 淘汰数据, 只有cache存在数据, ToDoFunctor::erase才会被调用
  98. 如果只有Key, 则该数据也会被淘汰, 但是ToDoFunctor::erase不会被调用;
  99. > erase(int radio), 批量淘汰数据, 直到空闲块比率到达radio;
  100. ToDoFunctor::erase会被调用;
  101. 只有Key的记录也会被淘汰, 但是ToDoFunctor::erase不会被调用;
  102. > sync: 缓写数据, 超时没有回写且是脏数据需要回写, 回写完毕后, 数据会自动设置为干净数据;
  103. 可以多个线程或进程同时缓写;
  104. ToDoFunctor::sync会被调用;
  105. 只有Key的记录, ToDoFunctor::sync不会被调用;
  106. > backup: 备份数据, 顺着顺着Get链从尾部到头部开始备份;
  107. ToDoFunctor::backup会被调用;
  108. 只有Key的记录, ToDoFunctor::backup不会被调用;
  109. 由于备份游标只有一个, 因此多个进程同时备份的时候数据可能会每个进程有一部分
  110. 如果备份程序备份到一半down了, 则下次启动备份时会接着上次的备份进行, 除非将backup(true)调用备份
  111. ***********************************************************************
  112. 返回值说明:
  113. > 注意函数所有int的返回值, 如无特别说明, 请参见TC_HashMap::RT_
  114. ***********************************************************************
  115. 遍历说明:
  116. > 可以用lock_iterator对map进行以下几种遍历, 在遍历过程中其实对map加锁处理了
  117. > end(): 迭代器尾部
  118. > begin(): 按照block区块遍历
  119. > rbegin():按照block区块逆序遍历
  120. > beginSetTime(): 按照Set时间顺序遍历
  121. > rbeginSetTime(): 按照Set时间顺序遍历
  122. > beginGetTime(): 按照Get时间顺序遍历
  123. > rbeginGetTime(): 按照Get时间逆序遍历
  124. > beginDirty(): 按时间逆序遍历脏数据链(如果setClean, 则也可能在脏链表上)
  125. > 其实回写数据链是脏数据量的子集
  126. > 注意:lock_iterator一旦获取, 就对map加锁了, 直到lock_iterator析够为止
  127. >
  128. > 可以用hash_iterator对map进行遍历, 遍历过程中对map没有加锁, 推荐使用
  129. > hashBegin(): 获取hash遍历迭代器
  130. > hashEnd(): hash遍历尾部迭代器
  131. > 注意:hash_iterator对应的其实是一个hash桶链, 每次获取数据其实会获取桶链上面的所有数据
  132. */
  133. template<typename K,
  134. typename V,
  135. typename LockPolicy,
  136. template<class, class> class StorePolicy>
  137. class TarsHashMap : public StorePolicy<TC_HashMap, LockPolicy>
  138. {
  139. public:
  140. /**
  141. * 定义数据操作基类
  142. * 获取,遍历,删除,淘汰时都可以使用该操作类
  143. */
  144. class ToDoFunctor
  145. {
  146. public:
  147. /**
  148. * 数据记录
  149. */
  150. struct DataRecord
  151. {
  152. K _key;
  153. V _value;
  154. bool _dirty;
  155. time_t _iSyncTime;
  156. DataRecord() : _dirty(true), _iSyncTime(0)
  157. {
  158. }
  159. };
  160. /**
  161. * 析够
  162. */
  163. virtual ~ToDoFunctor(){};
  164. /**
  165. * 淘汰数据
  166. * @param stDataRecord: 被淘汰的数据
  167. */
  168. virtual void erase(const DataRecord &stDataRecord){};
  169. /**
  170. * 删除数据
  171. * @param bExists: 是否存在数据
  172. * @param stDataRecord: 数据, bExists==true时有效, 否则只有key有效
  173. */
  174. virtual void del(bool bExists, const DataRecord &stDataRecord){};
  175. /**
  176. * 回写数据
  177. * @param stDataRecord: 数据
  178. */
  179. virtual void sync(const DataRecord &stDataRecord){};
  180. /**
  181. * 备份数据
  182. * @param stDataRecord: 数据
  183. */
  184. virtual void backup(const DataRecord &stDataRecord){};
  185. /**
  186. * 获取数据, 默认返回RT_NO_GET
  187. * stDataRecord中_key有效, 其他数据需要返回
  188. * @param stDataRecord: 需要获取的数据
  189. *
  190. * @return int, 获取到数据, 返回:TC_HashMap::RT_OK
  191. * 没有数据,返回:TC_HashMap::RT_NO_DATA,
  192. * 系统默认GET,返回:TC_HashMap::RT_NO_GET
  193. * 其他,则返回:TC_HashMap::RT_LOAD_DATA_ERR
  194. */
  195. virtual int get(DataRecord &stDataRecord)
  196. {
  197. return TC_HashMap::RT_NO_GET;
  198. }
  199. };
  200. typedef typename ToDoFunctor::DataRecord DataRecord;
  201. ///////////////////////////////////////////////////////////////////
  202. /**
  203. * 自动锁, 用于迭代器
  204. */
  205. class JhmAutoLock : public TC_HandleBase
  206. {
  207. public:
  208. /**
  209. * 构造
  210. * @param mutex
  211. */
  212. JhmAutoLock(typename LockPolicy::Mutex &mutex) : _lock(mutex)
  213. {
  214. }
  215. protected:
  216. //不实现
  217. JhmAutoLock(const JhmAutoLock &al);
  218. JhmAutoLock &operator=(const JhmAutoLock &al);
  219. protected:
  220. /**
  221. * 锁
  222. */
  223. TC_LockT<typename LockPolicy::Mutex> _lock;
  224. };
  225. typedef TC_AutoPtr<JhmAutoLock> JhmAutoLockPtr;
  226. ///////////////////////////////////////////////////////////////////
  227. /**
  228. * 数据项
  229. */
  230. class JhmLockItem
  231. {
  232. public:
  233. /**
  234. * 构造函数
  235. * @param item
  236. */
  237. JhmLockItem(const TC_HashMap::HashMapLockItem &item)
  238. : _item(item)
  239. {
  240. }
  241. /**
  242. * 拷贝构造
  243. * @param it
  244. */
  245. JhmLockItem(const JhmLockItem &item)
  246. : _item(item._item)
  247. {
  248. }
  249. /**
  250. * 复制
  251. * @param it
  252. *
  253. * @return JhmLockItem&
  254. */
  255. JhmLockItem& operator=(const JhmLockItem &item)
  256. {
  257. if(this != &item)
  258. {
  259. _item = item._item;
  260. }
  261. return (*this);
  262. }
  263. /**
  264. *
  265. * @param item
  266. *
  267. * @return bool
  268. */
  269. bool operator==(const JhmLockItem& item)
  270. {
  271. return (_item == item._item);
  272. }
  273. /**
  274. *
  275. * @param item
  276. *
  277. * @return bool
  278. */
  279. bool operator!=(const JhmLockItem& item)
  280. {
  281. return !((*this) == item);
  282. }
  283. /**
  284. * 是否是脏数据
  285. *
  286. * @return bool
  287. */
  288. bool isDirty() { return _item.isDirty(); }
  289. /**
  290. * 是否只有Key
  291. *
  292. * @return bool
  293. */
  294. bool isOnlyKey() { return _item.isOnlyKey(); }
  295. /**
  296. * 最后回写时间
  297. *
  298. * @return time_t
  299. */
  300. time_t getSyncTime() { return _item.getSyncTime(); }
  301. /**
  302. * 获取值
  303. * @return int
  304. * TC_HashMap::RT_OK:数据获取OK
  305. * 其他值, 异常
  306. */
  307. int get(K& k)
  308. {
  309. string sk;
  310. int ret = _item.get(sk);
  311. if(ret != TC_HashMap::RT_OK)
  312. {
  313. return ret;
  314. }
  315. tars::TarsInputStream<BufferReader> is;
  316. is.setBuffer(sk.c_str(), sk.length());
  317. k.readFrom(is);
  318. return ret;
  319. }
  320. /**
  321. * 获取值
  322. * @return int
  323. * TC_HashMap::RT_OK:数据获取OK
  324. * TC_HashMap::RT_ONLY_KEY: key有效, v无效为空
  325. * 其他值, 异常
  326. */
  327. int get(K& k, V& v)
  328. {
  329. string sk;
  330. string sv;
  331. int ret = _item.get(sk, sv);
  332. if(ret != TC_HashMap::RT_OK && ret != TC_HashMap::RT_ONLY_KEY)
  333. {
  334. return ret;
  335. }
  336. tars::TarsInputStream<BufferReader> is;
  337. is.setBuffer(sk.c_str(), sk.length());
  338. k.readFrom(is);
  339. if(ret != TC_HashMap::RT_ONLY_KEY)
  340. {
  341. is.setBuffer(sv.c_str(), sv.length());
  342. v.readFrom(is);
  343. }
  344. return ret;
  345. }
  346. protected:
  347. TC_HashMap::HashMapLockItem _item;
  348. };
  349. ///////////////////////////////////////////////////////////////////
  350. /**
  351. * 迭代器
  352. */
  353. struct JhmLockIterator
  354. {
  355. public:
  356. /**
  357. * 构造
  358. * @param it
  359. * @param lock
  360. */
  361. JhmLockIterator(const TC_HashMap::lock_iterator it, const JhmAutoLockPtr &lock)
  362. : _it(it), _item(it._iItem), _lock(lock)
  363. {
  364. }
  365. /**
  366. * 拷贝构造
  367. * @param it
  368. */
  369. JhmLockIterator(const JhmLockIterator &it)
  370. : _it(it._it), _item(it._item), _lock(it._lock)
  371. {
  372. }
  373. /**
  374. * 复制
  375. * @param it
  376. *
  377. * @return JhmLockIterator&
  378. */
  379. JhmLockIterator& operator=(const JhmLockIterator &it)
  380. {
  381. if(this != &it)
  382. {
  383. _it = it._it;
  384. _item = it._item;
  385. _lock = it._lock;
  386. }
  387. return (*this);
  388. }
  389. /**
  390. *
  391. * @param it
  392. *
  393. * @return bool
  394. */
  395. bool operator==(const JhmLockIterator& it)
  396. {
  397. return (_it == it._it && _item == it._item);
  398. }
  399. /**
  400. *
  401. * @param mv
  402. *
  403. * @return bool
  404. */
  405. bool operator!=(const JhmLockIterator& it)
  406. {
  407. return !((*this) == it);
  408. }
  409. /**
  410. * 前置++
  411. *
  412. * @return JhmLockIterator&
  413. */
  414. JhmLockIterator& operator++()
  415. {
  416. ++_it;
  417. _item = JhmLockItem(_it._iItem);
  418. return (*this);
  419. }
  420. /**
  421. * 后置++
  422. *
  423. * @return JhmLockIterator&
  424. */
  425. JhmLockIterator operator++(int)
  426. {
  427. JhmLockIterator jit(_it, _lock);
  428. ++_it;
  429. _item = JhmLockItem(_it._iItem);
  430. return jit;
  431. }
  432. /**
  433. * 获取数据项
  434. *
  435. * @return JhmLockItem&
  436. */
  437. JhmLockItem& operator*() { return _item; }
  438. /**
  439. * 获取数据项
  440. *
  441. * @return JhmLockItem*
  442. */
  443. JhmLockItem* operator->() { return &_item; }
  444. protected:
  445. /**
  446. * 迭代器
  447. */
  448. TC_HashMap::lock_iterator _it;
  449. /**
  450. * 数据项
  451. */
  452. JhmLockItem _item;
  453. /**
  454. * 锁
  455. */
  456. JhmAutoLockPtr _lock;
  457. };
  458. typedef JhmLockIterator lock_iterator ;
  459. ///////////////////////////////////////////////////////////////////
  460. /**
  461. * 锁, 用于非锁迭代器
  462. *
  463. */
  464. class JhmLock : public TC_HandleBase
  465. {
  466. public:
  467. /**
  468. * 构造
  469. * @param mutex
  470. */
  471. JhmLock(typename LockPolicy::Mutex &mutex) : _mutex(mutex)
  472. {
  473. }
  474. /**
  475. * 获取锁
  476. *
  477. * @return typename LockPolicy::Mutex
  478. */
  479. typename LockPolicy::Mutex& mutex()
  480. {
  481. return _mutex;
  482. }
  483. protected:
  484. //不实现
  485. JhmLock(const JhmLock &al);
  486. JhmLock &operator=(const JhmLock &al);
  487. protected:
  488. /**
  489. * 锁
  490. */
  491. typename LockPolicy::Mutex &_mutex;
  492. };
  493. typedef TC_AutoPtr<JhmLock> JhmLockPtr;
  494. ///////////////////////////////////////////////////////////////////
  495. /**
  496. * 数据项
  497. */
  498. class JhmItem
  499. {
  500. public:
  501. /**
  502. * 构造函数
  503. * @param item
  504. */
  505. JhmItem(const TC_HashMap::HashMapItem &item, const JhmLockPtr &lock)
  506. : _item(item), _lock(lock)
  507. {
  508. }
  509. /**
  510. * 拷贝构造
  511. * @param it
  512. */
  513. JhmItem(const JhmItem &item)
  514. : _item(item._item), _lock(item._lock)
  515. {
  516. }
  517. /**
  518. * 复制
  519. * @param it
  520. *
  521. * @return JhmItem&
  522. */
  523. JhmItem& operator=(const JhmItem &item)
  524. {
  525. if(this != &item)
  526. {
  527. _item = item._item;
  528. _lock = item._lock;
  529. }
  530. return (*this);
  531. }
  532. /**
  533. *
  534. * @param item
  535. *
  536. * @return bool
  537. */
  538. bool operator==(const JhmItem& item)
  539. {
  540. return (_item == item._item);
  541. }
  542. /**
  543. *
  544. * @param item
  545. *
  546. * @return bool
  547. */
  548. bool operator!=(const JhmItem& item)
  549. {
  550. return !((*this) == item);
  551. }
  552. /**
  553. * 获取当前hash桶的所有数量, 注意只获取有key/value的数据
  554. * 对于只有key的数据, 不获取
  555. * 如果协议解码有问题也不获取
  556. * @param
  557. */
  558. void get(vector<pair<K, V> > &v)
  559. {
  560. vector<TC_HashMap::BlockData> vtData;
  561. {
  562. TC_LockT<typename LockPolicy::Mutex> lock(_lock->mutex());
  563. _item.get(vtData);
  564. }
  565. for(size_t i = 0; i < vtData.size(); i++)
  566. {
  567. pair<K, V> pk;
  568. try
  569. {
  570. tars::TarsInputStream<BufferReader> is;
  571. is.setBuffer(vtData[i]._key.c_str(), vtData[i]._key.length());
  572. pk.first.readFrom(is);
  573. is.setBuffer(vtData[i]._value.c_str(), vtData[i]._value.length());
  574. pk.second.readFrom(is);
  575. v.push_back(pk);
  576. }
  577. catch(exception &ex)
  578. {
  579. }
  580. }
  581. }
  582. /**
  583. * 设置当前桶下的所有数据为脏数据
  584. *
  585. * @param
  586. *
  587. * @return int
  588. */
  589. int setDirty()
  590. {
  591. {
  592. TC_LockT<typename LockPolicy::Mutex> lock(_lock->mutex());
  593. return _item.setDirty();
  594. }
  595. }
  596. protected:
  597. TC_HashMap::HashMapItem _item;
  598. JhmLockPtr _lock;
  599. };
  600. ///////////////////////////////////////////////////////////////////
  601. /**
  602. * 迭代器
  603. */
  604. struct JhmIterator
  605. {
  606. public:
  607. /**
  608. * 构造
  609. * @param it
  610. * @param lock
  611. */
  612. JhmIterator(const TC_HashMap::hash_iterator &it, const JhmLockPtr &lock)
  613. : _it(it), _item(it._iItem, lock), _lock(lock)
  614. {
  615. }
  616. /**
  617. * 拷贝构造
  618. * @param it
  619. */
  620. JhmIterator(const JhmIterator &it)
  621. : _it(it._it), _item(it._item), _lock(it._lock)
  622. {
  623. }
  624. /**
  625. * 复制
  626. * @param it
  627. *
  628. * @return JhmIterator&
  629. */
  630. JhmIterator& operator=(const JhmIterator &it)
  631. {
  632. if(this != &it)
  633. {
  634. _it = it._it;
  635. _item = it._item;
  636. }
  637. return (*this);
  638. }
  639. /**
  640. *
  641. * @param it
  642. *
  643. * @return bool
  644. */
  645. bool operator==(const JhmIterator& it)
  646. {
  647. return (_it == it._it && _item == it._item);
  648. }
  649. /**
  650. *
  651. * @param mv
  652. *
  653. * @return bool
  654. */
  655. bool operator!=(const JhmIterator& it)
  656. {
  657. return !((*this) == it);
  658. }
  659. /**
  660. * 前置++
  661. *
  662. * @return JhmIterator&
  663. */
  664. JhmIterator& operator++()
  665. {
  666. TC_LockT<typename LockPolicy::Mutex> lock(_lock->mutex());
  667. ++_it;
  668. _item = JhmItem(_it._iItem, _lock);
  669. return (*this);
  670. }
  671. /**
  672. * 后置++
  673. *
  674. * @return JhmIterator&
  675. */
  676. JhmIterator operator++(int)
  677. {
  678. TC_LockT<typename LockPolicy::Mutex> lock(_lock->mutex());
  679. JhmIterator jit(_it, _lock);
  680. ++_it;
  681. _item = JhmItem(_it._iItem, _lock);
  682. return jit;
  683. }
  684. /**
  685. * 获取数据项
  686. *
  687. * @return JhmItem&
  688. */
  689. JhmItem& operator*() { return _item; }
  690. /**
  691. * 获取数据项
  692. *
  693. * @return JhmItem*
  694. */
  695. JhmItem* operator->() { return &_item; }
  696. protected:
  697. /**
  698. * 迭代器
  699. */
  700. TC_HashMap::hash_iterator _it;
  701. /**
  702. * 数据项
  703. */
  704. JhmItem _item;
  705. /**
  706. * 锁
  707. */
  708. JhmLockPtr _lock;
  709. };
  710. typedef JhmIterator hash_iterator ;
  711. ////////////////////////////////////////////////////////////////////////////
  712. //
  713. /**
  714. * 构造函数
  715. */
  716. TarsHashMap()
  717. {
  718. _todo_of = NULL;
  719. }
  720. /**
  721. * 初始化数据块平均大小
  722. * 表示内存分配的时候,会分配n个最小块, n个(最小快*增长因子), n个(最小快*增长因子*增长因子)..., 直到n个最大块
  723. * n是hashmap自己计算出来的
  724. * 这种分配策略通常是你数据快记录变长比较多的使用, 便于节约内存,如果数据记录基本不是变长的, 那最小块=最大快,增长因子=1就可以了
  725. * @param iMinDataSize: 最小数据块大小
  726. * @param iMaxDataSize: 最大数据块大小
  727. * @param fFactor: 增长因子 >= 1.0
  728. */
  729. void initDataBlockSize(size_t iMinDataSize, size_t iMaxDataSize, float fFactor)
  730. {
  731. this->_t.initDataBlockSize(iMinDataSize, iMaxDataSize, fFactor);
  732. }
  733. /**
  734. * 设置hash比率(设置chunk数据块/hash项比值, 默认是2)
  735. * 有需要更改必须在create之前调用
  736. *
  737. * @param fRadio
  738. */
  739. void initHashRadio(float fRadio) { this->_t.initHashRadio(fRadio);}
  740. /**
  741. * 设置hash方式
  742. * @param hash_of
  743. */
  744. void setHashFunctor(TC_HashMap::hash_functor hashf)
  745. {
  746. TC_LockT<typename LockPolicy::Mutex> lock(LockPolicy::mutex());
  747. this->_t.setHashFunctor(hashf);
  748. }
  749. /**
  750. * 获取hash方式
  751. *
  752. * @return TC_HashMap::hash_functor&
  753. */
  754. TC_HashMap::hash_functor &getHashFunctor() { return this->_t.getHashFunctor(); }
  755. /**
  756. * 设置淘汰操作类
  757. * @param erase_of
  758. */
  759. void setToDoFunctor(ToDoFunctor *todo_of) { this->_todo_of = todo_of; }
  760. /**
  761. * 获取每种大小内存块的头部信息
  762. *
  763. * @return vector<TC_MemChunk::tagChunkHead>: 不同大小内存块头部信息
  764. */
  765. vector<TC_MemChunk::tagChunkHead> getBlockDetail()
  766. {
  767. TC_LockT<typename LockPolicy::Mutex> lock(LockPolicy::mutex());
  768. return this->_t.getBlockDetail();
  769. }
  770. /**
  771. * 所有block中chunk的个数
  772. *
  773. * @return size_t
  774. */
  775. size_t allBlockChunkCount()
  776. {
  777. TC_LockT<typename LockPolicy::Mutex> lock(LockPolicy::mutex());
  778. return this->_t.allBlockChunkCount();
  779. }
  780. /**
  781. * 每种block中chunk的个数(不同大小内存块的个数相同)
  782. *
  783. * @return size_t
  784. */
  785. vector<size_t> singleBlockChunkCount()
  786. {
  787. TC_LockT<typename LockPolicy::Mutex> lock(LockPolicy::mutex());
  788. return this->_t.singleBlockChunkCount();
  789. }
  790. /**
  791. * 获取hash桶的个数
  792. *
  793. * @return size_t
  794. */
  795. size_t getHashCount()
  796. {
  797. TC_LockT<typename LockPolicy::Mutex> lock(LockPolicy::mutex());
  798. return this->_t.getHashCount();
  799. }
  800. /**
  801. * 元素的个数
  802. *
  803. * @return size_t
  804. */
  805. size_t size()
  806. {
  807. TC_LockT<typename LockPolicy::Mutex> lock(LockPolicy::mutex());
  808. return this->_t.size();
  809. }
  810. /**
  811. * 脏数据元素个数
  812. *
  813. * @return size_t
  814. */
  815. size_t dirtyCount()
  816. {
  817. TC_LockT<typename LockPolicy::Mutex> lock(LockPolicy::mutex());
  818. return this->_t.dirtyCount();
  819. }
  820. /**
  821. * Only数据元素个数
  822. *
  823. * @return size_t
  824. */
  825. size_t onlyKeyCount()
  826. {
  827. TC_LockT<typename LockPolicy::Mutex> lock(LockPolicy::mutex());
  828. return this->_t.onlyKeyCount();
  829. }
  830. /**
  831. * 设置每次淘汰数量
  832. * @param n
  833. */
  834. void setEraseCount(size_t n)
  835. {
  836. TC_LockT<typename LockPolicy::Mutex> lock(LockPolicy::mutex());
  837. this->_t.setEraseCount(n);
  838. }
  839. /**
  840. * 获取每次淘汰数量
  841. *
  842. * @return size_t
  843. */
  844. size_t getEraseCount()
  845. {
  846. TC_LockT<typename LockPolicy::Mutex> lock(LockPolicy::mutex());
  847. return this->_t.getEraseCount();
  848. }
  849. /**
  850. * 设置只读
  851. * @param bReadOnly
  852. */
  853. void setReadOnly(bool bReadOnly)
  854. {
  855. TC_LockT<typename LockPolicy::Mutex> lock(LockPolicy::mutex());
  856. this->_t.setReadOnly(bReadOnly);
  857. }
  858. /**
  859. * 是否只读
  860. *
  861. * @return bool
  862. */
  863. bool isReadOnly()
  864. {
  865. TC_LockT<typename LockPolicy::Mutex> lock(LockPolicy::mutex());
  866. return this->_t.isReadOnly();
  867. }
  868. /**
  869. * 设置是否可以自动淘汰
  870. * @param bAutoErase
  871. */
  872. void setAutoErase(bool bAutoErase)
  873. {
  874. TC_LockT<typename LockPolicy::Mutex> lock(LockPolicy::mutex());
  875. this->_t.setAutoErase(bAutoErase);
  876. }
  877. /**
  878. * 是否可以自动淘汰
  879. *
  880. * @return bool
  881. */
  882. bool isAutoErase()
  883. {
  884. TC_LockT<typename LockPolicy::Mutex> lock(LockPolicy::mutex());
  885. return this->_t.isAutoErase();
  886. }
  887. /**
  888. * 设置淘汰方式
  889. * TC_HashMap::ERASEBYGET
  890. * TC_HashMap::ERASEBYSET
  891. * @param cEraseMode
  892. */
  893. void setEraseMode(char cEraseMode)
  894. {
  895. TC_LockT<typename LockPolicy::Mutex> lock(LockPolicy::mutex());
  896. this->_t.setEraseMode(cEraseMode);
  897. }
  898. /**
  899. * 获取淘汰方式
  900. *
  901. * @return bool
  902. */
  903. char getEraseMode()
  904. {
  905. TC_LockT<typename LockPolicy::Mutex> lock(LockPolicy::mutex());
  906. return this->_t.getEraseMode();
  907. }
  908. /**
  909. * 头部信息
  910. *
  911. * @return TC_HashMap::tagMapHead
  912. */
  913. TC_HashMap::tagMapHead& getMapHead() { return this->_t.getMapHead(); }
  914. /**
  915. * 设置回写时间(秒)
  916. * @param iSyncTime
  917. */
  918. void setSyncTime(time_t iSyncTime)
  919. {
  920. TC_LockT<typename LockPolicy::Mutex> lock(LockPolicy::mutex());
  921. this->_t.setSyncTime(iSyncTime);
  922. }
  923. /**
  924. * 获取回写时间
  925. *
  926. * @return time_t
  927. */
  928. time_t getSyncTime()
  929. {
  930. TC_LockT<typename LockPolicy::Mutex> lock(LockPolicy::mutex());
  931. return this->_t.getSyncTime();
  932. }
  933. /**
  934. * dump到文件
  935. * @param sFile
  936. * @param bDoClear: 是否清空
  937. * @return int
  938. * TC_HashMap::RT_DUMP_FILE_ERR: dump到文件出错
  939. * TC_HashMap::RT_OK: dump到文件成功
  940. */
  941. int dump2file(const string &sFile, bool bDoClear = false)
  942. {
  943. TC_LockT<typename LockPolicy::Mutex> lock(LockPolicy::mutex());
  944. int ret = this->_t.dump2file(sFile);
  945. if(ret != TC_HashMap::RT_OK)
  946. {
  947. return ret;
  948. }
  949. if(bDoClear)
  950. this->_t.clear();
  951. return ret;
  952. }
  953. /**
  954. * 从文件load
  955. * @param sFile
  956. *
  957. * @return int
  958. * TC_HashMap::RT_LOAL_FILE_ERR: load出错
  959. * TC_HashMap::RT_VERSION_MISMATCH_ERR: 版本不一致
  960. * TC_HashMap::RT_OK: load成功
  961. */
  962. int load5file(const string &sFile)
  963. {
  964. TC_LockT<typename LockPolicy::Mutex> lock(LockPolicy::mutex());
  965. return this->_t.load5file(sFile);
  966. }
  967. /**
  968. * 清空hash map
  969. * 所有map中的数据都被清空
  970. */
  971. void clear()
  972. {
  973. TC_LockT<typename LockPolicy::Mutex> lock(LockPolicy::mutex());
  974. return this->_t.clear();
  975. }
  976. /**
  977. * 检查数据状态
  978. * @param k
  979. *
  980. * @return int
  981. * TC_HashMap::RT_NO_DATA: 没有当前数据
  982. * TC_HashMap::RT_ONLY_KEY:只有Key
  983. * TC_HashMap::RT_DIRTY_DATA: 是脏数据
  984. * TC_HashMap::RT_OK: 是干净数据
  985. * 其他返回值: 错误
  986. */
  987. int checkDirty(const K &k)
  988. {
  989. tars::TarsOutputStream<BufferWriter> osk;
  990. k.writeTo(osk);
  991. string sk(osk.getBuffer(), osk.getLength());
  992. TC_LockT<typename LockPolicy::Mutex> lock(LockPolicy::mutex());
  993. return this->_t.checkDirty(sk);
  994. }
  995. /**
  996. * 设置为干净数据i, 修改SET/GET时间链, 会导致数据不回写
  997. * @param k
  998. *
  999. * @return int
  1000. * TC_HashMap::RT_READONLY: 只读
  1001. * TC_HashMap::RT_NO_DATA: 没有当前数据
  1002. * TC_HashMap::RT_ONLY_KEY:只有Key
  1003. * TC_HashMap::RT_OK: 设置成功
  1004. * 其他返回值: 错误
  1005. */
  1006. int setClean(const K& k)
  1007. {
  1008. tars::TarsOutputStream<BufferWriter> osk;
  1009. k.writeTo(osk);
  1010. string sk(osk.getBuffer(), osk.getLength());
  1011. TC_LockT<typename LockPolicy::Mutex> lock(LockPolicy::mutex());
  1012. return this->_t.setClean(sk);
  1013. }
  1014. /**
  1015. * 设置为脏数据, 修改SET/GET时间链, 会导致数据回写
  1016. * @param k
  1017. * @return int
  1018. * TC_HashMap::RT_READONLY: 只读
  1019. * TC_HashMap::RT_NO_DATA: 没有当前数据
  1020. * TC_HashMap::RT_ONLY_KEY:只有Key
  1021. * TC_HashMap::RT_OK: 设置脏数据成功
  1022. * 其他返回值: 错误
  1023. */
  1024. int setDirty(const K& k)
  1025. {
  1026. tars::TarsOutputStream<BufferWriter> osk;
  1027. k.writeTo(osk);
  1028. string sk(osk.getBuffer(), osk.getLength());
  1029. TC_LockT<typename LockPolicy::Mutex> lock(LockPolicy::mutex());
  1030. return this->_t.setDirty(sk);
  1031. }
  1032. /**
  1033. * 获取数据, 修改GET时间链
  1034. * (如果没设置自定义Get函数,没有数据时返回:RT_NO_DATA)
  1035. * @param k
  1036. * @param v
  1037. * @param iSyncTime:数据上次回写的时间, 没有缓写则为0
  1038. *
  1039. * @return int:
  1040. * TC_HashMap::RT_NO_DATA: 没有数据
  1041. * TC_HashMap::RT_READONLY: 只读模式
  1042. * TC_HashMap::RT_ONLY_KEY:只有Key
  1043. * TC_HashMap::RT_OK:获取数据成功
  1044. * TC_HashMap::RT_LOAD_DATA_ERR: load数据失败
  1045. * 其他返回值: 错误
  1046. */
  1047. int get(const K& k, V &v, time_t &iSyncTime)
  1048. {
  1049. iSyncTime = 0;
  1050. int ret = TC_HashMap::RT_OK;
  1051. tars::TarsOutputStream<BufferWriter> osk;
  1052. k.writeTo(osk);
  1053. string sk(osk.getBuffer(), osk.getLength());
  1054. string sv;
  1055. {
  1056. TC_LockT<typename LockPolicy::Mutex> lock(LockPolicy::mutex());
  1057. ret = this->_t.get(sk, sv, iSyncTime);
  1058. }
  1059. //读取到数据了, 解包
  1060. if(ret == TC_HashMap::RT_OK)
  1061. {
  1062. tars::TarsInputStream<BufferReader> is;
  1063. is.setBuffer(sv.c_str(), sv.length());
  1064. v.readFrom(is);
  1065. return ret;
  1066. }
  1067. if(ret != TC_HashMap::RT_NO_DATA || _todo_of == NULL)
  1068. {
  1069. return ret;
  1070. }
  1071. //只读模式
  1072. if(isReadOnly())
  1073. {
  1074. return TC_HashMap::RT_READONLY;
  1075. }
  1076. //获取函数
  1077. typename ToDoFunctor::DataRecord stDataRecord;
  1078. stDataRecord._key = k;
  1079. ret = _todo_of->get(stDataRecord);
  1080. if(ret == TC_HashMap::RT_OK)
  1081. {
  1082. v = stDataRecord._value;
  1083. return this->set(stDataRecord._key, stDataRecord._value, stDataRecord._dirty);
  1084. }
  1085. else if(ret == TC_HashMap::RT_NO_GET)
  1086. {
  1087. return TC_HashMap::RT_NO_DATA;
  1088. }
  1089. else if(ret == TC_HashMap::RT_NO_DATA)
  1090. {
  1091. ret = this->set(stDataRecord._key);
  1092. if(ret == TC_HashMap::RT_OK)
  1093. {
  1094. return TC_HashMap::RT_ONLY_KEY;
  1095. }
  1096. return ret;
  1097. }
  1098. return TC_HashMap::RT_LOAD_DATA_ERR;
  1099. }
  1100. /**
  1101. * 获取数据, 修改GET时间链
  1102. * @param k
  1103. * @param v
  1104. *
  1105. * @return int:
  1106. * TC_HashMap::RT_NO_DATA: 没有数据
  1107. * TC_HashMap::RT_ONLY_KEY:只有Key
  1108. * TC_HashMap::RT_OK:获取数据成功
  1109. * TC_HashMap::RT_LOAD_DATA_ERR: load数据失败
  1110. * 其他返回值: 错误
  1111. */
  1112. int get(const K& k, V &v)
  1113. {
  1114. time_t iSyncTime;
  1115. return get(k, v, iSyncTime);
  1116. }
  1117. /**
  1118. * 根据key, 获取相同hash值的所有数据
  1119. * 注意:c匹配对象操作中, map是加锁的, 需要注意
  1120. * @param h
  1121. * @param vv
  1122. * @param c, 匹配仿函数: bool operator()(K v);
  1123. *
  1124. * @return int, RT_OK
  1125. */
  1126. template<typename C>
  1127. int getHash(size_t h, vector<pair<K, V> > &vv, C c)
  1128. {
  1129. int ret = TC_HashMap::RT_OK;
  1130. TC_LockT<typename LockPolicy::Mutex> lock(LockPolicy::mutex());
  1131. this->_t.doUpdate();
  1132. size_t index = h % this->_t.getHashCount();
  1133. size_t iAddr = this->_t.item(index)->_iBlockAddr;
  1134. TC_HashMap::Block block(&this->_t, iAddr);
  1135. while(block.getHead() != 0)
  1136. {
  1137. TC_HashMap::BlockData data;
  1138. ret = block.getBlockData(data);
  1139. if(ret == TC_HashMap::RT_OK)
  1140. {
  1141. K tk;
  1142. V tv;
  1143. try
  1144. {
  1145. tars::TarsInputStream<BufferReader> is;
  1146. is.setBuffer(data._key.c_str(), data._key.length());
  1147. tk.readFrom(is);
  1148. if(c(tk))
  1149. {
  1150. is.setBuffer(data._value.c_str(), data._value.length());
  1151. tv.readFrom(is);
  1152. vv.push_back(make_pair(tk, tv));
  1153. }
  1154. }
  1155. catch(exception &ex)
  1156. {
  1157. }
  1158. }
  1159. if(!block.nextBlock())
  1160. {
  1161. break;
  1162. }
  1163. }
  1164. return TC_HashMap::RT_OK;
  1165. }
  1166. /**
  1167. * 根据key, 获取相同hash值的所有数据
  1168. * 注意:c匹配对象操作中, map是加锁的, 需要注意
  1169. * @param h
  1170. * @param vv
  1171. * @param c, 匹配仿函数: bool operator()(K v);
  1172. *
  1173. * @return int, RT_OK
  1174. */
  1175. template<typename C>
  1176. int getHash(size_t h, vector<DataRecord> &vv, C c)
  1177. {
  1178. int ret = TC_HashMap::RT_OK;
  1179. TC_LockT<typename LockPolicy::Mutex> lock(LockPolicy::mutex());
  1180. this->_t.doUpdate();
  1181. size_t index = h % this->_t.getHashCount();
  1182. size_t iAddr = this->_t.item(index)->_iBlockAddr;
  1183. TC_HashMap::Block block(&this->_t, iAddr);
  1184. while(block.getHead() != 0)
  1185. {
  1186. TC_HashMap::BlockData data;
  1187. ret = block.getBlockData(data);
  1188. if(ret == TC_HashMap::RT_OK)
  1189. {
  1190. K tk;
  1191. V tv;
  1192. try
  1193. {
  1194. tars::TarsInputStream<BufferReader> is;
  1195. is.setBuffer(data._key.c_str(), data._key.length());
  1196. tk.readFrom(is);
  1197. if(c(tk))
  1198. {
  1199. is.setBuffer(data._value.c_str(), data._value.length());
  1200. tv.readFrom(is);
  1201. DataRecord stDataRecord;
  1202. stDataRecord._key = tk;
  1203. stDataRecord._value = tv;
  1204. stDataRecord._dirty = data._dirty;
  1205. stDataRecord._iSyncTime = data._synct;
  1206. vv.push_back(stDataRecord);
  1207. }
  1208. }
  1209. catch(exception &ex)
  1210. {
  1211. }
  1212. }
  1213. if(!block.nextBlock())
  1214. {
  1215. break;
  1216. }
  1217. }
  1218. return TC_HashMap::RT_OK;
  1219. }
  1220. /**
  1221. * 恢复数据
  1222. * 对于block记录无法读取的数据自动删除
  1223. * @param bRepair: 是否修复
  1224. * @return 返回删除的记录数
  1225. */
  1226. size_t recover(bool bRepair)
  1227. {
  1228. size_t c = this->_t.getHashCount();
  1229. size_t e = 0;
  1230. for(size_t i = 0; i < c; i++)
  1231. {
  1232. TC_LockT<typename LockPolicy::Mutex> lock(LockPolicy::mutex());
  1233. e += this->_t.recover(i, bRepair);
  1234. }
  1235. return e;
  1236. }
  1237. /**
  1238. * 设置数据, 修改时间链, 内存不够时会自动淘汰老的数据
  1239. * @param k: 关键字
  1240. * @param v: 值
  1241. * @param bDirty: 是否是脏数据
  1242. * @return int:
  1243. * TC_HashMap::RT_READONLY: map只读
  1244. * TC_HashMap::RT_NO_MEMORY: 没有空间(不淘汰数据情况下会出现)
  1245. * TC_HashMap::RT_OK: 设置成功
  1246. * 其他返回值: 错误
  1247. */
  1248. int set(const K& k, const V& v, bool bDirty = true)
  1249. {
  1250. tars::TarsOutputStream<BufferWriter> osk;
  1251. k.writeTo(osk);
  1252. string sk(osk.getBuffer(), osk.getLength());
  1253. tars::TarsOutputStream<BufferWriter> osv;
  1254. v.writeTo(osv);
  1255. string sv(osv.getBuffer(), osv.getLength());
  1256. int ret = TC_HashMap::RT_OK;
  1257. vector<TC_HashMap::BlockData> vtData;
  1258. {
  1259. TC_LockT<typename LockPolicy::Mutex> lock(LockPolicy::mutex());
  1260. ret = this->_t.set(sk, sv, bDirty, vtData);
  1261. }
  1262. //操作淘汰数据
  1263. if(_todo_of)
  1264. {
  1265. for(size_t i = 0; i < vtData.size(); i++)
  1266. {
  1267. K tk;
  1268. V tv;
  1269. try
  1270. {
  1271. tars::TarsInputStream<BufferReader> is;
  1272. is.setBuffer(vtData[i]._key.c_str(), vtData[i]._key.length());
  1273. tk.readFrom(is);
  1274. is.setBuffer(vtData[i]._value.c_str(), vtData[i]._value.length());
  1275. tv.readFrom(is);
  1276. typename ToDoFunctor::DataRecord stDataRecord;
  1277. stDataRecord._key = tk;
  1278. stDataRecord._value = tv;
  1279. stDataRecord._dirty = vtData[i]._dirty;
  1280. stDataRecord._iSyncTime = vtData[i]._synct;
  1281. _todo_of->sync(stDataRecord);
  1282. }
  1283. catch(exception &ex)
  1284. {
  1285. }
  1286. }
  1287. }
  1288. return ret;
  1289. }
  1290. /**
  1291. * 仅设置Key, 内存不够时会自动淘汰老的数据
  1292. * @param k: 关键字
  1293. * @return int:
  1294. * TC_HashMap::RT_READONLY: map只读
  1295. * TC_HashMap::RT_NO_MEMORY: 没有空间(不淘汰数据情况下会出现)
  1296. * TC_HashMap::RT_OK: 设置成功
  1297. * 其他返回值: 错误
  1298. */
  1299. int set(const K& k)
  1300. {
  1301. tars::TarsOutputStream<BufferWriter> osk;
  1302. k.writeTo(osk);
  1303. string sk(osk.getBuffer(), osk.getLength());
  1304. int ret = TC_HashMap::RT_OK;
  1305. vector<TC_HashMap::BlockData> vtData;
  1306. {
  1307. TC_LockT<typename LockPolicy::Mutex> lock(LockPolicy::mutex());
  1308. ret = this->_t.set(sk, vtData);
  1309. }
  1310. //操作淘汰数据
  1311. if(_todo_of)
  1312. {
  1313. for(size_t i = 0; i < vtData.size(); i++)
  1314. {
  1315. K tk;
  1316. V tv;
  1317. try
  1318. {
  1319. tars::TarsInputStream<BufferReader> is;
  1320. is.setBuffer(vtData[i]._key.c_str(), vtData[i]._key.length());
  1321. tk.readFrom(is);
  1322. is.setBuffer(vtData[i]._value.c_str(), vtData[i]._value.length());
  1323. tv.readFrom(is);
  1324. typename ToDoFunctor::DataRecord stDataRecord;
  1325. stDataRecord._key = tk;
  1326. stDataRecord._value = tv;
  1327. stDataRecord._dirty = vtData[i]._dirty;
  1328. stDataRecord._iSyncTime = vtData[i]._synct;
  1329. _todo_of->sync(stDataRecord);
  1330. }
  1331. catch(exception &ex)
  1332. {
  1333. }
  1334. }
  1335. }
  1336. return ret;
  1337. }
  1338. /**
  1339. * 删除数据
  1340. * 无论cache是否有数据,todo的del都被调用
  1341. *
  1342. * @param k, 关键字
  1343. * @return int:
  1344. * TC_HashMap::RT_READONLY: map只读
  1345. * TC_HashMap::RT_NO_DATA: 没有当前数据
  1346. * TC_HashMap::RT_ONLY_KEY:只有Key, 也删除了
  1347. * TC_HashMap::RT_OK: 删除数据成功
  1348. * 其他返回值: 错误
  1349. */
  1350. int del(const K& k)
  1351. {
  1352. int ret = TC_HashMap::RT_OK;
  1353. TC_HashMap::BlockData data;
  1354. tars::TarsOutputStream<BufferWriter> os;
  1355. k.writeTo(os);
  1356. string sk(os.getBuffer(), os.getLength());
  1357. {
  1358. TC_LockT<typename LockPolicy::Mutex> lock(LockPolicy::mutex());
  1359. ret = this->_t.del(sk, data);
  1360. }
  1361. if(ret != TC_HashMap::RT_OK && ret != TC_HashMap::RT_ONLY_KEY && ret != TC_HashMap::RT_NO_DATA)
  1362. {
  1363. return ret;
  1364. }
  1365. if(_todo_of)
  1366. {
  1367. typename ToDoFunctor::DataRecord stDataRecord;
  1368. stDataRecord._key = k;
  1369. if(ret == TC_HashMap::RT_OK)
  1370. {
  1371. V v;
  1372. tars::TarsInputStream<BufferReader> is;
  1373. is.setBuffer(data._value.c_str(), data._value.length());
  1374. v.readFrom(is);
  1375. stDataRecord._value = v;
  1376. stDataRecord._dirty = data._dirty;
  1377. stDataRecord._iSyncTime = data._synct;
  1378. }
  1379. _todo_of->del((ret == TC_HashMap::RT_OK), stDataRecord);
  1380. }
  1381. return ret;
  1382. }
  1383. /**
  1384. * 删除数据
  1385. * cache有数据,todo的erase被调用
  1386. *
  1387. * @param k, 关键字
  1388. * @return int:
  1389. * TC_HashMap::RT_READONLY: map只读
  1390. * TC_HashMap::RT_NO_DATA: 没有当前数据
  1391. * TC_HashMap::RT_ONLY_KEY:只有Key, 也删除了
  1392. * TC_HashMap::RT_OK: 删除数据成功
  1393. * 其他返回值: 错误
  1394. */
  1395. int erase(const K& k)
  1396. {
  1397. int ret = TC_HashMap::RT_OK;
  1398. TC_HashMap::BlockData data;
  1399. tars::TarsOutputStream<BufferWriter> os;
  1400. k.writeTo(os);
  1401. string sk(os.getBuffer(), os.getLength());
  1402. {
  1403. TC_LockT<typename LockPolicy::Mutex> lock(LockPolicy::mutex());
  1404. ret = this->_t.del(sk, data);
  1405. }
  1406. if(ret != TC_HashMap::RT_OK)
  1407. {
  1408. return ret;
  1409. }
  1410. if(_todo_of)
  1411. {
  1412. V v;
  1413. tars::TarsInputStream<BufferReader> is;
  1414. is.setBuffer(data._value.c_str(), data._value.length());
  1415. v.readFrom(is);
  1416. typename ToDoFunctor::DataRecord stDataRecord;
  1417. stDataRecord._key = k;
  1418. stDataRecord._value = v;
  1419. stDataRecord._dirty = data._dirty;
  1420. stDataRecord._iSyncTime = data._synct;
  1421. _todo_of->erase(stDataRecord);
  1422. }
  1423. return ret;
  1424. }
  1425. /**
  1426. * 强制删除数据,不调用todo的erase被调用
  1427. *
  1428. * @param k, 关键字
  1429. * @return int:
  1430. * TC_HashMap::RT_READONLY: map只读
  1431. * TC_HashMap::RT_NO_DATA: 没有当前数据
  1432. * TC_HashMap::RT_ONLY_KEY:只有Key, 也删除了
  1433. * TC_HashMap::RT_OK: 删除数据成功
  1434. * 其他返回值: 错误
  1435. */
  1436. int eraseByForce(const K& k)
  1437. {
  1438. int ret = TC_HashMap::RT_OK;
  1439. TC_HashMap::BlockData data;
  1440. tars::TarsOutputStream<BufferWriter> os;
  1441. k.writeTo(os);
  1442. string sk(os.getBuffer(), os.getLength());
  1443. {
  1444. TC_LockT<typename LockPolicy::Mutex> lock(LockPolicy::mutex());
  1445. ret = this->_t.del(sk, data);
  1446. }
  1447. if(ret != TC_HashMap::RT_OK)
  1448. {
  1449. return ret;
  1450. }
  1451. return ret;
  1452. }
  1453. /**
  1454. * 根据key, 获取相同hash值的所有数据
  1455. * 注意:c匹配对象操作中, map是加锁的, 需要注意
  1456. * @param h
  1457. * @param vv
  1458. * @param c, 匹配仿函数: bool operator()(K v);
  1459. *
  1460. * @return int, RT_OK
  1461. */
  1462. /**
  1463. * 根据hash,强制删除相同hash值的所有数据,不调用todo的erase被调用
  1464. * 注意:c匹配对象操作中, map是加锁的, 需要注意
  1465. * @param h
  1466. * @param c, 匹配仿函数: bool operator()(K v);
  1467. * @return int:
  1468. * TC_HashMap::RT_READONLY: map只读
  1469. * TC_HashMap::RT_NO_DATA: 没有当前数据
  1470. * TC_HashMap::RT_ONLY_KEY:只有Key, 也删除了
  1471. * TC_HashMap::RT_OK: 删除数据成功
  1472. * 其他返回值: 错误
  1473. */
  1474. template<typename C>
  1475. int eraseHashByForce(size_t h, C c)
  1476. {
  1477. int ret = TC_HashMap::RT_OK;
  1478. vector<string> vDelKey;
  1479. TC_LockT<typename LockPolicy::Mutex> lock(LockPolicy::mutex());
  1480. this->_t.doUpdate();
  1481. size_t index = h % this->_t.getHashCount();
  1482. size_t iAddr = this->_t.item(index)->_iBlockAddr;
  1483. TC_HashMap::Block block(&this->_t, iAddr);
  1484. TC_HashMap::BlockData data;
  1485. while(block.getHead() != 0)
  1486. {
  1487. ret = block.getBlockData(data);
  1488. if(ret == TC_HashMap::RT_OK)
  1489. {
  1490. K tk;
  1491. V tv;
  1492. try
  1493. {
  1494. tars::TarsInputStream<BufferReader> is;
  1495. is.setBuffer(data._key.c_str(), data._key.length());
  1496. tk.readFrom(is);
  1497. if(c(tk))
  1498. vDelKey.push_back(data._key);
  1499. }
  1500. catch(exception &ex)
  1501. {
  1502. }
  1503. }
  1504. if(!block.nextBlock())
  1505. {
  1506. break;
  1507. }
  1508. }
  1509. for(size_t i=0; i<vDelKey.size(); ++i)
  1510. {
  1511. ret = this->_t.del(vDelKey[i], data);
  1512. if(ret != TC_HashMap::RT_OK)
  1513. {
  1514. return ret;
  1515. }
  1516. }
  1517. return TC_HashMap::RT_OK;
  1518. }
  1519. /**
  1520. * 根据hash,强制删除相同hash值的所有数据,不调用todo的erase被调用
  1521. * 注意:c匹配对象操作中, map是加锁的, 需要注意
  1522. * @param h
  1523. * @param c, 匹配仿函数: bool operator()(K v);
  1524. * @return int:
  1525. * TC_HashMap::RT_READONLY: map只读
  1526. * TC_HashMap::RT_NO_DATA: 没有当前数据
  1527. * TC_HashMap::RT_ONLY_KEY:只有Key, 也删除了
  1528. * TC_HashMap::RT_OK: 删除数据成功
  1529. * 其他返回值: 错误
  1530. */
  1531. template<typename C>
  1532. int eraseHashByForce(size_t h, C c, vector<K>& vDelK)
  1533. {
  1534. int ret = TC_HashMap::RT_OK;
  1535. vector<string> vDelKey;
  1536. TC_LockT<typename LockPolicy::Mutex> lock(LockPolicy::mutex());
  1537. this->_t.doUpdate();
  1538. size_t index = h % this->_t.getHashCount();
  1539. size_t iAddr = this->_t.item(index)->_iBlockAddr;
  1540. TC_HashMap::Block block(&this->_t, iAddr);
  1541. TC_HashMap::BlockData data;
  1542. while(block.getHead() != 0)
  1543. {
  1544. ret = block.getBlockData(data);
  1545. if(ret == TC_HashMap::RT_OK)
  1546. {
  1547. K tk;
  1548. try
  1549. {
  1550. tars::TarsInputStream<BufferReader> is;
  1551. is.setBuffer(data._key.c_str(), data._key.length());
  1552. tk.readFrom(is);
  1553. if(c(tk))
  1554. {
  1555. vDelKey.push_back(data._key);
  1556. vDelK.push_back(tk);
  1557. }
  1558. }
  1559. catch(exception &ex)
  1560. {
  1561. }
  1562. }
  1563. if(!block.nextBlock())
  1564. {
  1565. break;
  1566. }
  1567. }
  1568. for(size_t i=0; i<vDelKey.size(); ++i)
  1569. {
  1570. ret = this->_t.del(vDelKey[i], data);
  1571. if(ret != TC_HashMap::RT_OK)
  1572. {
  1573. vDelK.resize(i);
  1574. return ret;
  1575. }
  1576. }
  1577. return TC_HashMap::RT_OK;
  1578. }
  1579. /**
  1580. * 淘汰数据, 根据Get时间淘汰
  1581. * 直到: 元素个数/chunks * 100 < radio,bCheckDirty 为true时,遇到脏数据则淘汰结束
  1582. * @param radio: 共享内存chunks使用比例 0< radio < 100
  1583. * @return int:
  1584. * TC_HashMap::RT_READONLY: map只读
  1585. * TC_HashMap::RT_OK:淘汰完毕
  1586. */
  1587. int erase(int radio, bool bCheckDirty = false)
  1588. {
  1589. while(true)
  1590. {
  1591. int ret;
  1592. TC_HashMap::BlockData data;
  1593. {
  1594. TC_LockT<typename LockPolicy::Mutex> lock(LockPolicy::mutex());
  1595. ret = this->_t.erase(radio, data, bCheckDirty);
  1596. if(ret == TC_HashMap::RT_OK || ret == TC_HashMap::RT_READONLY)
  1597. {
  1598. return ret;
  1599. }
  1600. if(ret != TC_HashMap::RT_ERASE_OK)
  1601. {
  1602. continue;
  1603. }
  1604. }
  1605. if(_todo_of)
  1606. {
  1607. K tk;
  1608. V tv;
  1609. tars::TarsInputStream<BufferReader> is;
  1610. is.setBuffer(data._key.c_str(), data._key.length());
  1611. tk.readFrom(is);
  1612. is.setBuffer(data._value.c_str(), data._value.length());
  1613. tv.readFrom(is);
  1614. typename ToDoFunctor::DataRecord stDataRecord;
  1615. stDataRecord._key = tk;
  1616. stDataRecord._value = tv;
  1617. stDataRecord._dirty = data._dirty;
  1618. stDataRecord._iSyncTime = data._synct;
  1619. _todo_of->erase(stDataRecord);
  1620. }
  1621. }
  1622. return TC_HashMap::RT_OK;
  1623. }
  1624. /**
  1625. * 回写单条记录, 如果记录不存在, 则不做任何处理
  1626. * @param k
  1627. *
  1628. * @return int
  1629. * TC_HashMap::RT_NO_DATA: 没有数据
  1630. * TC_HashMap::RT_ONLY_KEY:只有Key
  1631. * TC_HashMap::RT_OK:获取数据成功
  1632. * TC_HashMap::RT_LOAD_DATA_ERR: load数据失败
  1633. * 其他返回值: 错误
  1634. */
  1635. int sync(const K& k)
  1636. {
  1637. V v;
  1638. time_t iSyncTime;
  1639. int ret = get(k, v, iSyncTime);
  1640. if(ret == TC_HashMap::RT_OK)
  1641. {
  1642. bool bDirty = (checkDirty(k) == TC_HashMap::RT_DIRTY_DATA);
  1643. if(_todo_of)
  1644. {
  1645. typename ToDoFunctor::DataRecord stDataRecord;
  1646. stDataRecord._key = k;
  1647. stDataRecord._value = v;
  1648. stDataRecord._dirty = bDirty;
  1649. stDataRecord._iSyncTime = iSyncTime;
  1650. _todo_of->sync(stDataRecord);
  1651. }
  1652. }
  1653. return ret;
  1654. }
  1655. /**
  1656. * 将脏数据且一定时间没有回写的数据全部回写
  1657. * 数据回写时间与当前时间超过_pHead->_iSyncTime(setSyncTime)则需要回写
  1658. *
  1659. * map只读时仍然可以回写
  1660. *
  1661. * @param iNowTime: 回写到什么时间, 通常是当前时间
  1662. * @return int:
  1663. * TC_HashMap::RT_OK: 回写完毕了
  1664. */
  1665. int sync(time_t iNowTime)
  1666. {
  1667. {
  1668. TC_LockT<typename LockPolicy::Mutex> lock(LockPolicy::mutex());
  1669. this->_t.sync();
  1670. }
  1671. while(true)
  1672. {
  1673. TC_HashMap::BlockData data;
  1674. int ret;
  1675. {
  1676. TC_LockT<typename LockPolicy::Mutex> lock(LockPolicy::mutex());
  1677. ret = this->_t.sync(iNowTime, data);
  1678. if(ret == TC_HashMap::RT_OK)
  1679. {
  1680. return ret;
  1681. }
  1682. if(ret != TC_HashMap::RT_NEED_SYNC)
  1683. {
  1684. continue;
  1685. }
  1686. }
  1687. if(_todo_of)
  1688. {
  1689. K tk;
  1690. V tv;
  1691. tars::TarsInputStream<BufferReader> is;
  1692. is.setBuffer(data._key.c_str(), data._key.length());
  1693. tk.readFrom(is);
  1694. is.setBuffer(data._value.c_str(), data._value.length());
  1695. tv.readFrom(is);
  1696. typename ToDoFunctor::DataRecord stDataRecord;
  1697. stDataRecord._key = tk;
  1698. stDataRecord._value = tv;
  1699. stDataRecord._dirty = data._dirty;
  1700. stDataRecord._iSyncTime = data._synct;
  1701. _todo_of->sync(stDataRecord);
  1702. }
  1703. }
  1704. return TC_HashMap::RT_OK;
  1705. }
  1706. /**
  1707. *将脏数据尾指针赋给回写尾指针
  1708. */
  1709. void sync()
  1710. {
  1711. TC_LockT<typename LockPolicy::Mutex> lock(LockPolicy::mutex());
  1712. this->_t.sync();
  1713. }
  1714. /**
  1715. * 将脏数据且一定时间没有回写的数据回写,只回写一个脏数据,目的是替代int sync(uint32_t iNowTime)
  1716. * 方法,把由业务控制每次回写数据量,使用时应该先调用void sync()
  1717. * 注意:c条件对象操作中, map是加锁的, 需要注意
  1718. *
  1719. * map只读时仍然可以回写
  1720. *
  1721. * @param iNowTime: 回写到什么时间, 通常是当前时间
  1722. * @return int:
  1723. * TC_HashMapCompact::RT_OK: 回写完毕了
  1724. *
  1725. * 示例:
  1726. * p->sync();
  1727. * while(true) {
  1728. * int iRet = pthis->SyncOnce(tNow);
  1729. * if( iRet == TC_HashMapCompact::RT_OK )
  1730. * break;
  1731. * }
  1732. */
  1733. template<typename C>
  1734. int syncOnce(uint32_t iNowTime, C c)
  1735. {
  1736. TC_HashMap::BlockData data;
  1737. K tk;
  1738. tars::TarsInputStream<BufferReader> is;
  1739. int ret;
  1740. {
  1741. TC_LockT<typename LockPolicy::Mutex> lock(LockPolicy::mutex());
  1742. ret = this->_t.sync(iNowTime, data);
  1743. if(ret == TC_HashMap::RT_OK)
  1744. {
  1745. return ret;
  1746. }
  1747. if(ret != TC_HashMap::RT_NEED_SYNC)
  1748. {
  1749. return ret;
  1750. }
  1751. if(_todo_of)
  1752. {
  1753. is.setBuffer(data._key.c_str(), data._key.length());
  1754. tk.readFrom(is);
  1755. if(!c(tk))
  1756. {
  1757. this->_t.setDirtyAfterSync(data._key);
  1758. return ret;
  1759. }
  1760. }
  1761. else
  1762. {
  1763. return ret;
  1764. }
  1765. }
  1766. V tv;
  1767. is.setBuffer(data._value.c_str(), data._value.length());
  1768. tv.readFrom(is);
  1769. typename ToDoFunctor::DataRecord stDataRecord;
  1770. stDataRecord._key = tk;
  1771. stDataRecord._value = tv;
  1772. stDataRecord._dirty = data._dirty;
  1773. stDataRecord._iSyncTime = data._synct;
  1774. _todo_of->sync(stDataRecord);
  1775. return ret;
  1776. }
  1777. /**
  1778. * 将脏数据且一定时间没有回写的数据回写,只回写一个脏数据,目的是替代int sync(time_t iNowTime)
  1779. * 方法,把由业务控制每次回写数据量,使用时应该先调用void sync()
  1780. *
  1781. * 数据回写时间与当前时间超过_pHead->_iSyncTime(setSyncTime)则需要回写
  1782. * map只读时仍然可以回写
  1783. *
  1784. * @param iNowTime: 回写到什么时间, 通常是当前时间
  1785. * @return int:
  1786. * TC_HashMap::RT_OK: 回写完毕了
  1787. *
  1788. * 示例:
  1789. * p->sync();
  1790. * while(true) {
  1791. * int iRet = pthis->SyncOnce(tNow);
  1792. * if( iRet == TC_HashMap::RT_OK )
  1793. * break;
  1794. * }
  1795. */
  1796. int syncOnce(time_t iNowTime)
  1797. {
  1798. TC_HashMap::BlockData data;
  1799. int ret;
  1800. {
  1801. TC_LockT<typename LockPolicy::Mutex> lock(LockPolicy::mutex());
  1802. ret = this->_t.sync(iNowTime, data);
  1803. if(ret == TC_HashMap::RT_OK)
  1804. {
  1805. return ret;
  1806. }
  1807. if(ret != TC_HashMap::RT_NEED_SYNC)
  1808. {
  1809. return ret;
  1810. }
  1811. }
  1812. if(_todo_of)
  1813. {
  1814. K tk;
  1815. V tv;
  1816. tars::TarsInputStream<BufferReader> is;
  1817. is.setBuffer(data._key.c_str(), data._key.length());
  1818. tk.readFrom(is);
  1819. is.setBuffer(data._value.c_str(), data._value.length());
  1820. tv.readFrom(is);
  1821. typename ToDoFunctor::DataRecord stDataRecord;
  1822. stDataRecord._key = tk;
  1823. stDataRecord._value = tv;
  1824. stDataRecord._dirty = data._dirty;
  1825. stDataRecord._iSyncTime = data._synct;
  1826. _todo_of->sync(stDataRecord);
  1827. }
  1828. return ret;
  1829. }
  1830. /**
  1831. * 备份数据
  1832. * map只读时仍然可以备份
  1833. * 可以多个线程/进程备份数据,同时备份时bForceFromBegin设置为false效率更高
  1834. *
  1835. * @param bForceFromBegin: 是否强制重头开始备份, 通常为false
  1836. * @return int:
  1837. * TC_HashMap::RT_OK: 备份OK了
  1838. */
  1839. int backup(bool bForceFromBegin = false)
  1840. {
  1841. {
  1842. //开始准备备份
  1843. TC_LockT<typename LockPolicy::Mutex> lock(LockPolicy::mutex());
  1844. this->_t.backup(bForceFromBegin);
  1845. }
  1846. while(true)
  1847. {
  1848. TC_HashMap::BlockData data;
  1849. int ret;
  1850. {
  1851. TC_LockT<typename LockPolicy::Mutex> lock(LockPolicy::mutex());
  1852. ret = this->_t.backup(data);
  1853. if(ret == TC_HashMap::RT_OK)
  1854. {
  1855. return ret;
  1856. }
  1857. if(ret != TC_HashMap::RT_NEED_BACKUP)
  1858. {
  1859. continue;
  1860. }
  1861. }
  1862. if(_todo_of)
  1863. {
  1864. K tk;
  1865. V tv;
  1866. tars::TarsInputStream<BufferReader> is;
  1867. is.setBuffer(data._key.c_str(), data._key.length());
  1868. tk.readFrom(is);
  1869. is.setBuffer(data._value.c_str(), data._value.length());
  1870. tv.readFrom(is);
  1871. typename ToDoFunctor::DataRecord stDataRecord;
  1872. stDataRecord._key = tk;
  1873. stDataRecord._value = tv;
  1874. stDataRecord._dirty = data._dirty;
  1875. stDataRecord._iSyncTime = data._synct;
  1876. _todo_of->backup(stDataRecord);
  1877. }
  1878. }
  1879. return TC_HashMap::RT_OK;
  1880. }
  1881. /**
  1882. * 描述
  1883. *
  1884. * @return string
  1885. */
  1886. string desc() { return this->_t.desc(); }
  1887. ///////////////////////////////////////////////////////////////////////////////
  1888. /**
  1889. * 尾部
  1890. *
  1891. * @return lock_iterator
  1892. */
  1893. lock_iterator end()
  1894. {
  1895. JhmAutoLockPtr jlock;
  1896. return JhmLockIterator(this->_t.end(), jlock);
  1897. }
  1898. /**
  1899. * 根据Key查找数据
  1900. * @param k
  1901. */
  1902. lock_iterator find(const K& k)
  1903. {
  1904. tars::TarsOutputStream<BufferWriter> os;
  1905. k.writeTo(os);
  1906. string sk(os.getBuffer(), os.getLength());
  1907. JhmAutoLockPtr jlock(new JhmAutoLock(this->mutex()));
  1908. return JhmLockIterator(this->_t.find(sk), jlock);
  1909. }
  1910. /**
  1911. * block正序
  1912. *
  1913. * @return lock_iterator
  1914. */
  1915. lock_iterator begin()
  1916. {
  1917. JhmAutoLockPtr jlock(new JhmAutoLock(this->mutex()));
  1918. return JhmLockIterator(this->_t.begin(), jlock);
  1919. }
  1920. /**
  1921. * block逆序
  1922. *
  1923. * @return lock_iterator
  1924. */
  1925. lock_iterator rbegin()
  1926. {
  1927. JhmAutoLockPtr jlock(new JhmAutoLock(this->mutex()));
  1928. return JhmLockIterator(this->_t.rbegin(), jlock);
  1929. }
  1930. /**
  1931. * 以Set时间排序的迭代器
  1932. * 返回的迭代器++表示按照时间顺序:最近Set-->最久Set
  1933. *
  1934. * @return lock_iterator
  1935. */
  1936. lock_iterator beginSetTime()
  1937. {
  1938. JhmAutoLockPtr jlock(new JhmAutoLock(this->mutex()));
  1939. return JhmLockIterator(this->_t.beginSetTime(), jlock);
  1940. }
  1941. /**
  1942. * Set时间链逆序的迭代器
  1943. *
  1944. * 返回的迭代器++表示按照时间顺序:最久Set-->最近Set
  1945. *
  1946. * @return lock_iterator
  1947. */
  1948. lock_iterator rbeginSetTime()
  1949. {
  1950. JhmAutoLockPtr jlock(new JhmAutoLock(this->mutex()));
  1951. return JhmLockIterator(this->_t.rbeginSetTime(), jlock);
  1952. }
  1953. /**
  1954. * 以Get时间排序的迭代器
  1955. * 返回的迭代器++表示按照时间顺序:最近Get-->最久Get
  1956. *
  1957. * @return lock_iterator
  1958. */
  1959. lock_iterator beginGetTime()
  1960. {
  1961. JhmAutoLockPtr jlock(new JhmAutoLock(this->mutex()));
  1962. return JhmLockIterator(this->_t.beginGetTime(), jlock);
  1963. }
  1964. /**
  1965. * Get时间链逆序的迭代器
  1966. *
  1967. * 返回的迭代器++表示按照时间顺序:最久Get-->最近Get
  1968. *
  1969. * @return lock_iterator
  1970. */
  1971. lock_iterator rbeginGetTime()
  1972. {
  1973. JhmAutoLockPtr jlock(new JhmAutoLock(this->mutex()));
  1974. return JhmLockIterator(this->_t.rbeginGetTime(), jlock);
  1975. }
  1976. /**
  1977. * 获取脏链表尾部迭代器(最长时间没有Set的脏数据)
  1978. *
  1979. * 返回的迭代器++表示按照时间顺序:最近Set-->最久Set
  1980. * 可能存在干净数据
  1981. *
  1982. * @return lock_iterator
  1983. */
  1984. lock_iterator beginDirty()
  1985. {
  1986. JhmAutoLockPtr jlock(new JhmAutoLock(this->mutex()));
  1987. return JhmLockIterator(this->_t.beginDirty(), jlock);
  1988. }
  1989. /////////////////////////////////////////////////////////////////////////////////////////
  1990. // 以下是遍历map函数, 不需要对map加锁
  1991. /**
  1992. * 根据hash桶遍历
  1993. *
  1994. * @return hash_iterator
  1995. */
  1996. hash_iterator hashBegin()
  1997. {
  1998. JhmLockPtr jlock(new JhmLock(this->mutex()));
  1999. TC_LockT<typename LockPolicy::Mutex> lock(LockPolicy::mutex());
  2000. return JhmIterator(this->_t.hashBegin(), jlock);
  2001. }
  2002. /**
  2003. * 结束
  2004. *
  2005. * @return
  2006. */
  2007. hash_iterator hashEnd()
  2008. {
  2009. JhmLockPtr jlock;
  2010. return JhmIterator(this->_t.hashEnd(), jlock);
  2011. }
  2012. /**
  2013. * 获取指定下标的hash_iterator
  2014. * @param iIndex
  2015. *
  2016. * @return hash_iterator
  2017. */
  2018. hash_iterator hashIndex(size_t iIndex)
  2019. {
  2020. JhmLockPtr jlock(new JhmLock(this->mutex()));
  2021. TC_LockT<typename LockPolicy::Mutex> lock(LockPolicy::mutex());
  2022. return JhmIterator(this->_t.hashIndex(iIndex), jlock);
  2023. }
  2024. protected:
  2025. /**
  2026. * 删除数据的函数对象
  2027. */
  2028. ToDoFunctor *_todo_of;
  2029. };
  2030. }
  2031. #endif