db.hpp 57 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694
  1. /*****************************************************************************\
  2. * Copyright (c) rAthena Dev Teams - Licensed under GNU GPL *
  3. * For more information, see LICENCE in the main folder *
  4. * *
  5. * This file is separated in two sections: *
  6. * (1) public typedefs, enums, unions, structures and defines *
  7. * (2) public functions *
  8. * *
  9. * <B>Notes on the release system:</B> *
  10. * Whenever an entry is removed from the database both the key and the *
  11. * data are requested to be released. *
  12. * At least one entry is removed when replacing an entry, removing an *
  13. * entry, clearing the database or destroying the database. *
  14. * What is actually released is defined by the release function, the *
  15. * functions of the database only ask for the key and/or data to be *
  16. * released. *
  17. * *
  18. * TODO: *
  19. * - create a custom database allocator *
  20. * - see what functions need or should be added to the database interface *
  21. * *
  22. * HISTORY: *
  23. * 2013/08/25 - Added int64/uint64 support for keys *
  24. * 2012/03/09 - Added enum for data types (int, uint, void*) *
  25. * 2007/11/09 - Added an iterator to the database. *
  26. * 2.1 (Athena build #???#) - Portability fix *
  27. * - Fixed the portability of casting to union and added the functions *
  28. * {@link DBMap#ensure(DBMap,DBKey,DBCreateData,...)} and *
  29. * {@link DBMap#clear(DBMap,DBApply,...)}. *
  30. * 2.0 (Athena build 4859) - Transition version *
  31. * - Almost everything recoded with a strategy similar to objects, *
  32. * database structure is maintained. *
  33. * 1.0 (up to Athena build 4706) *
  34. * - Previous database system. *
  35. * *
  36. * @version 2.1 (Athena build #???#) - Portability fix *
  37. * @author (Athena build 4859) Flavio @ Amazon Project *
  38. * @author (up to Athena build 4706) Athena Dev Teams *
  39. * @encoding US-ASCII *
  40. * @see common#db.cpp *
  41. \*****************************************************************************/
  42. #ifndef DB_HPP
  43. #define DB_HPP
  44. #include <stdarg.h>
  45. #include "cbasetypes.hpp"
  46. /*****************************************************************************\
  47. * (1) Section with public typedefs, enums, unions, structures and defines. *
  48. * DBRelease - Enumeration of release options. *
  49. * DBType - Enumeration of database types. *
  50. * DBOptions - Bitfield enumeration of database options. *
  51. * DBKey - Union of used key types. *
  52. * DBDataType - Enumeration of data types. *
  53. * DBData - Struct for used data types. *
  54. * DBApply - Format of functions applied to the databases. *
  55. * DBMatcher - Format of matchers used in DBMap::getall. *
  56. * DBComparator - Format of the comparators used by the databases. *
  57. * DBHasher - Format of the hashers used by the databases. *
  58. * DBReleaser - Format of the releasers used by the databases. *
  59. * DBIterator - Database iterator. *
  60. * DBMap - Database interface. *
  61. \*****************************************************************************/
  62. /**
  63. * Bitfield with what should be released by the releaser function (if the
  64. * function supports it).
  65. * @public
  66. * @see #DBReleaser
  67. * @see #db_custom_release(DBRelease)
  68. */
  69. typedef enum DBRelease {
  70. DB_RELEASE_NOTHING = 0x0,
  71. DB_RELEASE_KEY = 0x1,
  72. DB_RELEASE_DATA = 0x2,
  73. DB_RELEASE_BOTH = DB_RELEASE_KEY|DB_RELEASE_DATA,
  74. } DBRelease;
  75. /**
  76. * Supported types of database.
  77. * See {@link #db_fix_options(DBType,DBOptions)} for restrictions of the
  78. * types of databases.
  79. * @param DB_INT Uses int's for keys
  80. * @param DB_UINT Uses unsigned int's for keys
  81. * @param DB_STRING Uses strings for keys.
  82. * @param DB_ISTRING Uses case insensitive strings for keys.
  83. * @param DB_INT64 Uses int64's for keys
  84. * @param DB_UINT64 Uses uint64's for keys
  85. * @public
  86. * @see #DBOptions
  87. * @see #DBKey
  88. * @see #db_fix_options(DBType,DBOptions)
  89. * @see #db_default_cmp(DBType)
  90. * @see #db_default_hash(DBType)
  91. * @see #db_default_release(DBType,DBOptions)
  92. * @see #db_alloc(const char *,int,DBType,DBOptions,unsigned short)
  93. */
  94. typedef enum DBType {
  95. DB_INT,
  96. DB_UINT,
  97. DB_STRING,
  98. DB_ISTRING,
  99. DB_INT64,
  100. DB_UINT64,
  101. } DBType;
  102. /**
  103. * Bitfield of options that define the behavior of the database.
  104. * See {@link #db_fix_options(DBType,DBOptions)} for restrictions of the
  105. * types of databases.
  106. * @param DB_OPT_BASE Base options: does not duplicate keys, releases nothing
  107. * and does not allow NULL keys or NULL data.
  108. * @param DB_OPT_DUP_KEY Duplicates the keys internally. If DB_OPT_RELEASE_KEY
  109. * is defined, the real key is freed as soon as the entry is added.
  110. * @param DB_OPT_RELEASE_KEY Releases the key.
  111. * @param DB_OPT_RELEASE_DATA Releases the data whenever an entry is removed
  112. * from the database.
  113. * WARNING: for functions that return the data (like DBMap::remove),
  114. * a dangling pointer will be returned.
  115. * @param DB_OPT_RELEASE_BOTH Releases both key and data.
  116. * @param DB_OPT_ALLOW_NULL_KEY Allow NULL keys in the database.
  117. * @param DB_OPT_ALLOW_NULL_DATA Allow NULL data in the database.
  118. * @public
  119. * @see #db_fix_options(DBType,DBOptions)
  120. * @see #db_default_release(DBType,DBOptions)
  121. * @see #db_alloc(const char *,int,DBType,DBOptions,unsigned short)
  122. */
  123. typedef enum DBOptions {
  124. DB_OPT_BASE = 0x00,
  125. DB_OPT_DUP_KEY = 0x01,
  126. DB_OPT_RELEASE_KEY = 0x02,
  127. DB_OPT_RELEASE_DATA = 0x04,
  128. DB_OPT_RELEASE_BOTH = DB_OPT_RELEASE_KEY|DB_OPT_RELEASE_DATA,
  129. DB_OPT_ALLOW_NULL_KEY = 0x08,
  130. DB_OPT_ALLOW_NULL_DATA = 0x10,
  131. } DBOptions;
  132. /**
  133. * Union of key types used by the database.
  134. * @param i Type of key for DB_INT databases
  135. * @param ui Type of key for DB_UINT databases
  136. * @param str Type of key for DB_STRING and DB_ISTRING databases
  137. * @public
  138. * @see #DBType
  139. * @see DBMap#get
  140. * @see DBMap#put
  141. * @see DBMap#remove
  142. */
  143. typedef union DBKey {
  144. int i;
  145. unsigned int ui;
  146. const char *str;
  147. int64 i64;
  148. uint64 ui64;
  149. } DBKey;
  150. /**
  151. * Supported types of database data.
  152. * @param DB_DATA_INT Uses ints for data.
  153. * @param DB_DATA_UINT Uses unsigned ints for data.
  154. * @param DB_DATA_PTR Uses void pointers for data.
  155. * @public
  156. * @see #DBData
  157. */
  158. typedef enum DBDataType {
  159. DB_DATA_INT,
  160. DB_DATA_UINT,
  161. DB_DATA_PTR,
  162. DB_DATA_I64
  163. } DBDataType;
  164. /**
  165. * Struct for data types used by the database.
  166. * @param type Type of data
  167. * @param u Union of available data types
  168. * @param u.i Data of int type
  169. * @param u.ui Data of unsigned int type
  170. * @param u.ptr Data of void* type
  171. * @param u.i64 Data of int64 type
  172. * @public
  173. */
  174. typedef struct DBData {
  175. DBDataType type;
  176. union {
  177. int i;
  178. unsigned int ui;
  179. void *ptr;
  180. int64 i64;
  181. } u;
  182. } DBData;
  183. /**
  184. * Format of functions that create the data for the key when the entry doesn't
  185. * exist in the database yet.
  186. * @param key Key of the database entry
  187. * @param args Extra arguments of the function
  188. * @return Data identified by the key to be put in the database
  189. * @public
  190. * @see DBMap#vensure
  191. * @see DBMap#ensure
  192. */
  193. typedef DBData (*DBCreateData)(DBKey key, va_list args);
  194. /**
  195. * Format of functions to be applied to an unspecified quantity of entries of
  196. * a database.
  197. * Any function that applies this function to the database will return the sum
  198. * of values returned by this function.
  199. * @param key Key of the database entry
  200. * @param data Data of the database entry
  201. * @param args Extra arguments of the function
  202. * @return Value to be added up by the function that is applying this
  203. * @public
  204. * @see DBMap#vforeach
  205. * @see DBMap#foreach
  206. * @see DBMap#vdestroy
  207. * @see DBMap#destroy
  208. */
  209. typedef int (*DBApply)(DBKey key, DBData *data, va_list args);
  210. /**
  211. * Format of functions that match database entries.
  212. * The purpose of the match depends on the function that is calling the matcher.
  213. * Returns 0 if it is a match, another number otherwise.
  214. * @param key Key of the database entry
  215. * @param data Data of the database entry
  216. * @param args Extra arguments of the function
  217. * @return 0 if a match, another number otherwise
  218. * @public
  219. * @see DBMap#getall
  220. */
  221. typedef int (*DBMatcher)(DBKey key, DBData data, va_list args);
  222. /**
  223. * Format of the comparators used internally by the database system.
  224. * Compares key1 to key2.
  225. * Returns 0 is equal, negative if lower and positive is higher.
  226. * @param key1 Key being compared
  227. * @param key2 Key we are comparing to
  228. * @param maxlen Maximum number of characters used in DB_STRING and DB_ISTRING
  229. * databases.
  230. * @return 0 if equal, negative if lower and positive if higher
  231. * @public
  232. * @see #db_default_cmp(DBType)
  233. */
  234. typedef int (*DBComparator)(DBKey key1, DBKey key2, unsigned short maxlen);
  235. /**
  236. * Format of the hashers used internally by the database system.
  237. * Creates the hash of the key.
  238. * @param key Key being hashed
  239. * @param maxlen Maximum number of characters used in DB_STRING and DB_ISTRING
  240. * databases.
  241. * @return Hash of the key
  242. * @public
  243. * @see #db_default_hash(DBType)
  244. */
  245. typedef uint64 (*DBHasher)(DBKey key, unsigned short maxlen);
  246. /**
  247. * Format of the releaser used by the database system.
  248. * Releases nothing, the key, the data or both.
  249. * All standard releasers use aFree to release.
  250. * @param key Key of the database entry
  251. * @param data Data of the database entry
  252. * @param which What is being requested to be released
  253. * @public
  254. * @see #DBRelease
  255. * @see #db_default_releaser(DBType,DBOptions)
  256. * @see #db_custom_release(DBRelease)
  257. */
  258. typedef void (*DBReleaser)(DBKey key, DBData data, DBRelease which);
  259. typedef struct DBIterator DBIterator;
  260. typedef struct DBMap DBMap;
  261. /**
  262. * Database iterator.
  263. * Supports forward iteration, backward iteration and removing entries from the database.
  264. * The iterator is initially positioned before the first entry of the database.
  265. * While the iterator exists the database is locked internally, so invoke
  266. * {@link DBIterator#destroy} as soon as possible.
  267. * @public
  268. * @see #DBMap
  269. */
  270. struct DBIterator
  271. {
  272. /**
  273. * Fetches the first entry in the database.
  274. * Returns the data of the entry.
  275. * Puts the key in out_key, if out_key is not NULL.
  276. * @param self Iterator
  277. * @param out_key Key of the entry
  278. * @return Data of the entry
  279. * @protected
  280. */
  281. DBData* (*first)(DBIterator* self, DBKey* out_key);
  282. /**
  283. * Fetches the last entry in the database.
  284. * Returns the data of the entry.
  285. * Puts the key in out_key, if out_key is not NULL.
  286. * @param self Iterator
  287. * @param out_key Key of the entry
  288. * @return Data of the entry
  289. * @protected
  290. */
  291. DBData* (*last)(DBIterator* self, DBKey* out_key);
  292. /**
  293. * Fetches the next entry in the database.
  294. * Returns the data of the entry.
  295. * Puts the key in out_key, if out_key is not NULL.
  296. * @param self Iterator
  297. * @param out_key Key of the entry
  298. * @return Data of the entry
  299. * @protected
  300. */
  301. DBData* (*next)(DBIterator* self, DBKey* out_key);
  302. /**
  303. * Fetches the previous entry in the database.
  304. * Returns the data of the entry.
  305. * Puts the key in out_key, if out_key is not NULL.
  306. * @param self Iterator
  307. * @param out_key Key of the entry
  308. * @return Data of the entry
  309. * @protected
  310. */
  311. DBData* (*prev)(DBIterator* self, DBKey* out_key);
  312. /**
  313. * Returns true if the fetched entry exists.
  314. * The databases entries might have NULL data, so use this to to test if
  315. * the iterator is done.
  316. * @param self Iterator
  317. * @return true is the entry exists
  318. * @protected
  319. */
  320. bool (*exists)(DBIterator* self);
  321. /**
  322. * Removes the current entry from the database.
  323. * NOTE: {@link DBIterator#exists} will return false until another entry
  324. * is fetched
  325. * Puts data of the removed entry in out_data, if out_data is not NULL.
  326. * @param self Iterator
  327. * @param out_data Data of the removed entry.
  328. * @return 1 if entry was removed, 0 otherwise
  329. * @protected
  330. * @see DBMap#remove
  331. */
  332. int (*remove)(DBIterator* self, DBData *out_data);
  333. /**
  334. * Destroys this iterator and unlocks the database.
  335. * @param self Iterator
  336. * @protected
  337. */
  338. void (*destroy)(DBIterator* self);
  339. };
  340. /**
  341. * Public interface of a database. Only contains functions.
  342. * All the functions take the interface as the first argument.
  343. * @public
  344. * @see #db_alloc(const char*,int,DBType,DBOptions,unsigned short)
  345. */
  346. struct DBMap {
  347. /**
  348. * Returns a new iterator for this database.
  349. * The iterator keeps the database locked until it is destroyed.
  350. * The database will keep functioning normally but will only free internal
  351. * memory when unlocked, so destroy the iterator as soon as possible.
  352. * @param self Database
  353. * @return New iterator
  354. * @protected
  355. */
  356. DBIterator* (*iterator)(DBMap* self);
  357. /**
  358. * Returns true if the entry exists.
  359. * @param self Database
  360. * @param key Key that identifies the entry
  361. * @return true is the entry exists
  362. * @protected
  363. */
  364. bool (*exists)(DBMap* self, DBKey key);
  365. /**
  366. * Get the data of the entry identified by the key.
  367. * @param self Database
  368. * @param key Key that identifies the entry
  369. * @return Data of the entry or NULL if not found
  370. * @protected
  371. */
  372. DBData* (*get)(DBMap* self, DBKey key);
  373. /**
  374. * Just calls {@link DBMap#vgetall}.
  375. * Get the data of the entries matched by <code>match</code>.
  376. * It puts a maximum of <code>max</code> entries into <code>buf</code>.
  377. * If <code>buf</code> is NULL, it only counts the matches.
  378. * Returns the number of entries that matched.
  379. * NOTE: if the value returned is greater than <code>max</code>, only the
  380. * first <code>max</code> entries found are put into the buffer.
  381. * @param self Database
  382. * @param buf Buffer to put the data of the matched entries
  383. * @param max Maximum number of data entries to be put into buf
  384. * @param match Function that matches the database entries
  385. * @param ... Extra arguments for match
  386. * @return The number of entries that matched
  387. * @protected
  388. * @see DBMap#vgetall(DBMap*,void **,unsigned int,DBMatcher,va_list)
  389. */
  390. unsigned int (*getall)(DBMap* self, DBData** buf, unsigned int max, DBMatcher match, ...);
  391. /**
  392. * Get the data of the entries matched by <code>match</code>.
  393. * It puts a maximum of <code>max</code> entries into <code>buf</code>.
  394. * If <code>buf</code> is NULL, it only counts the matches.
  395. * Returns the number of entries that matched.
  396. * NOTE: if the value returned is greater than <code>max</code>, only the
  397. * first <code>max</code> entries found are put into the buffer.
  398. * @param self Database
  399. * @param buf Buffer to put the data of the matched entries
  400. * @param max Maximum number of data entries to be put into buf
  401. * @param match Function that matches the database entries
  402. * @param ... Extra arguments for match
  403. * @return The number of entries that matched
  404. * @protected
  405. * @see DBMap#getall(DBMap*,void **,unsigned int,DBMatcher,...)
  406. */
  407. unsigned int (*vgetall)(DBMap* self, DBData** buf, unsigned int max, DBMatcher match, va_list args);
  408. /**
  409. * Just calls {@link DBMap#vensure}.
  410. * Get the data of the entry identified by the key.
  411. * If the entry does not exist, an entry is added with the data returned by
  412. * <code>create</code>.
  413. * @param self Database
  414. * @param key Key that identifies the entry
  415. * @param create Function used to create the data if the entry doesn't exist
  416. * @param ... Extra arguments for create
  417. * @return Data of the entry
  418. * @protected
  419. * @see DBMap#vensure(DBMap*,DBKey,DBCreateData,va_list)
  420. */
  421. DBData* (*ensure)(DBMap* self, DBKey key, DBCreateData create, ...);
  422. /**
  423. * Get the data of the entry identified by the key.
  424. * If the entry does not exist, an entry is added with the data returned by
  425. * <code>create</code>.
  426. * @param self Database
  427. * @param key Key that identifies the entry
  428. * @param create Function used to create the data if the entry doesn't exist
  429. * @param args Extra arguments for create
  430. * @return Data of the entry
  431. * @protected
  432. * @see DBMap#ensure(DBMap*,DBKey,DBCreateData,...)
  433. */
  434. DBData* (*vensure)(DBMap* self, DBKey key, DBCreateData create, va_list args);
  435. /**
  436. * Put the data identified by the key in the database.
  437. * Puts the previous data in out_data, if out_data is not NULL.
  438. * NOTE: Uses the new key, the old one is released.
  439. * @param self Database
  440. * @param key Key that identifies the data
  441. * @param data Data to be put in the database
  442. * @param out_data Previous data if the entry exists
  443. * @return 1 if if the entry already exists, 0 otherwise
  444. * @protected
  445. */
  446. int (*put)(DBMap* self, DBKey key, DBData data, DBData *out_data);
  447. /**
  448. * Remove an entry from the database.
  449. * Puts the previous data in out_data, if out_data is not NULL.
  450. * NOTE: The key (of the database) is released.
  451. * @param self Database
  452. * @param key Key that identifies the entry
  453. * @param out_data Previous data if the entry exists
  454. * @return 1 if if the entry already exists, 0 otherwise
  455. * @protected
  456. */
  457. int (*remove)(DBMap* self, DBKey key, DBData *out_data);
  458. /**
  459. * Just calls {@link DBMap#vforeach}.
  460. * Apply <code>func</code> to every entry in the database.
  461. * Returns the sum of values returned by func.
  462. * @param self Database
  463. * @param func Function to be applied
  464. * @param ... Extra arguments for func
  465. * @return Sum of the values returned by func
  466. * @protected
  467. * @see DBMap#vforeach(DBMap*,DBApply,va_list)
  468. */
  469. int (*foreach)(DBMap* self, DBApply func, ...);
  470. /**
  471. * Apply <code>func</code> to every entry in the database.
  472. * Returns the sum of values returned by func.
  473. * @param self Database
  474. * @param func Function to be applied
  475. * @param args Extra arguments for func
  476. * @return Sum of the values returned by func
  477. * @protected
  478. * @see DBMap#foreach(DBMap*,DBApply,...)
  479. */
  480. int (*vforeach)(DBMap* self, DBApply func, va_list args);
  481. /**
  482. * Just calls {@link DBMap#vclear}.
  483. * Removes all entries from the database.
  484. * Before deleting an entry, func is applied to it.
  485. * Releases the key and the data.
  486. * Returns the sum of values returned by func, if it exists.
  487. * @param self Database
  488. * @param func Function to be applied to every entry before deleting
  489. * @param ... Extra arguments for func
  490. * @return Sum of values returned by func
  491. * @protected
  492. * @see DBMap#vclear(DBMap*,DBApply,va_list)
  493. */
  494. int (*clear)(DBMap* self, DBApply func, ...);
  495. /**
  496. * Removes all entries from the database.
  497. * Before deleting an entry, func is applied to it.
  498. * Releases the key and the data.
  499. * Returns the sum of values returned by func, if it exists.
  500. * @param self Database
  501. * @param func Function to be applied to every entry before deleting
  502. * @param args Extra arguments for func
  503. * @return Sum of values returned by func
  504. * @protected
  505. * @see DBMap#clear(DBMap*,DBApply,...)
  506. */
  507. int (*vclear)(DBMap* self, DBApply func, va_list args);
  508. /**
  509. * Just calls {@link DBMap#vdestroy}.
  510. * Finalize the database, feeing all the memory it uses.
  511. * Before deleting an entry, func is applied to it.
  512. * Releases the key and the data.
  513. * Returns the sum of values returned by func, if it exists.
  514. * NOTE: This locks the database globally. Any attempt to insert or remove
  515. * a database entry will give an error and be aborted (except for clearing).
  516. * @param self Database
  517. * @param func Function to be applied to every entry before deleting
  518. * @param ... Extra arguments for func
  519. * @return Sum of values returned by func
  520. * @protected
  521. * @see DBMap#vdestroy(DBMap*,DBApply,va_list)
  522. */
  523. int (*destroy)(DBMap* self, DBApply func, ...);
  524. /**
  525. * Finalize the database, feeing all the memory it uses.
  526. * Before deleting an entry, func is applied to it.
  527. * Returns the sum of values returned by func, if it exists.
  528. * NOTE: This locks the database globally. Any attempt to insert or remove
  529. * a database entry will give an error and be aborted (except for clearing).
  530. * @param self Database
  531. * @param func Function to be applied to every entry before deleting
  532. * @param args Extra arguments for func
  533. * @return Sum of values returned by func
  534. * @protected
  535. * @see DBMap#destroy(DBMap*,DBApply,...)
  536. */
  537. int (*vdestroy)(DBMap* self, DBApply func, va_list args);
  538. /**
  539. * Return the size of the database (number of items in the database).
  540. * @param self Database
  541. * @return Size of the database
  542. * @protected
  543. */
  544. unsigned int (*size)(DBMap* self);
  545. /**
  546. * Return the type of the database.
  547. * @param self Database
  548. * @return Type of the database
  549. * @protected
  550. */
  551. DBType (*type)(DBMap* self);
  552. /**
  553. * Return the options of the database.
  554. * @param self Database
  555. * @return Options of the database
  556. * @protected
  557. */
  558. DBOptions (*options)(DBMap* self);
  559. };
  560. // For easy access to the common functions.
  561. #define db_exists(db,k) ( (db)->exists((db),(k)) )
  562. #define idb_exists(db,k) ( (db)->exists((db),db_i2key(k)) )
  563. #define uidb_exists(db,k) ( (db)->exists((db),db_ui2key(k)) )
  564. #define strdb_exists(db,k) ( (db)->exists((db),db_str2key(k)) )
  565. #define i64db_exists(db,k) ( (db)->exists((db),db_i642key(k)) )
  566. #define ui64db_exists(db,k) ( (db)->exists((db),db_ui642key(k)) )
  567. // Get pointer-type data from DBMaps of various key types
  568. #define db_get(db,k) ( db_data2ptr((db)->get((db),(k))) )
  569. #define idb_get(db,k) ( db_data2ptr((db)->get((db),db_i2key(k))) )
  570. #define uidb_get(db,k) ( db_data2ptr((db)->get((db),db_ui2key(k))) )
  571. #define strdb_get(db,k) ( db_data2ptr((db)->get((db),db_str2key(k))) )
  572. #define i64db_get(db,k) ( db_data2ptr((db)->get((db),db_i642key(k))) )
  573. #define ui64db_get(db,k) ( db_data2ptr((db)->get((db),db_ui642key(k))) )
  574. // Get int-type data from DBMaps of various key types
  575. #define db_iget(db,k) ( db_data2i((db)->get((db),(k))) )
  576. #define idb_iget(db,k) ( db_data2i((db)->get((db),db_i2key(k))) )
  577. #define uidb_iget(db,k) ( db_data2i((db)->get((db),db_ui2key(k))) )
  578. #define strdb_iget(db,k) ( db_data2i((db)->get((db),db_str2key(k))) )
  579. #define i64db_iget(db,k) ( db_data2i((db)->get((db),db_i642key(k))) )
  580. #define ui64db_iget(db,k) ( db_data2i((db)->get((db),db_ui642key(k))) )
  581. // Get uint-type data from DBMaps of various key types
  582. #define db_uiget(db,k) ( db_data2ui((db)->get((db),(k))) )
  583. #define idb_uiget(db,k) ( db_data2ui((db)->get((db),db_i2key(k))) )
  584. #define uidb_uiget(db,k) ( db_data2ui((db)->get((db),db_ui2key(k))) )
  585. #define strdb_uiget(db,k) ( db_data2ui((db)->get((db),db_str2key(k))) )
  586. #define i64db_uiget(db,k) ( db_data2ui((db)->get((db),db_i642key(k))) )
  587. #define ui64db_uiget(db,k) ( db_data2ui((db)->get((db),db_ui642key(k))) )
  588. // Get int64-type data from DBMaps of various key types
  589. #define db_i64get(db,k) ( db_data2i64((db)->get((db),(k))) )
  590. #define idb_i64get(db,k) ( db_data2i64((db)->get((db),db_i2key(k))) )
  591. #define uidb_i64get(db,k) ( db_data2i64((db)->get((db),db_ui2key(k))) )
  592. #define strdb_i64get(db,k) ( db_data2i64((db)->get((db),db_str2key(k))) )
  593. #define i64db_i64get(db,k) ( db_data2i64((db)->get((db),db_i642key(k))) )
  594. #define ui64db_i64get(db,k) ( db_data2i64((db)->get((db),db_ui642key(k))) )
  595. // Put pointer-type data into DBMaps of various key types
  596. #define db_put(db,k,d) ( (db)->put((db),(k),db_ptr2data(d),NULL) )
  597. #define idb_put(db,k,d) ( (db)->put((db),db_i2key(k),db_ptr2data(d),NULL) )
  598. #define uidb_put(db,k,d) ( (db)->put((db),db_ui2key(k),db_ptr2data(d),NULL) )
  599. #define strdb_put(db,k,d) ( (db)->put((db),db_str2key(k),db_ptr2data(d),NULL) )
  600. #define i64db_put(db,k,d) ( (db)->put((db),db_i642key(k),db_ptr2data(d),NULL) )
  601. #define ui64db_put(db,k,d) ( (db)->put((db),db_ui642key(k),db_ptr2data(d),NULL) )
  602. // Put int-type data into DBMaps of various key types
  603. #define db_iput(db,k,d) ( (db)->put((db),(k),db_i2data(d),NULL) )
  604. #define idb_iput(db,k,d) ( (db)->put((db),db_i2key(k),db_i2data(d),NULL) )
  605. #define uidb_iput(db,k,d) ( (db)->put((db),db_ui2key(k),db_i2data(d),NULL) )
  606. #define strdb_iput(db,k,d) ( (db)->put((db),db_str2key(k),db_i2data(d),NULL) )
  607. #define i64db_iput(db,k,d) ( (db)->put((db),db_i642key(k),db_i2data(d),NULL) )
  608. #define ui64db_iput(db,k,d) ( (db)->put((db),db_ui642key(k),db_i2data(d),NULL) )
  609. // Put uint-type data into DBMaps of various key types
  610. #define db_uiput(db,k,d) ( (db)->put((db),(k),db_ui2data(d),NULL) )
  611. #define idb_uiput(db,k,d) ( (db)->put((db),db_i2key(k),db_ui2data(d),NULL) )
  612. #define uidb_uiput(db,k,d) ( (db)->put((db),db_ui2key(k),db_ui2data(d),NULL) )
  613. #define strdb_uiput(db,k,d) ( (db)->put((db),db_str2key(k),db_ui2data(d),NULL) )
  614. #define i64db_uiput(db,k,d) ( (db)->put((db),db_i642key(k),db_ui2data(d),NULL) )
  615. #define ui64db_uiput(db,k,d) ( (db)->put((db),db_ui642key(k),db_ui2data(d),NULL) )
  616. // Put int64 data into DBMaps of various key types
  617. #define db_i64put(db,k,d) ( (db)->put((db),(k),db_i642data(d),NULL) )
  618. #define idb_i64put(db,k,d) ( (db)->put((db),db_i2key(k),db_i642data(d),NULL) )
  619. #define uidb_i64put(db,k,d) ( (db)->put((db),db_ui2key(k),db_i642data(d),NULL) )
  620. #define strdb_i64put(db,k,d) ( (db)->put((db),db_str2key(k),db_i642data(d),NULL) )
  621. #define i64db_i64put(db,k,d) ( (db)->put((db),db_i642key(k),db_i642data(d),NULL) )
  622. #define ui64db_i64put(db,k,d) ( (db)->put((db),db_ui642key(k),db_i642data(d),NULL) )
  623. // Remove entry from DBMaps of various key types
  624. #define db_remove(db,k) ( (db)->remove((db),(k),NULL) )
  625. #define idb_remove(db,k) ( (db)->remove((db),db_i2key(k),NULL) )
  626. #define uidb_remove(db,k) ( (db)->remove((db),db_ui2key(k),NULL) )
  627. #define strdb_remove(db,k) ( (db)->remove((db),db_str2key(k),NULL) )
  628. #define i64db_remove(db,k) ( (db)->remove((db),db_i642key(k),NULL) )
  629. #define ui64db_remove(db,k) ( (db)->remove((db),db_ui642key(k),NULL) )
  630. //These are discarding the possible vargs you could send to the function, so those
  631. //that require vargs must not use these defines.
  632. #define db_ensure(db,k,f) ( db_data2ptr((db)->ensure((db),(k),(f))) )
  633. #define idb_ensure(db,k,f) ( db_data2ptr((db)->ensure((db),db_i2key(k),(f))) )
  634. #define uidb_ensure(db,k,f) ( db_data2ptr((db)->ensure((db),db_ui2key(k),(f))) )
  635. #define strdb_ensure(db,k,f) ( db_data2ptr((db)->ensure((db),db_str2key(k),(f))) )
  636. #define i64db_ensure(db,k,f) ( db_data2ptr((db)->ensure((db),db_i642key(k),(f))) )
  637. #define ui64db_ensure(db,k,f) ( db_data2ptr((db)->ensure((db),db_ui642key(k),(f))) )
  638. // Database creation and destruction macros
  639. #define idb_alloc(opt) db_alloc(__FILE__,__func__,__LINE__,DB_INT,(opt),sizeof(int))
  640. #define uidb_alloc(opt) db_alloc(__FILE__,__func__,__LINE__,DB_UINT,(opt),sizeof(unsigned int))
  641. #define strdb_alloc(opt,maxlen) db_alloc(__FILE__,__func__,__LINE__,DB_STRING,(opt),(maxlen))
  642. #define stridb_alloc(opt,maxlen) db_alloc(__FILE__,__func__,__LINE__,DB_ISTRING,(opt),(maxlen))
  643. #define i64db_alloc(opt) db_alloc(__FILE__,__func__,__LINE__,DB_INT64,(opt),sizeof(int64))
  644. #define ui64db_alloc(opt) db_alloc(__FILE__,__func__,__LINE__,DB_UINT64,(opt),sizeof(uint64))
  645. #define db_destroy(db) ( (db)->destroy((db),NULL) )
  646. // Other macros
  647. #define db_clear(db) ( (db)->clear((db),NULL) )
  648. #define db_size(db) ( (db)->size(db) )
  649. #define db_iterator(db) ( (db)->iterator(db) )
  650. #define dbi_first(dbi) ( db_data2ptr((dbi)->first((dbi),NULL)) )
  651. #define dbi_last(dbi) ( db_data2ptr((dbi)->last((dbi),NULL)) )
  652. #define dbi_next(dbi) ( db_data2ptr((dbi)->next((dbi),NULL)) )
  653. #define dbi_prev(dbi) ( db_data2ptr((dbi)->prev((dbi),NULL)) )
  654. #define dbi_remove(dbi) ( (dbi)->remove((dbi),NULL) )
  655. #define dbi_exists(dbi) ( (dbi)->exists(dbi) )
  656. #define dbi_destroy(dbi) ( (dbi)->destroy(dbi) )
  657. /*****************************************************************************\
  658. * (2) Section with public functions. *
  659. * db_fix_options - Fix the options for a type of database. *
  660. * db_default_cmp - Get the default comparator for a type of database. *
  661. * db_default_hash - Get the default hasher for a type of database. *
  662. * db_default_release - Get the default releaser for a type of database *
  663. * with the fixed options. *
  664. * db_custom_release - Get the releaser that behaves as specified. *
  665. * db_alloc - Allocate a new database. *
  666. * db_i2key - Manual cast from 'int' to 'DBKey'. *
  667. * db_ui2key - Manual cast from 'unsigned int' to 'DBKey'. *
  668. * db_str2key - Manual cast from 'unsigned char *' to 'DBKey'. *
  669. * db_i642key - Manual cast from 'int64' to 'DBKey'. *
  670. * db_ui642key - Manual cast from 'uint64' to 'DBKey'. *
  671. * db_i2data - Manual cast from 'int' to 'DBData'. *
  672. * db_ui2data - Manual cast from 'unsigned int' to 'DBData'. *
  673. * db_ptr2data - Manual cast from 'void*' to 'DBData'. *
  674. * db_data2i - Gets 'int' value from 'DBData'. *
  675. * db_data2ui - Gets 'unsigned int' value from 'DBData'. *
  676. * db_data2ptr - Gets 'void*' value from 'DBData'. *
  677. * db_init - Initializes the database system. *
  678. * db_final - Finalizes the database system. *
  679. \*****************************************************************************/
  680. /**
  681. * Returns the fixed options according to the database type.
  682. * Sets required options and unsets unsupported options.
  683. * For numeric databases DB_OPT_DUP_KEY and DB_OPT_RELEASE_KEY are unset.
  684. * @param type Type of the database
  685. * @param options Original options of the database
  686. * @return Fixed options of the database
  687. * @private
  688. * @see #DBType
  689. * @see #DBOptions
  690. * @see #db_default_release(DBType,DBOptions)
  691. */
  692. DBOptions db_fix_options(DBType type, DBOptions options);
  693. /**
  694. * Returns the default comparator for the type of database.
  695. * @param type Type of database
  696. * @return Comparator for the type of database or NULL if unknown database
  697. * @public
  698. * @see #DBType
  699. * @see #DBComparator
  700. */
  701. DBComparator db_default_cmp(DBType type);
  702. /**
  703. * Returns the default hasher for the specified type of database.
  704. * @param type Type of database
  705. * @return Hasher of the type of database or NULL if unknown database
  706. * @public
  707. * @see #DBType
  708. * @see #DBHasher
  709. */
  710. DBHasher db_default_hash(DBType type);
  711. /**
  712. * Returns the default releaser for the specified type of database with the
  713. * specified options.
  714. * NOTE: the options are fixed by {@link #db_fix_options(DBType,DBOptions)}
  715. * before choosing the releaser
  716. * @param type Type of database
  717. * @param options Options of the database
  718. * @return Default releaser for the type of database with the fixed options
  719. * @public
  720. * @see #DBType
  721. * @see #DBOptions
  722. * @see #DBReleaser
  723. * @see #db_fix_options(DBType,DBOptions)
  724. * @see #db_custom_release(DBRelease)
  725. */
  726. DBReleaser db_default_release(DBType type, DBOptions options);
  727. /**
  728. * Returns the releaser that behaves as <code>which</code> specifies.
  729. * @param which Defines what the releaser releases
  730. * @return Releaser for the specified release options
  731. * @public
  732. * @see #DBRelease
  733. * @see #DBReleaser
  734. * @see #db_default_release(DBType,DBOptions)
  735. */
  736. DBReleaser db_custom_release(DBRelease which);
  737. /**
  738. * Allocate a new database of the specified type.
  739. * It uses the default comparator, hasher and releaser of the specified
  740. * database type and fixed options.
  741. * NOTE: the options are fixed by {@link #db_fix_options(DBType,DBOptions)}
  742. * before creating the database.
  743. * @param file File where the database is being allocated
  744. * @param line Line of the file where the database is being allocated
  745. * @param type Type of database
  746. * @param options Options of the database
  747. * @param maxlen Maximum length of the string to be used as key in string
  748. * databases. If 0, the maximum number of maxlen is used (64K).
  749. * @return The interface of the database
  750. * @public
  751. * @see #DBType
  752. * @see #DBMap
  753. * @see #db_default_cmp(DBType)
  754. * @see #db_default_hash(DBType)
  755. * @see #db_default_release(DBType,DBOptions)
  756. * @see #db_fix_options(DBType,DBOptions)
  757. */
  758. DBMap* db_alloc(const char *file, const char *func, int line, DBType type, DBOptions options, unsigned short maxlen);
  759. /**
  760. * Manual cast from 'int' to the union DBKey.
  761. * @param key Key to be casted
  762. * @return The key as a DBKey union
  763. * @public
  764. */
  765. DBKey db_i2key(int key);
  766. /**
  767. * Manual cast from 'unsigned int' to the union DBKey.
  768. * @param key Key to be casted
  769. * @return The key as a DBKey union
  770. * @public
  771. */
  772. DBKey db_ui2key(unsigned int key);
  773. /**
  774. * Manual cast from 'unsigned char *' to the union DBKey.
  775. * @param key Key to be casted
  776. * @return The key as a DBKey union
  777. * @public
  778. */
  779. DBKey db_str2key(const char *key);
  780. /**
  781. * Manual cast from 'int64' to the union DBKey.
  782. * @param key Key to be casted
  783. * @return The key as a DBKey union
  784. * @public
  785. */
  786. DBKey db_i642key(int64 key);
  787. /**
  788. * Manual cast from 'uint64' to the union DBKey.
  789. * @param key Key to be casted
  790. * @return The key as a DBKey union
  791. * @public
  792. */
  793. DBKey db_ui642key(uint64 key);
  794. /**
  795. * Manual cast from 'int' to the struct DBData.
  796. * @param data Data to be casted
  797. * @return The data as a DBData struct
  798. * @public
  799. */
  800. DBData db_i2data(int data);
  801. /**
  802. * Manual cast from 'unsigned int' to the struct DBData.
  803. * @param data Data to be casted
  804. * @return The data as a DBData struct
  805. * @public
  806. */
  807. DBData db_ui2data(unsigned int data);
  808. /**
  809. * Manual cast from 'void *' to the struct DBData.
  810. * @param data Data to be casted
  811. * @return The data as a DBData struct
  812. * @public
  813. */
  814. DBData db_ptr2data(void *data);
  815. /**
  816. * Manual cast from 'int64' to the struct DBData.
  817. * @param data Data to be casted
  818. * @return The data as a DBData struct
  819. * @public
  820. */
  821. DBData db_i642data(int64 data);
  822. /**
  823. * Gets int type data from struct DBData.
  824. * If data is not int type, returns 0.
  825. * @param data Data
  826. * @return Integer value of the data.
  827. * @public
  828. */
  829. int db_data2i(DBData *data);
  830. /**
  831. * Gets unsigned int type data from struct DBData.
  832. * If data is not unsigned int type, returns 0.
  833. * @param data Data
  834. * @return Unsigned int value of the data.
  835. * @public
  836. */
  837. unsigned int db_data2ui(DBData *data);
  838. /**
  839. * Gets void* type data from struct DBData.
  840. * If data is not void* type, returns NULL.
  841. * @param data Data
  842. * @return Void* value of the data.
  843. * @public
  844. */
  845. void* db_data2ptr(DBData *data);
  846. /**
  847. * Gets int64 type data from struct DBData.
  848. * If data is not int64 type, returns 0.
  849. * @param data Data
  850. * @return Integer(64-bit signed) value of the data.
  851. * @public
  852. */
  853. int64 db_data2i64(DBData *data);
  854. /**
  855. * Initialize the database system.
  856. * @public
  857. * @see #db_final(void)
  858. */
  859. void db_init(void);
  860. /**
  861. * Finalize the database system.
  862. * Frees the memory used by the block reusage system.
  863. * @public
  864. * @see #db_init(void)
  865. */
  866. void db_final(void);
  867. // Link DB System - From jAthena
  868. struct linkdb_node {
  869. struct linkdb_node *next;
  870. struct linkdb_node *prev;
  871. void *key;
  872. void *data;
  873. };
  874. typedef void (*LinkDBFunc)(void* key, void* data, va_list args);
  875. void linkdb_insert (struct linkdb_node** head, void *key, void* data); // Doesn't take into account duplicate keys
  876. void linkdb_replace (struct linkdb_node** head, void *key, void* data); // Takes into account duplicate keys
  877. void* linkdb_search (struct linkdb_node** head, void *key);
  878. void* linkdb_erase (struct linkdb_node** head, void *key);
  879. void linkdb_final (struct linkdb_node** head);
  880. void linkdb_vforeach(struct linkdb_node** head, LinkDBFunc func, va_list ap);
  881. void linkdb_foreach (struct linkdb_node** head, LinkDBFunc func, ...);
  882. /// Finds an entry in an array.
  883. /// ex: ARR_FIND(0, size, i, list[i] == target);
  884. ///
  885. /// @param __start Starting index (ex: 0)
  886. /// @param __end End index (ex: size of the array)
  887. /// @param __var Index variable
  888. /// @param __cmp Expression that returns true when the target entry is found
  889. #define ARR_FIND(__start, __end, __var, __cmp) \
  890. do{ \
  891. for( (__var) = (__start); (__var) < (__end); ++(__var) ) \
  892. if( __cmp ) \
  893. break; \
  894. }while(0)
  895. /// Moves an entry of the array.
  896. /// Use ARR_MOVERIGHT/ARR_MOVELEFT if __from and __to are direct numbers.
  897. /// ex: ARR_MOVE(i, 0, list, int);// move index i to index 0
  898. ///
  899. ///
  900. /// @param __from Initial index of the entry
  901. /// @param __to Target index of the entry
  902. /// @param __arr Array
  903. /// @param __type Type of entry
  904. #define ARR_MOVE(__from, __to, __arr, __type) \
  905. do{ \
  906. if( (__from) != (__to) ) \
  907. { \
  908. __type __backup__; \
  909. memmove(&__backup__, (__arr)+(__from), sizeof(__type)); \
  910. if( (__from) < (__to) ) \
  911. memmove((__arr)+(__from), (__arr)+(__from)+1, ((__to)-(__from))*sizeof(__type)); \
  912. else if( (__from) > (__to) ) \
  913. memmove((__arr)+(__to)+1, (__arr)+(__to), ((__from)-(__to))*sizeof(__type)); \
  914. memmove((__arr)+(__to), &__backup__, sizeof(__type)); \
  915. } \
  916. }while(0)
  917. /// Moves an entry of the array to the right.
  918. /// ex: ARR_MOVERIGHT(1, 4, list, int);// move index 1 to index 4
  919. ///
  920. /// @param __from Initial index of the entry
  921. /// @param __to Target index of the entry
  922. /// @param __arr Array
  923. /// @param __type Type of entry
  924. #define ARR_MOVERIGHT(__from, __to, __arr, __type) \
  925. do{ \
  926. __type __backup__; \
  927. memmove(&__backup__, (__arr)+(__from), sizeof(__type)); \
  928. memmove((__arr)+(__from), (__arr)+(__from)+1, ((__to)-(__from))*sizeof(__type)); \
  929. memmove((__arr)+(__to), &__backup__, sizeof(__type)); \
  930. }while(0)
  931. /// Moves an entry of the array to the left.
  932. /// ex: ARR_MOVELEFT(3, 0, list, int);// move index 3 to index 0
  933. ///
  934. /// @param __from Initial index of the entry
  935. /// @param __end Target index of the entry
  936. /// @param __arr Array
  937. /// @param __type Type of entry
  938. #define ARR_MOVELEFT(__from, __to, __arr, __type) \
  939. do{ \
  940. __type __backup__; \
  941. memmove(&__backup__, (__arr)+(__from), sizeof(__type)); \
  942. memmove((__arr)+(__to)+1, (__arr)+(__to), ((__from)-(__to))*sizeof(__type)); \
  943. memmove((__arr)+(__to), &__backup__, sizeof(__type)); \
  944. }while(0)
  945. /////////////////////////////////////////////////////////////////////
  946. // Vector library based on defines. (dynamic array)
  947. // uses aMalloc, aRealloc, aFree
  948. /// Declares an anonymous vector struct.
  949. ///
  950. /// @param __type Type of data
  951. #define VECTOR_DECL(__type) \
  952. struct { \
  953. size_t _max_; \
  954. size_t _len_; \
  955. __type* _data_; \
  956. }
  957. /// Declares a named vector struct.
  958. ///
  959. /// @param __name Structure name
  960. /// @param __type Type of data
  961. #define VECTOR_STRUCT_DECL(__name,__type) \
  962. struct __name { \
  963. size_t _max_; \
  964. size_t _len_; \
  965. __type* _data_; \
  966. }
  967. /// Declares and initializes an anonymous vector variable.
  968. ///
  969. /// @param __type Type of data
  970. /// @param __var Variable name
  971. #define VECTOR_VAR(__type,__var) \
  972. VECTOR_DECL(__type) __var = {0,0,NULL}
  973. /// Declares and initializes a named vector variable.
  974. ///
  975. /// @param __name Structure name
  976. /// @param __var Variable name
  977. #define VECTOR_STRUCT_VAR(__name,__var) \
  978. struct __name __var = {0,0,NULL}
  979. /// Initializes a vector.
  980. ///
  981. /// @param __vec Vector
  982. #define VECTOR_INIT(__vec) \
  983. memset(&(__vec), 0, sizeof(__vec))
  984. /// Returns the internal array of values.
  985. ///
  986. /// @param __vec Vector
  987. /// @return Array of values
  988. #define VECTOR_DATA(__vec) \
  989. ( (__vec)._data_ )
  990. /// Returns the length of the vector.
  991. ///
  992. /// @param __vec Vector
  993. /// @return Length
  994. #define VECTOR_LENGTH(__vec) \
  995. ( (__vec)._len_ )
  996. /// Returns the capacity of the vector.
  997. ///
  998. /// @param __vec Vector
  999. /// @return Capacity
  1000. #define VECTOR_CAPACITY(__vec) \
  1001. ( (__vec)._max_ )
  1002. /// Returns the value at the target index.
  1003. /// Assumes the index exists.
  1004. ///
  1005. /// @param __vec Vector
  1006. /// @param __idx Index
  1007. /// @return Value
  1008. #define VECTOR_INDEX(__vec,__idx) \
  1009. ( VECTOR_DATA(__vec)[__idx] )
  1010. /// Returns the first value of the vector.
  1011. /// Assumes the array is not empty.
  1012. ///
  1013. /// @param __vec Vector
  1014. /// @return First value
  1015. #define VECTOR_FIRST(__vec) \
  1016. ( VECTOR_INDEX(__vec,0) )
  1017. /// Returns the last value of the vector.
  1018. /// Assumes the array is not empty.
  1019. ///
  1020. /// @param __vec Vector
  1021. /// @return Last value
  1022. #define VECTOR_LAST(__vec) \
  1023. ( VECTOR_INDEX(__vec,VECTOR_LENGTH(__vec)-1) )
  1024. /// Resizes the vector.
  1025. /// Excess values are discarded, new positions are zeroed.
  1026. ///
  1027. /// @param __vec Vector
  1028. /// @param __n Size
  1029. #define VECTOR_RESIZE(__vec,__n,__cast) \
  1030. do{ \
  1031. if( (__n) > VECTOR_CAPACITY(__vec) ) \
  1032. { /* increase size */ \
  1033. if( VECTOR_CAPACITY(__vec) == 0 ) VECTOR_DATA(__vec) = (__cast)(aMalloc((__n)*sizeof(VECTOR_FIRST(__vec))) ); /* allocate new */ \
  1034. else VECTOR_DATA(__vec) = (__cast)(aRealloc(VECTOR_DATA(__vec),(__n)*sizeof(VECTOR_FIRST(__vec))) ); /* reallocate */ \
  1035. memset(VECTOR_DATA(__vec)+VECTOR_LENGTH(__vec), 0, (VECTOR_CAPACITY(__vec)-VECTOR_LENGTH(__vec))*sizeof(VECTOR_FIRST(__vec))); /* clear new data */ \
  1036. VECTOR_CAPACITY(__vec) = (__n); /* update capacity */ \
  1037. } \
  1038. else if( (__n) == 0 && VECTOR_CAPACITY(__vec) ) \
  1039. { /* clear vector */ \
  1040. aFree(VECTOR_DATA(__vec)); VECTOR_DATA(__vec) = NULL; /* free data */ \
  1041. VECTOR_CAPACITY(__vec) = 0; /* clear capacity */ \
  1042. VECTOR_LENGTH(__vec) = 0; /* clear length */ \
  1043. } \
  1044. else if( (__n) < VECTOR_CAPACITY(__vec) ) \
  1045. { /* reduce size */ \
  1046. VECTOR_DATA(__vec) = (__cast)(aRealloc(VECTOR_DATA(__vec),(__n)*sizeof(VECTOR_FIRST(__vec))) ); /* reallocate */ \
  1047. VECTOR_CAPACITY(__vec) = (__n); /* update capacity */ \
  1048. if( VECTOR_LENGTH(__vec) > (__n) ) VECTOR_LENGTH(__vec) = (__n); /* update length */ \
  1049. } \
  1050. }while(0)
  1051. /// Ensures that the array has the target number of empty positions.
  1052. /// Increases the capacity in multiples of __step.
  1053. ///
  1054. /// @param __vec Vector
  1055. /// @param __n Empty positions
  1056. /// @param __step Increase
  1057. #define VECTOR_ENSURE2(__vec,__n,__step,__cast) \
  1058. do{ \
  1059. size_t _empty_ = VECTOR_CAPACITY(__vec)-VECTOR_LENGTH(__vec); \
  1060. if( (__n) > _empty_ ) { \
  1061. while( (__n) > _empty_ ) _empty_ += (__step); \
  1062. VECTOR_RESIZE(__vec,_empty_+VECTOR_LENGTH(__vec),__cast); \
  1063. } \
  1064. }while(0)
  1065. #define VECTOR_ENSURE(__vec,__n,__step) VECTOR_ENSURE2(__vec,__n,__step,int*)
  1066. /// Inserts a zeroed value in the target index.
  1067. /// Assumes the index is valid and there is enough capacity.
  1068. ///
  1069. /// @param __vec Vector
  1070. /// @param __idx Index
  1071. #define VECTOR_INSERTZEROED(__vec,__idx) \
  1072. do{ \
  1073. if( (__idx) < VECTOR_LENGTH(__vec) ) /* move data */ \
  1074. memmove(&VECTOR_INDEX(__vec,(__idx)+1),&VECTOR_INDEX(__vec,__idx),(VECTOR_LENGTH(__vec)-(__idx))*sizeof(VECTOR_FIRST(__vec))); \
  1075. memset(&VECTOR_INDEX(__vec,__idx), 0, sizeof(VECTOR_INDEX(__vec,__idx))); /* set zeroed value */ \
  1076. ++VECTOR_LENGTH(__vec); /* increase length */ \
  1077. }while(0)
  1078. /// Inserts a value in the target index. (using the '=' operator)
  1079. /// Assumes the index is valid and there is enough capacity.
  1080. ///
  1081. /// @param __vec Vector
  1082. /// @param __idx Index
  1083. /// @param __val Value
  1084. #define VECTOR_INSERT(__vec,__idx,__val) \
  1085. do{ \
  1086. if( (__idx) < VECTOR_LENGTH(__vec) ) /* move data */ \
  1087. memmove(&VECTOR_INDEX(__vec,(__idx)+1),&VECTOR_INDEX(__vec,__idx),(VECTOR_LENGTH(__vec)-(__idx))*sizeof(VECTOR_FIRST(__vec))); \
  1088. VECTOR_INDEX(__vec,__idx) = (__val); /* set value */ \
  1089. ++VECTOR_LENGTH(__vec); /* increase length */ \
  1090. }while(0)
  1091. /// Inserts a value in the target index. (using memcpy)
  1092. /// Assumes the index is valid and there is enough capacity.
  1093. ///
  1094. /// @param __vec Vector
  1095. /// @param __idx Index
  1096. /// @param __val Value
  1097. #define VECTOR_INSERTCOPY(__vec,__idx,__val) \
  1098. VECTOR_INSERTARRAY(__vec,__idx,&(__val),1)
  1099. /// Inserts the values of the array in the target index. (using memcpy)
  1100. /// Assumes the index is valid and there is enough capacity.
  1101. ///
  1102. /// @param __vec Vector
  1103. /// @param __idx Index
  1104. /// @param __pval Array of values
  1105. /// @param __n Number of values
  1106. #define VECTOR_INSERTARRAY(__vec,__idx,__pval,__n) \
  1107. do{ \
  1108. if( (__idx) < VECTOR_LENGTH(__vec) ) /* move data */ \
  1109. memmove(&VECTOR_INDEX(__vec,(__idx)+(__n)),&VECTOR_INDEX(__vec,__idx),(VECTOR_LENGTH(__vec)-(__idx))*sizeof(VECTOR_FIRST(__vec))); \
  1110. memcpy(&VECTOR_INDEX(__vec,__idx), (__pval), (__n)*sizeof(VECTOR_FIRST(__vec))); /* set values */ \
  1111. VECTOR_LENGTH(__vec) += (__n); /* increase length */ \
  1112. }while(0)
  1113. /// Inserts a zeroed value in the end of the vector.
  1114. /// Assumes there is enough capacity.
  1115. ///
  1116. /// @param __vec Vector
  1117. #define VECTOR_PUSHZEROED(__vec) \
  1118. do{ \
  1119. memset(&VECTOR_INDEX(__vec,VECTOR_LENGTH(__vec)), 0, sizeof(VECTOR_INDEX(__vec,VECTOR_LENGTH(__vec)))); /* set zeroed value */ \
  1120. ++VECTOR_LENGTH(__vec); /* increase length */ \
  1121. }while(0)
  1122. /// Inserts a value in the end of the vector. (using the '=' operator)
  1123. /// Assumes there is enough capacity.
  1124. ///
  1125. /// @param __vec Vector
  1126. /// @param __val Value
  1127. #define VECTOR_PUSH(__vec,__val) \
  1128. do{ \
  1129. VECTOR_INDEX(__vec,VECTOR_LENGTH(__vec)) = (__val); /* set value */ \
  1130. ++VECTOR_LENGTH(__vec); /* increase length */ \
  1131. }while(0)
  1132. /// Inserts a value in the end of the vector. (using memcpy)
  1133. /// Assumes there is enough capacity.
  1134. ///
  1135. /// @param __vec Vector
  1136. /// @param __val Value
  1137. #define VECTOR_PUSHCOPY(__vec,__val) \
  1138. VECTOR_PUSHARRAY(__vec,&(__val),1)
  1139. /// Inserts the values of the array in the end of the vector. (using memcpy)
  1140. /// Assumes there is enough capacity.
  1141. ///
  1142. /// @param __vec Vector
  1143. /// @param __pval Array of values
  1144. /// @param __n Number of values
  1145. #define VECTOR_PUSHARRAY(__vec,__pval,__n) \
  1146. do{ \
  1147. memcpy(&VECTOR_INDEX(__vec,VECTOR_LENGTH(__vec)), (__pval), (__n)*sizeof(VECTOR_FIRST(__vec))); /* set values */ \
  1148. VECTOR_LENGTH(__vec) += (__n); /* increase length */ \
  1149. }while(0)
  1150. /// Removes and returns the last value of the vector.
  1151. /// Assumes the array is not empty.
  1152. ///
  1153. /// @param __vec Vector
  1154. /// @return Removed value
  1155. #define VECTOR_POP(__vec) \
  1156. ( VECTOR_INDEX(__vec,--VECTOR_LENGTH(__vec)) )
  1157. /// Removes the last N values of the vector and returns the value of the last pop.
  1158. /// Assumes there are enough values.
  1159. ///
  1160. /// @param __vec Vector
  1161. /// @param __n Number of pops
  1162. /// @return Last removed value
  1163. #define VECTOR_POPN(__vec,__n) \
  1164. ( VECTOR_INDEX(__vec,(VECTOR_LENGTH(__vec)-=(__n))) )
  1165. /// Removes the target index from the vector.
  1166. /// Assumes the index is valid and there are enough values.
  1167. ///
  1168. /// @param __vec Vector
  1169. /// @param __idx Index
  1170. #define VECTOR_ERASE(__vec,__idx) \
  1171. VECTOR_ERASEN(__vec,__idx,1)
  1172. /// Removes N values from the target index of the vector.
  1173. /// Assumes the index is valid and there are enough values.
  1174. ///
  1175. /// @param __vec Vector
  1176. /// @param __idx Index
  1177. /// @param __n Number of values
  1178. #define VECTOR_ERASEN(__vec,__idx,__n) \
  1179. do{ \
  1180. if( (__idx) < VECTOR_LENGTH(__vec)-(__n) ) /* move data */ \
  1181. memmove(&VECTOR_INDEX(__vec,__idx),&VECTOR_INDEX(__vec,(__idx)+(__n)),(VECTOR_LENGTH(__vec)-((__idx)+(__n)))*sizeof(VECTOR_FIRST(__vec))); \
  1182. VECTOR_LENGTH(__vec) -= (__n); /* decrease length */ \
  1183. }while(0)
  1184. /// Clears the vector, freeing allocated data.
  1185. ///
  1186. /// @param __vec Vector
  1187. #define VECTOR_CLEAR(__vec) \
  1188. do{ \
  1189. if( VECTOR_CAPACITY(__vec) ) \
  1190. { \
  1191. aFree(VECTOR_DATA(__vec)); VECTOR_DATA(__vec) = NULL; /* clear allocated array */ \
  1192. VECTOR_CAPACITY(__vec) = 0; /* clear capacity */ \
  1193. VECTOR_LENGTH(__vec) = 0; /* clear length */ \
  1194. } \
  1195. }while(0)
  1196. /// Resets the length and clears content, so the vector is empty
  1197. ///
  1198. /// @param __vec Vector
  1199. #define VECTOR_RESET(__vec) \
  1200. if( VECTOR_LENGTH(__vec) > 0 ) { \
  1201. memset(VECTOR_DATA(__vec), 0, (VECTOR_LENGTH(__vec)*sizeof(VECTOR_FIRST(__vec)))); /* clear data */ \
  1202. } \
  1203. VECTOR_LENGTH(__vec) = 0; /* clear current length */
  1204. /////////////////////////////////////////////////////////////////////
  1205. // Binary heap library based on defines. (uses the vector defines above)
  1206. // uses aMalloc, aRealloc, aFree
  1207. // WARNING: BHEAP implementation details affect behaviour of A* pathfinding
  1208. /// Declares an anonymous binary heap struct.
  1209. ///
  1210. /// @param __type Type of data
  1211. #define BHEAP_DECL(__type) VECTOR_DECL(__type)
  1212. /// Declares a named binary heap struct.
  1213. ///
  1214. /// @param __name Structure name
  1215. /// @param __type Type of data
  1216. #define BHEAP_STRUCT_DECL(__name,__type) VECTOR_STRUCT_DECL(__name,__type)
  1217. /// Declares and initializes an anonymous binary heap variable.
  1218. ///
  1219. /// @param __type Type of data
  1220. /// @param __var Variable name
  1221. #define BHEAP_VAR(__type,__var) VECTOR_VAR(__type,__var)
  1222. /// Declares and initializes a named binary heap variable.
  1223. ///
  1224. /// @param __name Structure name
  1225. /// @param __var Variable name
  1226. #define BHEAP_STRUCT_VAR(__name,__var) VECTOR_STRUCT_VAR(__name,__var)
  1227. /// Initializes a heap.
  1228. ///
  1229. /// @param __heap Binary heap
  1230. #define BHEAP_INIT(__heap) VECTOR_INIT(__heap)
  1231. /// Returns the internal array of values.
  1232. ///
  1233. /// @param __heap Binary heap
  1234. /// @return Array of values
  1235. #define BHEAP_DATA(__heap) VECTOR_DATA(__heap)
  1236. /// Returns the length of the heap.
  1237. ///
  1238. /// @param __heap Binary heap
  1239. /// @return Length
  1240. #define BHEAP_LENGTH(__heap) VECTOR_LENGTH(__heap)
  1241. /// Returns the capacity of the heap.
  1242. ///
  1243. /// @param __heap Binary heap
  1244. /// @return Capacity
  1245. #define BHEAP_CAPACITY(__heap) VECTOR_CAPACITY(__heap)
  1246. /// Ensures that the heap has the target number of empty positions.
  1247. /// Increases the capacity in multiples of __step.
  1248. ///
  1249. /// @param __heap Binary heap
  1250. /// @param __n Empty positions
  1251. /// @param __step Increase
  1252. #define BHEAP_ENSURE(__heap,__n,__step) VECTOR_ENSURE(__heap,__n,__step)
  1253. #define BHEAP_ENSURE2(__heap,__n,__step,__cast) VECTOR_ENSURE2(__heap,__n,__step,__cast)
  1254. /// Returns the top value of the heap.
  1255. /// Assumes the heap is not empty.
  1256. ///
  1257. /// @param __heap Binary heap
  1258. /// @return Value at the top
  1259. #define BHEAP_PEEK(__heap) VECTOR_INDEX(__heap,0)
  1260. /// Inserts a value in the heap. (using the '=' operator)
  1261. /// Assumes there is enough capacity.
  1262. ///
  1263. /// The comparator takes two values as arguments, returns:
  1264. /// - negative if the first value is on the top
  1265. /// - positive if the second value is on the top
  1266. /// - 0 if they are equal
  1267. ///
  1268. /// @param __heap Binary heap
  1269. /// @param __val Value
  1270. /// @param __topcmp Comparator
  1271. /// @param __swp Swapper
  1272. #define BHEAP_PUSH(__heap,__val,__topcmp,__swp) \
  1273. do{ \
  1274. size_t _i_ = VECTOR_LENGTH(__heap); \
  1275. VECTOR_PUSH(__heap,__val); /* insert at end */ \
  1276. while( _i_ ) \
  1277. { /* restore heap property in parents */ \
  1278. size_t _parent_ = (_i_-1)/2; \
  1279. if( __topcmp(VECTOR_INDEX(__heap,_parent_),VECTOR_INDEX(__heap,_i_)) < 0 ) \
  1280. break; /* done */ \
  1281. __swp(VECTOR_INDEX(__heap,_parent_),VECTOR_INDEX(__heap,_i_)); \
  1282. _i_ = _parent_; \
  1283. } \
  1284. }while(0)
  1285. /// See BHEAP_PUSH. Version used by A* implementation, matching client bheap.
  1286. ///
  1287. /// @param __heap Binary heap
  1288. /// @param __val Value
  1289. /// @param __topcmp Comparator
  1290. /// @param __swp Swapper
  1291. #define BHEAP_PUSH2(__heap,__val,__topcmp,__swp) \
  1292. do{ \
  1293. size_t _i_ = VECTOR_LENGTH(__heap); \
  1294. VECTOR_PUSH(__heap,__val); /* insert at end */ \
  1295. BHEAP_SIFTDOWN(__heap,0,_i_,__topcmp,__swp); \
  1296. }while(0)
  1297. /// Removes the top value of the heap. (using the '=' operator)
  1298. /// Assumes the heap is not empty.
  1299. ///
  1300. /// The comparator takes two values as arguments, returns:
  1301. /// - negative if the first value is on the top
  1302. /// - positive if the second value is on the top
  1303. /// - 0 if they are equal
  1304. ///
  1305. /// @param __heap Binary heap
  1306. /// @param __topcmp Comparator
  1307. /// @param __swp Swapper
  1308. #define BHEAP_POP(__heap,__topcmp,__swp) BHEAP_POPINDEX(__heap,0,__topcmp,__swp)
  1309. /// See BHEAP_POP. Version used by A* implementation, matching client bheap.
  1310. ///
  1311. /// @param __heap Binary heap
  1312. /// @param __topcmp Comparator
  1313. /// @param __swp Swapper
  1314. #define BHEAP_POP2(__heap,__topcmp,__swp) \
  1315. do{ \
  1316. VECTOR_INDEX(__heap,0) = VECTOR_POP(__heap); /* put last at index */ \
  1317. if( !VECTOR_LENGTH(__heap) ) /* removed last, nothing to do */ \
  1318. break; \
  1319. BHEAP_SIFTUP(__heap,0,__topcmp,__swp); \
  1320. }while(0)
  1321. /// Removes the target value of the heap. (using the '=' operator)
  1322. /// Assumes the index exists.
  1323. ///
  1324. /// The comparator takes two values as arguments, returns:
  1325. /// - negative if the first value is on the top
  1326. /// - positive if the second value is on the top
  1327. /// - 0 if they are equal
  1328. ///
  1329. /// @param __heap Binary heap
  1330. /// @param __idx Index
  1331. /// @param __topcmp Comparator
  1332. /// @param __swp Swapper
  1333. #define BHEAP_POPINDEX(__heap,__idx,__topcmp,__swp) \
  1334. do{ \
  1335. size_t _i_ = __idx; \
  1336. VECTOR_INDEX(__heap,__idx) = VECTOR_POP(__heap); /* put last at index */ \
  1337. if( _i_ >= VECTOR_LENGTH(__heap)) /* removed last, nothing to do */ \
  1338. break; \
  1339. while( _i_ ) \
  1340. { /* restore heap property in parents */ \
  1341. size_t _parent_ = (_i_-1)/2; \
  1342. if( __topcmp(VECTOR_INDEX(__heap,_parent_),VECTOR_INDEX(__heap,_i_)) < 0 ) \
  1343. break; /* done */ \
  1344. __swp(VECTOR_INDEX(__heap,_parent_),VECTOR_INDEX(__heap,_i_)); \
  1345. _i_ = _parent_; \
  1346. } \
  1347. while( _i_ < VECTOR_LENGTH(__heap) ) \
  1348. { /* restore heap property in childs */ \
  1349. size_t _lchild_ = _i_*2 + 1; \
  1350. size_t _rchild_ = _i_*2 + 2; \
  1351. if( (_lchild_ >= VECTOR_LENGTH(__heap) || __topcmp(VECTOR_INDEX(__heap,_i_),VECTOR_INDEX(__heap,_lchild_)) <= 0) && \
  1352. (_rchild_ >= VECTOR_LENGTH(__heap) || __topcmp(VECTOR_INDEX(__heap,_i_),VECTOR_INDEX(__heap,_rchild_)) <= 0) ) \
  1353. break; /* done */ \
  1354. else if( _rchild_ >= VECTOR_LENGTH(__heap) || __topcmp(VECTOR_INDEX(__heap,_lchild_),VECTOR_INDEX(__heap,_rchild_)) <= 0 ) \
  1355. { /* left child */ \
  1356. __swp(VECTOR_INDEX(__heap,_i_),VECTOR_INDEX(__heap,_lchild_)); \
  1357. _i_ = _lchild_; \
  1358. } \
  1359. else \
  1360. { /* right child */ \
  1361. __swp(VECTOR_INDEX(__heap,_i_),VECTOR_INDEX(__heap,_rchild_)); \
  1362. _i_ = _rchild_; \
  1363. } \
  1364. } \
  1365. }while(0)
  1366. /// Follow path up towards (but not all the way to) the root, swapping nodes until finding
  1367. /// a place where the new item that was placed at __idx fits.
  1368. /// Only goes as high as __startidx (usually 0).
  1369. ///
  1370. /// @param __heap Binary heap
  1371. /// @param __startidx Index of an ancestor of __idx
  1372. /// @param __idx Index of an inserted element
  1373. /// @param __topcmp Comparator
  1374. /// @param __swp Swapper
  1375. #define BHEAP_SIFTDOWN(__heap,__startidx,__idx,__topcmp,__swp) \
  1376. do{ \
  1377. size_t _i2_ = __idx; \
  1378. while( _i2_ > __startidx ) \
  1379. { /* restore heap property in parents */ \
  1380. size_t _parent_ = (_i2_-1)/2; \
  1381. if( __topcmp(VECTOR_INDEX(__heap,_parent_),VECTOR_INDEX(__heap,_i2_)) <= 0 ) \
  1382. break; /* done */ \
  1383. __swp(VECTOR_INDEX(__heap,_parent_),VECTOR_INDEX(__heap,_i2_)); \
  1384. _i2_ = _parent_; \
  1385. } \
  1386. }while(0)
  1387. /// Repeatedly swap the smaller child with parent, after placing a new item at __idx.
  1388. ///
  1389. /// @param __heap Binary heap
  1390. /// @param __idx Index of an inserted element
  1391. /// @param __topcmp Comparator
  1392. /// @param __swp Swapper
  1393. #define BHEAP_SIFTUP(__heap,__idx,__topcmp,__swp) \
  1394. do{ \
  1395. size_t _i_ = __idx; \
  1396. size_t _lchild_ = _i_*2 + 1; \
  1397. while( _lchild_ < VECTOR_LENGTH(__heap) ) \
  1398. { /* restore heap property in childs */ \
  1399. size_t _rchild_ = _i_*2 + 2; \
  1400. if( _rchild_ >= VECTOR_LENGTH(__heap) || __topcmp(VECTOR_INDEX(__heap,_lchild_),VECTOR_INDEX(__heap,_rchild_)) < 0 ) \
  1401. { /* left child */ \
  1402. __swp(VECTOR_INDEX(__heap,_i_),VECTOR_INDEX(__heap,_lchild_)); \
  1403. _i_ = _lchild_; \
  1404. } \
  1405. else \
  1406. { /* right child */ \
  1407. __swp(VECTOR_INDEX(__heap,_i_),VECTOR_INDEX(__heap,_rchild_)); \
  1408. _i_ = _rchild_; \
  1409. } \
  1410. _lchild_ = _i_*2 + 1; \
  1411. } \
  1412. BHEAP_SIFTDOWN(__heap,__idx,_i_,__topcmp,__swp); \
  1413. }while(0)
  1414. /// Call this after modifying the item at __idx__ to restore the heap
  1415. ///
  1416. /// @param __heap Binary heap
  1417. /// @param __idx Index
  1418. /// @param __topcmp Comparator
  1419. /// @param __swp Swapper
  1420. #define BHEAP_UPDATE(__heap,__idx,__topcmp,__swp) \
  1421. do{ \
  1422. BHEAP_SIFTDOWN(__heap,0,__idx,__topcmp,__swp); \
  1423. BHEAP_SIFTUP(__heap,__idx,__topcmp,__swp); \
  1424. }while(0)
  1425. /// Clears the binary heap, freeing allocated data.
  1426. ///
  1427. /// @param __heap Binary heap
  1428. #define BHEAP_CLEAR(__heap) VECTOR_CLEAR(__heap)
  1429. /// Resets the binary heap and clears content so it can be treated as empty
  1430. ///
  1431. /// @parm __heap Binary heap
  1432. #define BHEAP_RESET(__heap) VECTOR_RESET(__heap)
  1433. /// Generic comparator for a min-heap. (minimum value at top)
  1434. /// Returns -1 if v1 is smaller, 1 if v2 is smaller, 0 if equal.
  1435. ///
  1436. /// @param v1 First value
  1437. /// @param v2 Second value
  1438. /// @return negative if v1 is top, positive if v2 is top, 0 if equal
  1439. #define BHEAP_MINTOPCMP(v1,v2) ( v1 == v2 ? 0 : v1 < v2 ? -1 : 1 )
  1440. /// Generic comparator for a max-heap. (maximum value at top)
  1441. /// Returns -1 if v1 is bigger, 1 if v2 is bigger, 0 if equal.
  1442. ///
  1443. /// @param v1 First value
  1444. /// @param v2 Second value
  1445. /// @return negative if v1 is top, positive if v2 is top, 0 if equal
  1446. #define BHEAP_MAXTOPCMP(v1,v2) ( v1 == v2 ? 0 : v1 > v2 ? -1 : 1 )
  1447. #endif /* DB_HPP */