c_test.c 161 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244
  1. /* Copyright (c) 2011 The LevelDB Authors. All rights reserved.
  2. Use of this source code is governed by a BSD-style license that can be
  3. found in the LICENSE file. See the AUTHORS file for names of contributors. */
  4. // Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
  5. #include "rocksdb/c.h"
  6. #include <assert.h>
  7. #include <stddef.h>
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #include <string.h>
  11. #include <sys/types.h>
  12. #ifndef OS_WIN
  13. #include <unistd.h>
  14. #endif
  15. #include <inttypes.h>
  16. // Can not use port/port.h macros as this is a c file
  17. #ifdef OS_WIN
  18. #include <windows.h>
  19. // Ok for uniqueness
  20. int geteuid() {
  21. int result = 0;
  22. result = ((int)GetCurrentProcessId() << 16);
  23. result |= (int)GetCurrentThreadId();
  24. return result;
  25. }
  26. #endif
  27. const char* phase = "";
  28. static char dbname[200];
  29. static char sstfilename[200];
  30. static char dbbackupname[200];
  31. static char dbcheckpointname[200];
  32. static char dbpathname[200];
  33. static char secondary_path[200];
  34. static void StartPhase(const char* name) {
  35. fprintf(stderr, "=== Test %s\n", name);
  36. phase = name;
  37. }
  38. #ifdef _MSC_VER
  39. #pragma warning(push)
  40. #pragma warning(disable : 4996) // getenv security warning
  41. #endif
  42. static const char* GetTempDir(void) {
  43. const char* ret = getenv("TEST_TMPDIR");
  44. if (ret == NULL || ret[0] == '\0') {
  45. #ifdef OS_WIN
  46. ret = getenv("TEMP");
  47. #else
  48. ret = "/tmp";
  49. #endif
  50. }
  51. return ret;
  52. }
  53. #ifdef _MSC_VER
  54. #pragma warning(pop)
  55. #endif
  56. #define CheckNoError(err) \
  57. if ((err) != NULL) { \
  58. fprintf(stderr, "%s:%d: %s: %s\n", __FILE__, __LINE__, phase, (err)); \
  59. abort(); \
  60. }
  61. #define CheckCondition(cond) \
  62. if (!(cond)) { \
  63. fprintf(stderr, "%s:%d: %s: %s\n", __FILE__, __LINE__, phase, #cond); \
  64. abort(); \
  65. }
  66. static void CheckEqual(const char* expected, const char* v, size_t n) {
  67. if (expected == NULL && v == NULL) {
  68. // ok
  69. } else if (expected != NULL && v != NULL && n == strlen(expected) &&
  70. memcmp(expected, v, n) == 0) {
  71. // ok
  72. return;
  73. } else {
  74. fprintf(stderr, "%s: expected '%s', got '%s'\n", phase,
  75. (expected ? expected : "(null)"), (v ? v : "(null)"));
  76. abort();
  77. }
  78. }
  79. static void Free(char** ptr) {
  80. if (*ptr) {
  81. free(*ptr);
  82. *ptr = NULL;
  83. }
  84. }
  85. static void CheckValue(char* err, const char* expected, char** actual,
  86. size_t actual_length) {
  87. CheckNoError(err);
  88. CheckEqual(expected, *actual, actual_length);
  89. Free(actual);
  90. }
  91. static void CheckPinnedValue(char* err, const char* expected,
  92. const char** actual, size_t actual_length) {
  93. CheckNoError(err);
  94. CheckEqual(expected, *actual, actual_length);
  95. }
  96. static void CheckGet(rocksdb_t* db, const rocksdb_readoptions_t* options,
  97. const char* key, const char* expected) {
  98. char* err = NULL;
  99. size_t val_len;
  100. char* val;
  101. val = rocksdb_get(db, options, key, strlen(key), &val_len, &err);
  102. CheckNoError(err);
  103. CheckEqual(expected, val, val_len);
  104. Free(&val);
  105. }
  106. static void CheckGetCF(rocksdb_t* db, const rocksdb_readoptions_t* options,
  107. rocksdb_column_family_handle_t* handle, const char* key,
  108. const char* expected) {
  109. char* err = NULL;
  110. size_t val_len;
  111. char* val;
  112. val = rocksdb_get_cf(db, options, handle, key, strlen(key), &val_len, &err);
  113. CheckNoError(err);
  114. CheckEqual(expected, val, val_len);
  115. Free(&val);
  116. }
  117. static void CheckPinGet(rocksdb_t* db, const rocksdb_readoptions_t* options,
  118. const char* key, const char* expected) {
  119. char* err = NULL;
  120. size_t val_len;
  121. const char* val;
  122. rocksdb_pinnableslice_t* p;
  123. p = rocksdb_get_pinned(db, options, key, strlen(key), &err);
  124. CheckNoError(err);
  125. val = rocksdb_pinnableslice_value(p, &val_len);
  126. CheckEqual(expected, val, val_len);
  127. rocksdb_pinnableslice_destroy(p);
  128. }
  129. static void CheckPinGetCF(rocksdb_t* db, const rocksdb_readoptions_t* options,
  130. rocksdb_column_family_handle_t* handle,
  131. const char* key, const char* expected) {
  132. char* err = NULL;
  133. size_t val_len;
  134. const char* val;
  135. rocksdb_pinnableslice_t* p;
  136. p = rocksdb_get_pinned_cf(db, options, handle, key, strlen(key), &err);
  137. CheckNoError(err);
  138. val = rocksdb_pinnableslice_value(p, &val_len);
  139. CheckEqual(expected, val, val_len);
  140. rocksdb_pinnableslice_destroy(p);
  141. }
  142. static void CheckMultiGetValues(size_t num_keys, char** values,
  143. size_t* values_sizes, char** errs,
  144. const char** expected) {
  145. for (size_t i = 0; i < num_keys; i++) {
  146. CheckNoError(errs[i]);
  147. CheckEqual(expected[i], values[i], values_sizes[i]);
  148. Free(&values[i]);
  149. }
  150. }
  151. static void CheckIter(rocksdb_iterator_t* iter, const char* key,
  152. const char* val) {
  153. size_t len;
  154. const char* str;
  155. str = rocksdb_iter_key(iter, &len);
  156. CheckEqual(key, str, len);
  157. str = rocksdb_iter_value(iter, &len);
  158. CheckEqual(val, str, len);
  159. }
  160. // Callback from rocksdb_writebatch_iterate()
  161. static void CheckPut(void* ptr, const char* k, size_t klen, const char* v,
  162. size_t vlen) {
  163. int* state = (int*)ptr;
  164. CheckCondition(*state < 2);
  165. switch (*state) {
  166. case 0:
  167. CheckEqual("bar", k, klen);
  168. CheckEqual("b", v, vlen);
  169. break;
  170. case 1:
  171. CheckEqual("box", k, klen);
  172. CheckEqual("c", v, vlen);
  173. break;
  174. }
  175. (*state)++;
  176. }
  177. // Callback from rocksdb_writebatch_iterate()
  178. static void CheckDel(void* ptr, const char* k, size_t klen) {
  179. int* state = (int*)ptr;
  180. CheckCondition(*state == 2);
  181. CheckEqual("bar", k, klen);
  182. (*state)++;
  183. }
  184. // Callback from rocksdb_writebatch_iterate_cf()
  185. static void CheckPutCF(void* ptr, uint32_t cfid, const char* k, size_t klen,
  186. const char* v, size_t vlen) {
  187. int* state = (int*)ptr;
  188. switch (*state) {
  189. case 0:
  190. CheckEqual("bar", k, klen);
  191. CheckEqual("b", v, vlen);
  192. CheckCondition(cfid == 1);
  193. break;
  194. case 1:
  195. CheckEqual("box", k, klen);
  196. CheckEqual("c", v, vlen);
  197. CheckCondition(cfid == 1);
  198. break;
  199. case 4:
  200. CheckEqual("foo", k, klen);
  201. CheckEqual("f", v, vlen);
  202. CheckCondition(cfid == 0);
  203. break;
  204. case 6:
  205. CheckEqual("baz", k, klen);
  206. CheckEqual("a", v, vlen);
  207. CheckCondition(cfid == 0);
  208. break;
  209. default:
  210. CheckCondition(false);
  211. break;
  212. }
  213. (*state)++;
  214. }
  215. // Callback from rocksdb_writebatch_iterate_cf()
  216. static void CheckDelCF(void* ptr, uint32_t cfid, const char* k, size_t klen) {
  217. int* state = (int*)ptr;
  218. switch (*state) {
  219. case 2:
  220. CheckEqual("bar", k, klen);
  221. CheckCondition(cfid == 1);
  222. break;
  223. case 5:
  224. CheckEqual("foo", k, klen);
  225. CheckCondition(cfid == 0);
  226. break;
  227. default:
  228. CheckCondition(false);
  229. break;
  230. }
  231. (*state)++;
  232. }
  233. // Callback from rocksdb_writebatch_iterate_cf()
  234. static void CheckMergeCF(void* ptr, uint32_t cfid, const char* k, size_t klen,
  235. const char* v, size_t vlen) {
  236. int* state = (int*)ptr;
  237. switch (*state) {
  238. case 3:
  239. CheckEqual("box", k, klen);
  240. CheckEqual("cc", v, vlen);
  241. CheckCondition(cfid == 1);
  242. break;
  243. case 7:
  244. CheckEqual("baz", k, klen);
  245. CheckEqual("aa", v, vlen);
  246. CheckCondition(cfid == 0);
  247. break;
  248. default:
  249. CheckCondition(false);
  250. break;
  251. }
  252. (*state)++;
  253. }
  254. static void CmpDestroy(void* arg) { (void)arg; }
  255. static int CmpCompare(void* arg, const char* a, size_t alen, const char* b,
  256. size_t blen) {
  257. (void)arg;
  258. size_t n = (alen < blen) ? alen : blen;
  259. int r = memcmp(a, b, n);
  260. if (r == 0) {
  261. if (alen < blen) {
  262. r = -1;
  263. } else if (alen > blen) {
  264. r = +1;
  265. }
  266. }
  267. return r;
  268. }
  269. static const char* CmpName(void* arg) {
  270. (void)arg;
  271. return "foo";
  272. }
  273. // Custom compaction filter
  274. static void CFilterDestroy(void* arg) { (void)arg; }
  275. static const char* CFilterName(void* arg) {
  276. (void)arg;
  277. return "foo";
  278. }
  279. static unsigned char CFilterFilter(void* arg, int level, const char* key,
  280. size_t key_length,
  281. const char* existing_value,
  282. size_t value_length, char** new_value,
  283. size_t* new_value_length,
  284. unsigned char* value_changed) {
  285. (void)arg;
  286. (void)level;
  287. (void)existing_value;
  288. (void)value_length;
  289. if (key_length == 3) {
  290. if (memcmp(key, "bar", key_length) == 0) {
  291. return 1;
  292. } else if (memcmp(key, "baz", key_length) == 0) {
  293. *value_changed = 1;
  294. *new_value = "newbazvalue";
  295. *new_value_length = 11;
  296. return 0;
  297. }
  298. }
  299. return 0;
  300. }
  301. static void CFilterFactoryDestroy(void* arg) { (void)arg; }
  302. static const char* CFilterFactoryName(void* arg) {
  303. (void)arg;
  304. return "foo";
  305. }
  306. static rocksdb_compactionfilter_t* CFilterCreate(
  307. void* arg, rocksdb_compactionfiltercontext_t* context) {
  308. (void)arg;
  309. (void)context;
  310. return rocksdb_compactionfilter_create(NULL, CFilterDestroy, CFilterFilter,
  311. CFilterName);
  312. }
  313. void CheckMetaData(rocksdb_column_family_metadata_t* cf_meta,
  314. const char* expected_cf_name) {
  315. char* cf_name = rocksdb_column_family_metadata_get_name(cf_meta);
  316. assert(strcmp(cf_name, expected_cf_name) == 0);
  317. rocksdb_free(cf_name);
  318. size_t cf_size = rocksdb_column_family_metadata_get_size(cf_meta);
  319. assert(cf_size > 0);
  320. size_t cf_file_count = rocksdb_column_family_metadata_get_size(cf_meta);
  321. assert(cf_file_count > 0);
  322. uint64_t total_level_size = 0;
  323. size_t total_file_count = 0;
  324. size_t level_count = rocksdb_column_family_metadata_get_level_count(cf_meta);
  325. assert(level_count > 0);
  326. for (size_t l = 0; l < level_count; ++l) {
  327. rocksdb_level_metadata_t* level_meta =
  328. rocksdb_column_family_metadata_get_level_metadata(cf_meta, l);
  329. assert(level_meta);
  330. assert(rocksdb_level_metadata_get_level(level_meta) >= (int)l);
  331. uint64_t level_size = rocksdb_level_metadata_get_size(level_meta);
  332. uint64_t file_size_in_level = 0;
  333. size_t file_count = rocksdb_level_metadata_get_file_count(level_meta);
  334. total_file_count += file_count;
  335. for (size_t f = 0; f < file_count; ++f) {
  336. rocksdb_sst_file_metadata_t* file_meta =
  337. rocksdb_level_metadata_get_sst_file_metadata(level_meta, f);
  338. assert(file_meta);
  339. uint64_t file_size = rocksdb_sst_file_metadata_get_size(file_meta);
  340. assert(file_size > 0);
  341. file_size_in_level += file_size;
  342. char* file_name =
  343. rocksdb_sst_file_metadata_get_relative_filename(file_meta);
  344. assert(file_name);
  345. assert(strlen(file_name) > 0);
  346. rocksdb_free(file_name);
  347. size_t smallest_key_len;
  348. char* smallest_key = rocksdb_sst_file_metadata_get_smallestkey(
  349. file_meta, &smallest_key_len);
  350. assert(smallest_key);
  351. assert(smallest_key_len > 0);
  352. size_t largest_key_len;
  353. char* largest_key =
  354. rocksdb_sst_file_metadata_get_largestkey(file_meta, &largest_key_len);
  355. assert(largest_key);
  356. assert(largest_key_len > 0);
  357. rocksdb_free(smallest_key);
  358. rocksdb_free(largest_key);
  359. rocksdb_sst_file_metadata_destroy(file_meta);
  360. }
  361. assert(level_size == file_size_in_level);
  362. total_level_size += level_size;
  363. rocksdb_level_metadata_destroy(level_meta);
  364. }
  365. assert(total_file_count > 0);
  366. assert(cf_size == total_level_size);
  367. }
  368. void GetAndCheckMetaData(rocksdb_t* db) {
  369. rocksdb_column_family_metadata_t* cf_meta =
  370. rocksdb_get_column_family_metadata(db);
  371. CheckMetaData(cf_meta, "default");
  372. rocksdb_column_family_metadata_destroy(cf_meta);
  373. }
  374. void GetAndCheckMetaDataCf(rocksdb_t* db,
  375. rocksdb_column_family_handle_t* handle,
  376. const char* cf_name) {
  377. // Compact to make sure we have at least one sst file to obtain datadata.
  378. rocksdb_compact_range_cf(db, handle, NULL, 0, NULL, 0);
  379. rocksdb_column_family_metadata_t* cf_meta =
  380. rocksdb_get_column_family_metadata_cf(db, handle);
  381. CheckMetaData(cf_meta, cf_name);
  382. rocksdb_column_family_metadata_destroy(cf_meta);
  383. }
  384. static rocksdb_t* CheckCompaction(rocksdb_t* db, rocksdb_options_t* options,
  385. rocksdb_readoptions_t* roptions,
  386. rocksdb_writeoptions_t* woptions) {
  387. char* err = NULL;
  388. db = rocksdb_open(options, dbname, &err);
  389. CheckNoError(err);
  390. rocksdb_put(db, woptions, "foo", 3, "foovalue", 8, &err);
  391. CheckNoError(err);
  392. CheckGet(db, roptions, "foo", "foovalue");
  393. rocksdb_put(db, woptions, "bar", 3, "barvalue", 8, &err);
  394. CheckNoError(err);
  395. CheckGet(db, roptions, "bar", "barvalue");
  396. rocksdb_put(db, woptions, "baz", 3, "bazvalue", 8, &err);
  397. CheckNoError(err);
  398. CheckGet(db, roptions, "baz", "bazvalue");
  399. // Disable compaction
  400. rocksdb_disable_manual_compaction(db);
  401. rocksdb_compact_range(db, NULL, 0, NULL, 0);
  402. // should not filter anything when disabled
  403. CheckGet(db, roptions, "foo", "foovalue");
  404. CheckGet(db, roptions, "bar", "barvalue");
  405. CheckGet(db, roptions, "baz", "bazvalue");
  406. // Reenable compaction
  407. rocksdb_enable_manual_compaction(db);
  408. // Force compaction
  409. rocksdb_compact_range(db, NULL, 0, NULL, 0);
  410. rocksdb_wait_for_compact_options_t* wco;
  411. wco = rocksdb_wait_for_compact_options_create();
  412. rocksdb_wait_for_compact(db, wco, &err);
  413. CheckNoError(err);
  414. rocksdb_wait_for_compact_options_destroy(wco);
  415. // should have filtered bar, but not foo
  416. CheckGet(db, roptions, "foo", "foovalue");
  417. CheckGet(db, roptions, "bar", NULL);
  418. CheckGet(db, roptions, "baz", "newbazvalue");
  419. rocksdb_suggest_compact_range(db, "bar", 3, "foo", 3, &err);
  420. GetAndCheckMetaData(db);
  421. CheckNoError(err);
  422. return db;
  423. }
  424. // Custom merge operator
  425. static void MergeOperatorDestroy(void* arg) { (void)arg; }
  426. static const char* MergeOperatorName(void* arg) {
  427. (void)arg;
  428. return "TestMergeOperator";
  429. }
  430. static char* MergeOperatorFullMerge(
  431. void* arg, const char* key, size_t key_length, const char* existing_value,
  432. size_t existing_value_length, const char* const* operands_list,
  433. const size_t* operands_list_length, int num_operands,
  434. unsigned char* success, size_t* new_value_length) {
  435. (void)arg;
  436. (void)key;
  437. (void)key_length;
  438. (void)existing_value;
  439. (void)existing_value_length;
  440. (void)operands_list;
  441. (void)operands_list_length;
  442. (void)num_operands;
  443. *new_value_length = 4;
  444. *success = 1;
  445. char* result = malloc(4);
  446. memcpy(result, "fake", 4);
  447. return result;
  448. }
  449. static char* MergeOperatorPartialMerge(void* arg, const char* key,
  450. size_t key_length,
  451. const char* const* operands_list,
  452. const size_t* operands_list_length,
  453. int num_operands, unsigned char* success,
  454. size_t* new_value_length) {
  455. (void)arg;
  456. (void)key;
  457. (void)key_length;
  458. (void)operands_list;
  459. (void)operands_list_length;
  460. (void)num_operands;
  461. *new_value_length = 4;
  462. *success = 1;
  463. char* result = malloc(4);
  464. memcpy(result, "fake", 4);
  465. return result;
  466. }
  467. static void CheckTxnGet(rocksdb_transaction_t* txn,
  468. const rocksdb_readoptions_t* options, const char* key,
  469. const char* expected) {
  470. char* err = NULL;
  471. size_t val_len;
  472. char* val;
  473. val = rocksdb_transaction_get(txn, options, key, strlen(key), &val_len, &err);
  474. CheckNoError(err);
  475. CheckEqual(expected, val, val_len);
  476. Free(&val);
  477. }
  478. static void CheckTxnGetCF(rocksdb_transaction_t* txn,
  479. const rocksdb_readoptions_t* options,
  480. rocksdb_column_family_handle_t* column_family,
  481. const char* key, const char* expected) {
  482. char* err = NULL;
  483. size_t val_len;
  484. char* val;
  485. val = rocksdb_transaction_get_cf(txn, options, column_family, key,
  486. strlen(key), &val_len, &err);
  487. CheckNoError(err);
  488. CheckEqual(expected, val, val_len);
  489. Free(&val);
  490. }
  491. static void CheckTxnPinGet(rocksdb_transaction_t* txn,
  492. const rocksdb_readoptions_t* options,
  493. const char* key, const char* expected) {
  494. rocksdb_pinnableslice_t* p = NULL;
  495. const char* val = NULL;
  496. char* err = NULL;
  497. size_t val_len;
  498. p = rocksdb_transaction_get_pinned(txn, options, key, strlen(key), &err);
  499. CheckNoError(err);
  500. val = rocksdb_pinnableslice_value(p, &val_len);
  501. CheckEqual(expected, val, val_len);
  502. rocksdb_pinnableslice_destroy(p);
  503. }
  504. static void CheckTxnPinGetCF(rocksdb_transaction_t* txn,
  505. const rocksdb_readoptions_t* options,
  506. rocksdb_column_family_handle_t* column_family,
  507. const char* key, const char* expected) {
  508. rocksdb_pinnableslice_t* p = NULL;
  509. const char* val = NULL;
  510. char* err = NULL;
  511. size_t val_len;
  512. p = rocksdb_transaction_get_pinned_cf(txn, options, column_family, key,
  513. strlen(key), &err);
  514. CheckNoError(err);
  515. val = rocksdb_pinnableslice_value(p, &val_len);
  516. CheckEqual(expected, val, val_len);
  517. rocksdb_pinnableslice_destroy(p);
  518. }
  519. static void CheckTxnGetForUpdate(rocksdb_transaction_t* txn,
  520. const rocksdb_readoptions_t* options,
  521. const char* key, const char* expected) {
  522. char* err = NULL;
  523. size_t val_len;
  524. char* val;
  525. val = rocksdb_transaction_get_for_update(txn, options, key, strlen(key),
  526. &val_len, true, &err);
  527. CheckNoError(err);
  528. CheckEqual(expected, val, val_len);
  529. Free(&val);
  530. }
  531. static void CheckTxnDBGet(rocksdb_transactiondb_t* txn_db,
  532. const rocksdb_readoptions_t* options, const char* key,
  533. const char* expected) {
  534. char* err = NULL;
  535. size_t val_len;
  536. char* val;
  537. val = rocksdb_transactiondb_get(txn_db, options, key, strlen(key), &val_len,
  538. &err);
  539. CheckNoError(err);
  540. CheckEqual(expected, val, val_len);
  541. Free(&val);
  542. }
  543. static void CheckTxnDBGetCF(rocksdb_transactiondb_t* txn_db,
  544. const rocksdb_readoptions_t* options,
  545. rocksdb_column_family_handle_t* column_family,
  546. const char* key, const char* expected) {
  547. char* err = NULL;
  548. size_t val_len;
  549. char* val;
  550. val = rocksdb_transactiondb_get_cf(txn_db, options, column_family, key,
  551. strlen(key), &val_len, &err);
  552. CheckNoError(err);
  553. CheckEqual(expected, val, val_len);
  554. Free(&val);
  555. }
  556. static void CheckTxnGetForUpdateCF(
  557. rocksdb_transaction_t* txn, const rocksdb_readoptions_t* options,
  558. rocksdb_column_family_handle_t* column_family, const char* key,
  559. const char* expected) {
  560. char* err = NULL;
  561. size_t val_len;
  562. char* val;
  563. val = rocksdb_transaction_get_for_update_cf(
  564. txn, options, column_family, key, strlen(key), &val_len, true, &err);
  565. CheckNoError(err);
  566. CheckEqual(expected, val, val_len);
  567. Free(&val);
  568. }
  569. static void CheckTxnDBPinGet(rocksdb_transactiondb_t* txn_db,
  570. const rocksdb_readoptions_t* options,
  571. const char* key, const char* expected) {
  572. rocksdb_pinnableslice_t* p = NULL;
  573. const char* val = NULL;
  574. char* err = NULL;
  575. size_t val_len;
  576. p = rocksdb_transactiondb_get_pinned(txn_db, options, key, strlen(key), &err);
  577. CheckNoError(err);
  578. val = rocksdb_pinnableslice_value(p, &val_len);
  579. CheckEqual(expected, val, val_len);
  580. rocksdb_pinnableslice_destroy(p);
  581. }
  582. static void CheckTxnDBPinGetCF(rocksdb_transactiondb_t* txn_db,
  583. const rocksdb_readoptions_t* options,
  584. rocksdb_column_family_handle_t* column_family,
  585. const char* key, const char* expected) {
  586. rocksdb_pinnableslice_t* p = NULL;
  587. const char* val = NULL;
  588. char* err = NULL;
  589. size_t val_len;
  590. p = rocksdb_transactiondb_get_pinned_cf(txn_db, options, column_family, key,
  591. strlen(key), &err);
  592. CheckNoError(err);
  593. val = rocksdb_pinnableslice_value(p, &val_len);
  594. CheckEqual(expected, val, val_len);
  595. rocksdb_pinnableslice_destroy(p);
  596. }
  597. static void LoadAndCheckLatestOptions(const char* db_name, rocksdb_env_t* env,
  598. bool ignore_unknown_options,
  599. rocksdb_cache_t* cache,
  600. rocksdb_comparator_t* cmp,
  601. const size_t expected_num_column_families,
  602. const char** expected_cf_names,
  603. const char* expected_open_err) {
  604. rocksdb_options_t* db_options;
  605. size_t num_column_families;
  606. char** list_column_family_names;
  607. rocksdb_options_t** list_column_family_options;
  608. char* err = 0;
  609. // load the latest rocksdb option
  610. rocksdb_load_latest_options(db_name, env, ignore_unknown_options, cache,
  611. &db_options, &num_column_families,
  612. &list_column_family_names,
  613. &list_column_family_options, &err);
  614. assert(num_column_families == expected_num_column_families);
  615. CheckNoError(err);
  616. // verify the loaded options by opening the db.
  617. rocksdb_options_set_error_if_exists(db_options, 0);
  618. char** list_const_cf_names =
  619. (char**)malloc(num_column_families * sizeof(char*));
  620. rocksdb_options_t** list_const_cf_options = (rocksdb_options_t**)malloc(
  621. num_column_families * sizeof(rocksdb_options_t*));
  622. for (size_t i = 0; i < num_column_families; ++i) {
  623. assert(strcmp(list_column_family_names[i], expected_cf_names[i]) == 0);
  624. list_const_cf_names[i] = list_column_family_names[i];
  625. if (cmp) {
  626. rocksdb_options_set_comparator(list_column_family_options[i], cmp);
  627. }
  628. list_const_cf_options[i] = list_column_family_options[i];
  629. }
  630. rocksdb_column_family_handle_t** handles =
  631. (rocksdb_column_family_handle_t**)malloc(
  632. num_column_families * sizeof(rocksdb_column_family_handle_t*));
  633. rocksdb_t* db = rocksdb_open_column_families(
  634. db_options, db_name, (int)num_column_families,
  635. (const char* const*)list_const_cf_names,
  636. (const rocksdb_options_t* const*)list_const_cf_options, handles, &err);
  637. if (expected_open_err == NULL) {
  638. CheckNoError(err);
  639. for (size_t i = 0; i < num_column_families; ++i) {
  640. rocksdb_column_family_handle_destroy(handles[i]);
  641. }
  642. free(handles);
  643. rocksdb_close(db);
  644. } else {
  645. assert(err != NULL);
  646. assert(strcmp(err, expected_open_err) == 0);
  647. free(handles);
  648. free(err);
  649. }
  650. free(list_const_cf_names);
  651. free(list_const_cf_options);
  652. rocksdb_load_latest_options_destroy(db_options, list_column_family_names,
  653. list_column_family_options,
  654. num_column_families);
  655. }
  656. int main(int argc, char** argv) {
  657. (void)argc;
  658. (void)argv;
  659. rocksdb_t* db;
  660. rocksdb_comparator_t* cmp;
  661. rocksdb_cache_t* cache;
  662. rocksdb_dbpath_t* dbpath;
  663. rocksdb_env_t* env;
  664. rocksdb_options_t* options;
  665. rocksdb_compactoptions_t* coptions;
  666. rocksdb_block_based_table_options_t* table_options;
  667. rocksdb_readoptions_t* roptions;
  668. rocksdb_writeoptions_t* woptions;
  669. rocksdb_ratelimiter_t* rate_limiter;
  670. rocksdb_transactiondb_t* txn_db;
  671. rocksdb_transactiondb_options_t* txn_db_options;
  672. rocksdb_transaction_t* txn;
  673. rocksdb_transaction_options_t* txn_options;
  674. rocksdb_optimistictransactiondb_t* otxn_db;
  675. rocksdb_optimistictransaction_options_t* otxn_options;
  676. char* err = NULL;
  677. int run = -1;
  678. snprintf(dbname, sizeof(dbname), "%s/rocksdb_c_test-%d", GetTempDir(),
  679. ((int)geteuid()));
  680. snprintf(dbbackupname, sizeof(dbbackupname), "%s/rocksdb_c_test-%d-backup",
  681. GetTempDir(), ((int)geteuid()));
  682. snprintf(dbcheckpointname, sizeof(dbcheckpointname),
  683. "%s/rocksdb_c_test-%d-checkpoint", GetTempDir(), ((int)geteuid()));
  684. snprintf(sstfilename, sizeof(sstfilename), "%s/rocksdb_c_test-%d-sst",
  685. GetTempDir(), ((int)geteuid()));
  686. snprintf(dbpathname, sizeof(dbpathname), "%s/rocksdb_c_test-%d-dbpath",
  687. GetTempDir(), ((int)geteuid()));
  688. StartPhase("create_objects");
  689. cmp = rocksdb_comparator_create(NULL, CmpDestroy, CmpCompare, CmpName);
  690. dbpath = rocksdb_dbpath_create(dbpathname, 1024 * 1024);
  691. env = rocksdb_create_default_env();
  692. rocksdb_create_dir_if_missing(env, GetTempDir(), &err);
  693. CheckNoError(err);
  694. cache = rocksdb_cache_create_lru(100000);
  695. options = rocksdb_options_create();
  696. rocksdb_options_set_comparator(options, cmp);
  697. rocksdb_options_set_error_if_exists(options, 1);
  698. rocksdb_options_set_env(options, env);
  699. rocksdb_options_set_info_log(options, NULL);
  700. rocksdb_options_set_write_buffer_size(options, 100000);
  701. rocksdb_options_set_paranoid_checks(options, 1);
  702. rocksdb_options_set_max_open_files(options, 10);
  703. /* Compatibility with how test was written */
  704. rocksdb_options_set_write_dbid_to_manifest(options, 0);
  705. table_options = rocksdb_block_based_options_create();
  706. rocksdb_block_based_options_set_block_cache(table_options, cache);
  707. rocksdb_block_based_options_set_data_block_index_type(table_options, 1);
  708. rocksdb_block_based_options_set_data_block_hash_ratio(table_options, 0.75);
  709. rocksdb_block_based_options_set_top_level_index_pinning_tier(table_options,
  710. 1);
  711. rocksdb_block_based_options_set_partition_pinning_tier(table_options, 2);
  712. rocksdb_block_based_options_set_unpartitioned_pinning_tier(table_options, 3);
  713. rocksdb_options_set_block_based_table_factory(options, table_options);
  714. rocksdb_options_set_compression(options, rocksdb_no_compression);
  715. rocksdb_options_set_compression_options(options, -14, -1, 0, 0);
  716. int compression_levels[] = {rocksdb_no_compression, rocksdb_no_compression,
  717. rocksdb_no_compression, rocksdb_no_compression};
  718. rocksdb_options_set_compression_per_level(options, compression_levels, 4);
  719. rate_limiter = rocksdb_ratelimiter_create(1000 * 1024 * 1024, 100 * 1000, 10);
  720. rocksdb_options_set_ratelimiter(options, rate_limiter);
  721. rocksdb_ratelimiter_destroy(rate_limiter);
  722. rate_limiter =
  723. rocksdb_ratelimiter_create_auto_tuned(1000 * 1024 * 1024, 100 * 1000, 10);
  724. rocksdb_options_set_ratelimiter(options, rate_limiter);
  725. rocksdb_ratelimiter_destroy(rate_limiter);
  726. rate_limiter = rocksdb_ratelimiter_create_with_mode(1000 * 1024 * 1024,
  727. 100 * 1000, 10, 0, true);
  728. rocksdb_options_set_ratelimiter(options, rate_limiter);
  729. rocksdb_ratelimiter_destroy(rate_limiter);
  730. roptions = rocksdb_readoptions_create();
  731. rocksdb_readoptions_set_verify_checksums(roptions, 1);
  732. rocksdb_readoptions_set_fill_cache(roptions, 1);
  733. woptions = rocksdb_writeoptions_create();
  734. rocksdb_writeoptions_set_sync(woptions, 1);
  735. coptions = rocksdb_compactoptions_create();
  736. rocksdb_compactoptions_set_exclusive_manual_compaction(coptions, 1);
  737. rocksdb_options_add_compact_on_deletion_collector_factory(options, 10000,
  738. 10001);
  739. rocksdb_options_add_compact_on_deletion_collector_factory_del_ratio(
  740. options, 10000, 10001, 0.0);
  741. StartPhase("destroy");
  742. rocksdb_destroy_db(options, dbname, &err);
  743. Free(&err);
  744. StartPhase("open_error");
  745. rocksdb_open(options, dbname, &err);
  746. CheckCondition(err != NULL);
  747. Free(&err);
  748. StartPhase("open");
  749. rocksdb_options_set_create_if_missing(options, 1);
  750. db = rocksdb_open(options, dbname, &err);
  751. CheckNoError(err);
  752. CheckGet(db, roptions, "foo", NULL);
  753. StartPhase("put");
  754. rocksdb_put(db, woptions, "foo", 3, "hello", 5, &err);
  755. CheckNoError(err);
  756. CheckGet(db, roptions, "foo", "hello");
  757. StartPhase("backup_and_restore");
  758. {
  759. rocksdb_destroy_db(options, dbbackupname, &err);
  760. CheckNoError(err);
  761. rocksdb_backup_engine_t* be =
  762. rocksdb_backup_engine_open(options, dbbackupname, &err);
  763. CheckNoError(err);
  764. rocksdb_backup_engine_create_new_backup(be, db, &err);
  765. CheckNoError(err);
  766. // need a change to trigger a new backup
  767. rocksdb_delete(db, woptions, "does-not-exist", 14, &err);
  768. CheckNoError(err);
  769. rocksdb_backup_engine_create_new_backup(be, db, &err);
  770. CheckNoError(err);
  771. const rocksdb_backup_engine_info_t* bei =
  772. rocksdb_backup_engine_get_backup_info(be);
  773. CheckCondition(rocksdb_backup_engine_info_count(bei) > 1);
  774. rocksdb_backup_engine_info_destroy(bei);
  775. rocksdb_backup_engine_purge_old_backups(be, 1, &err);
  776. CheckNoError(err);
  777. bei = rocksdb_backup_engine_get_backup_info(be);
  778. CheckCondition(rocksdb_backup_engine_info_count(bei) == 1);
  779. rocksdb_backup_engine_info_destroy(bei);
  780. rocksdb_delete(db, woptions, "foo", 3, &err);
  781. CheckNoError(err);
  782. // get the identity before the backup
  783. size_t before_db_id_len = 0;
  784. char* before_db_id = rocksdb_get_db_identity(db, &before_db_id_len);
  785. CheckCondition(before_db_id_len == 36);
  786. rocksdb_close(db);
  787. rocksdb_destroy_db(options, dbname, &err);
  788. CheckNoError(err);
  789. rocksdb_restore_options_t* restore_options =
  790. rocksdb_restore_options_create();
  791. rocksdb_restore_options_set_keep_log_files(restore_options, 0);
  792. rocksdb_backup_engine_restore_db_from_latest_backup(be, dbname, dbname,
  793. restore_options, &err);
  794. CheckNoError(err);
  795. rocksdb_restore_options_destroy(restore_options);
  796. rocksdb_options_set_error_if_exists(options, 0);
  797. db = rocksdb_open(options, dbname, &err);
  798. CheckNoError(err);
  799. rocksdb_options_set_error_if_exists(options, 1);
  800. CheckGet(db, roptions, "foo", "hello");
  801. // the db_identity after the backup is different
  802. size_t after_db_id_len = 0;
  803. char* after_db_id = rocksdb_get_db_identity(db, &after_db_id_len);
  804. CheckCondition(after_db_id_len == 36);
  805. CheckCondition(memcmp(after_db_id, before_db_id, after_db_id_len) != 0);
  806. Free(&before_db_id);
  807. Free(&after_db_id);
  808. rocksdb_backup_engine_close(be);
  809. }
  810. StartPhase("checkpoint");
  811. {
  812. rocksdb_destroy_db(options, dbcheckpointname, &err);
  813. CheckNoError(err);
  814. rocksdb_checkpoint_t* checkpoint =
  815. rocksdb_checkpoint_object_create(db, &err);
  816. CheckNoError(err);
  817. rocksdb_checkpoint_create(checkpoint, dbcheckpointname, 0, &err);
  818. CheckNoError(err);
  819. rocksdb_checkpoint_object_destroy(checkpoint);
  820. checkpoint = NULL;
  821. // get the identity before the checkpoint
  822. size_t before_db_id_len = 0;
  823. char* before_db_id = rocksdb_get_db_identity(db, &before_db_id_len);
  824. CheckCondition(before_db_id_len == 36);
  825. // start a new database from the checkpoint
  826. rocksdb_close(db);
  827. rocksdb_options_set_error_if_exists(options, 0);
  828. db = rocksdb_open(options, dbcheckpointname, &err);
  829. CheckNoError(err);
  830. CheckGet(db, roptions, "foo", "hello");
  831. // the db_identity after the checkpoint is different
  832. size_t after_db_id_len = 0;
  833. char* after_db_id = rocksdb_get_db_identity(db, &after_db_id_len);
  834. CheckCondition(after_db_id_len == 36);
  835. CheckCondition(memcmp(after_db_id, before_db_id, after_db_id_len) != 0);
  836. Free(&before_db_id);
  837. Free(&after_db_id);
  838. rocksdb_close(db);
  839. rocksdb_destroy_db(options, dbcheckpointname, &err);
  840. CheckNoError(err);
  841. db = rocksdb_open(options, dbname, &err);
  842. CheckNoError(err);
  843. rocksdb_options_set_error_if_exists(options, 1);
  844. }
  845. StartPhase("checkpoint_db_id_in_manifest");
  846. {
  847. // create new DB with set_write_dbid_to_manifest=true
  848. // db_identity is now the same across checkpoints
  849. rocksdb_close(db);
  850. db = NULL;
  851. rocksdb_options_t* options_dbid_in_manifest = rocksdb_options_create();
  852. rocksdb_options_set_create_if_missing(options_dbid_in_manifest, 1);
  853. rocksdb_options_set_write_dbid_to_manifest(options_dbid_in_manifest, false);
  854. unsigned char write_to_manifest =
  855. rocksdb_options_get_write_dbid_to_manifest(options_dbid_in_manifest);
  856. CheckCondition(!write_to_manifest);
  857. rocksdb_options_set_write_dbid_to_manifest(options_dbid_in_manifest, true);
  858. write_to_manifest =
  859. rocksdb_options_get_write_dbid_to_manifest(options_dbid_in_manifest);
  860. CheckCondition(write_to_manifest);
  861. rocksdb_options_set_write_identity_file(options_dbid_in_manifest, true);
  862. unsigned char write_identity_file =
  863. rocksdb_options_get_write_identity_file(options_dbid_in_manifest);
  864. CheckCondition(write_identity_file);
  865. rocksdb_options_set_write_identity_file(options_dbid_in_manifest, false);
  866. write_identity_file =
  867. rocksdb_options_get_write_identity_file(options_dbid_in_manifest);
  868. CheckCondition(!write_identity_file);
  869. db = rocksdb_open(options_dbid_in_manifest, dbbackupname, &err);
  870. CheckNoError(err);
  871. rocksdb_checkpoint_t* checkpoint =
  872. rocksdb_checkpoint_object_create(db, &err);
  873. CheckNoError(err);
  874. rocksdb_checkpoint_create(checkpoint, dbcheckpointname, 0, &err);
  875. CheckNoError(err);
  876. rocksdb_checkpoint_object_destroy(checkpoint);
  877. checkpoint = NULL;
  878. // get the identity before the backup
  879. size_t before_db_id_len = 0;
  880. char* before_db_id = rocksdb_get_db_identity(db, &before_db_id_len);
  881. CheckCondition(before_db_id_len == 36);
  882. // open the checkpoint
  883. rocksdb_close(db);
  884. rocksdb_destroy_db(options_dbid_in_manifest, dbbackupname, &err);
  885. CheckNoError(err);
  886. rocksdb_options_set_error_if_exists(options_dbid_in_manifest, 0);
  887. db = rocksdb_open(options_dbid_in_manifest, dbcheckpointname, &err);
  888. CheckNoError(err);
  889. // the db_identity after the checkpoint is the same
  890. size_t after_db_id_len = 0;
  891. char* after_db_id = rocksdb_get_db_identity(db, &after_db_id_len);
  892. CheckCondition(after_db_id_len == 36);
  893. CheckCondition(memcmp(after_db_id, before_db_id, after_db_id_len) == 0);
  894. Free(&before_db_id);
  895. Free(&after_db_id);
  896. rocksdb_close(db);
  897. rocksdb_destroy_db(options_dbid_in_manifest, dbcheckpointname, &err);
  898. CheckNoError(err);
  899. rocksdb_options_destroy(options_dbid_in_manifest);
  900. options_dbid_in_manifest = NULL;
  901. // re-open the default database
  902. rocksdb_options_set_error_if_exists(options, 0);
  903. db = rocksdb_open(options, dbname, &err);
  904. CheckNoError(err);
  905. rocksdb_options_set_error_if_exists(options, 1);
  906. }
  907. StartPhase("checkpoint_export_column_family");
  908. {
  909. static char cf_export_path[200];
  910. static char db_import_path[200];
  911. snprintf(cf_export_path, sizeof(cf_export_path),
  912. "%s/rocksdb_c_test-%d-cf_export", GetTempDir(), ((int)geteuid()));
  913. snprintf(db_import_path, sizeof(db_import_path),
  914. "%s/rocksdb_c_test-%d-db_import", GetTempDir(), ((int)geteuid()));
  915. rocksdb_options_t* db_options = rocksdb_options_create();
  916. rocksdb_column_family_handle_t* cf_export =
  917. rocksdb_create_column_family(db, db_options, "cf_export", &err);
  918. CheckNoError(err);
  919. rocksdb_put_cf(db, woptions, cf_export, "k1", 2, "v1", 2, &err);
  920. CheckNoError(err);
  921. rocksdb_put_cf(db, woptions, cf_export, "k2", 2, "v2", 2, &err);
  922. CheckNoError(err);
  923. rocksdb_checkpoint_t* checkpoint =
  924. rocksdb_checkpoint_object_create(db, &err);
  925. CheckNoError(err);
  926. rocksdb_export_import_files_metadata_t* export_metadata =
  927. rocksdb_checkpoint_export_column_family(checkpoint, cf_export,
  928. cf_export_path, &err);
  929. CheckNoError(err);
  930. const char* comparator_name =
  931. rocksdb_export_import_files_metadata_get_db_comparator_name(
  932. export_metadata);
  933. CheckEqual("leveldb.BytewiseComparator", comparator_name, 26);
  934. rocksdb_free((void*)comparator_name);
  935. rocksdb_checkpoint_object_destroy(checkpoint);
  936. checkpoint = NULL;
  937. rocksdb_drop_column_family(db, cf_export, &err);
  938. CheckNoError(err);
  939. rocksdb_column_family_handle_destroy(cf_export);
  940. rocksdb_options_set_create_if_missing(db_options, 1);
  941. rocksdb_options_set_error_if_exists(db_options, 1);
  942. rocksdb_t* db_import = rocksdb_open(db_options, db_import_path, &err);
  943. CheckNoError(err);
  944. rocksdb_import_column_family_options_t* import_options =
  945. rocksdb_import_column_family_options_create();
  946. rocksdb_column_family_handle_t* cf_import =
  947. rocksdb_create_column_family_with_import(db_import, db_options,
  948. "cf_import", import_options,
  949. export_metadata, &err);
  950. CheckNoError(err);
  951. rocksdb_import_column_family_options_destroy(import_options);
  952. rocksdb_export_import_files_metadata_destroy(export_metadata);
  953. size_t val_len;
  954. char* val =
  955. rocksdb_get_cf(db_import, roptions, cf_import, "k1", 2, &val_len, &err);
  956. CheckNoError(err);
  957. CheckEqual("v1", val, val_len);
  958. free(val);
  959. val =
  960. rocksdb_get_cf(db_import, roptions, cf_import, "k2", 2, &val_len, &err);
  961. CheckNoError(err);
  962. CheckEqual("v2", val, val_len);
  963. free(val);
  964. rocksdb_column_family_handle_destroy(cf_import);
  965. cf_import = NULL;
  966. rocksdb_close(db_import);
  967. rocksdb_destroy_db(db_options, db_import_path, &err);
  968. CheckNoError(err);
  969. rocksdb_options_destroy(db_options);
  970. db_options = NULL;
  971. }
  972. StartPhase("compactall");
  973. rocksdb_compact_range(db, NULL, 0, NULL, 0);
  974. CheckGet(db, roptions, "foo", "hello");
  975. StartPhase("compactrange");
  976. rocksdb_compact_range(db, "a", 1, "z", 1);
  977. CheckGet(db, roptions, "foo", "hello");
  978. StartPhase("compactallopt");
  979. rocksdb_compact_range_opt(db, coptions, NULL, 0, NULL, 0);
  980. CheckGet(db, roptions, "foo", "hello");
  981. StartPhase("compactrangeopt");
  982. rocksdb_compact_range_opt(db, coptions, "a", 1, "z", 1);
  983. CheckGet(db, roptions, "foo", "hello");
  984. // Simple check cache usage
  985. StartPhase("cache_usage");
  986. {
  987. rocksdb_readoptions_set_pin_data(roptions, 1);
  988. rocksdb_iterator_t* iter = rocksdb_create_iterator(db, roptions);
  989. rocksdb_iter_seek(iter, "foo", 3);
  990. size_t usage = rocksdb_cache_get_usage(cache);
  991. CheckCondition(usage > 0);
  992. size_t pin_usage = rocksdb_cache_get_pinned_usage(cache);
  993. CheckCondition(pin_usage > 0);
  994. rocksdb_iter_next(iter);
  995. rocksdb_iter_destroy(iter);
  996. rocksdb_readoptions_set_pin_data(roptions, 0);
  997. }
  998. StartPhase("addfile");
  999. {
  1000. rocksdb_envoptions_t* env_opt = rocksdb_envoptions_create();
  1001. rocksdb_sstfilewriter_t* writer =
  1002. rocksdb_sstfilewriter_create(env_opt, options);
  1003. remove(sstfilename);
  1004. rocksdb_sstfilewriter_open(writer, sstfilename, &err);
  1005. CheckNoError(err);
  1006. rocksdb_sstfilewriter_put(writer, "sstk1", 5, "v1", 2, &err);
  1007. CheckNoError(err);
  1008. rocksdb_sstfilewriter_put(writer, "sstk2", 5, "v2", 2, &err);
  1009. CheckNoError(err);
  1010. rocksdb_sstfilewriter_put(writer, "sstk3", 5, "v3", 2, &err);
  1011. CheckNoError(err);
  1012. rocksdb_sstfilewriter_finish(writer, &err);
  1013. CheckNoError(err);
  1014. rocksdb_ingestexternalfileoptions_t* ing_opt =
  1015. rocksdb_ingestexternalfileoptions_create();
  1016. const char* file_list[1] = {sstfilename};
  1017. rocksdb_ingest_external_file(db, file_list, 1, ing_opt, &err);
  1018. CheckNoError(err);
  1019. CheckGet(db, roptions, "sstk1", "v1");
  1020. CheckGet(db, roptions, "sstk2", "v2");
  1021. CheckGet(db, roptions, "sstk3", "v3");
  1022. remove(sstfilename);
  1023. rocksdb_sstfilewriter_open(writer, sstfilename, &err);
  1024. CheckNoError(err);
  1025. rocksdb_sstfilewriter_put(writer, "sstk2", 5, "v4", 2, &err);
  1026. CheckNoError(err);
  1027. rocksdb_sstfilewriter_put(writer, "sstk22", 6, "v5", 2, &err);
  1028. CheckNoError(err);
  1029. rocksdb_sstfilewriter_put(writer, "sstk3", 5, "v6", 2, &err);
  1030. CheckNoError(err);
  1031. rocksdb_sstfilewriter_finish(writer, &err);
  1032. CheckNoError(err);
  1033. rocksdb_ingest_external_file(db, file_list, 1, ing_opt, &err);
  1034. CheckNoError(err);
  1035. CheckGet(db, roptions, "sstk1", "v1");
  1036. CheckGet(db, roptions, "sstk2", "v4");
  1037. CheckGet(db, roptions, "sstk22", "v5");
  1038. CheckGet(db, roptions, "sstk3", "v6");
  1039. rocksdb_sstfilewriter_open(writer, sstfilename, &err);
  1040. CheckNoError(err);
  1041. rocksdb_sstfilewriter_put(writer, "abc1", 4, "v7", 2, &err);
  1042. CheckNoError(err);
  1043. rocksdb_sstfilewriter_put(writer, "abc2", 4, "v8", 2, &err);
  1044. CheckNoError(err);
  1045. rocksdb_sstfilewriter_put(writer, "abc3", 4, "v9", 2, &err);
  1046. CheckNoError(err);
  1047. rocksdb_sstfilewriter_put(writer, "abc4", 4, "v10", 3, &err);
  1048. CheckNoError(err);
  1049. rocksdb_sstfilewriter_delete_range(writer, "abc1", 4, "abc4", 4, &err);
  1050. CheckNoError(err);
  1051. rocksdb_sstfilewriter_finish(writer, &err);
  1052. CheckNoError(err);
  1053. rocksdb_ingestexternalfileoptions_destroy(ing_opt);
  1054. rocksdb_sstfilewriter_destroy(writer);
  1055. rocksdb_envoptions_destroy(env_opt);
  1056. // Delete all keys we just ingested
  1057. rocksdb_delete(db, woptions, "sstk1", 5, &err);
  1058. CheckNoError(err);
  1059. rocksdb_delete(db, woptions, "sstk2", 5, &err);
  1060. CheckNoError(err);
  1061. rocksdb_delete(db, woptions, "sstk22", 6, &err);
  1062. CheckNoError(err);
  1063. rocksdb_delete(db, woptions, "sstk3", 5, &err);
  1064. CheckNoError(err);
  1065. }
  1066. StartPhase("writebatch");
  1067. {
  1068. rocksdb_writebatch_t* wb = rocksdb_writebatch_create();
  1069. rocksdb_writebatch_put(wb, "foo", 3, "a", 1);
  1070. rocksdb_writebatch_clear(wb);
  1071. rocksdb_writebatch_put(wb, "bar", 3, "b", 1);
  1072. rocksdb_writebatch_put(wb, "box", 3, "c", 1);
  1073. rocksdb_writebatch_delete(wb, "bar", 3);
  1074. rocksdb_write(db, woptions, wb, &err);
  1075. CheckNoError(err);
  1076. CheckGet(db, roptions, "foo", "hello");
  1077. CheckGet(db, roptions, "bar", NULL);
  1078. CheckGet(db, roptions, "box", "c");
  1079. int pos = 0;
  1080. rocksdb_writebatch_iterate(wb, &pos, CheckPut, CheckDel);
  1081. CheckCondition(pos == 3);
  1082. rocksdb_writebatch_clear(wb);
  1083. rocksdb_writebatch_put(wb, "bar", 3, "b", 1);
  1084. rocksdb_writebatch_put(wb, "bay", 3, "d", 1);
  1085. rocksdb_writebatch_delete_range(wb, "bar", 3, "bay", 3);
  1086. rocksdb_write(db, woptions, wb, &err);
  1087. CheckNoError(err);
  1088. CheckGet(db, roptions, "bar", NULL);
  1089. CheckGet(db, roptions, "bay", "d");
  1090. rocksdb_writebatch_clear(wb);
  1091. const char* start_list[1] = {"bay"};
  1092. const size_t start_sizes[1] = {3};
  1093. const char* end_list[1] = {"baz"};
  1094. const size_t end_sizes[1] = {3};
  1095. rocksdb_writebatch_delete_rangev(wb, 1, start_list, start_sizes, end_list,
  1096. end_sizes);
  1097. rocksdb_write(db, woptions, wb, &err);
  1098. CheckNoError(err);
  1099. CheckGet(db, roptions, "bay", NULL);
  1100. rocksdb_writebatch_destroy(wb);
  1101. }
  1102. StartPhase("writebatch_vectors");
  1103. {
  1104. rocksdb_writebatch_t* wb = rocksdb_writebatch_create();
  1105. const char* k_list[2] = {"z", "ap"};
  1106. const size_t k_sizes[2] = {1, 2};
  1107. const char* v_list[3] = {"x", "y", "z"};
  1108. const size_t v_sizes[3] = {1, 1, 1};
  1109. rocksdb_writebatch_putv(wb, 2, k_list, k_sizes, 3, v_list, v_sizes);
  1110. rocksdb_write(db, woptions, wb, &err);
  1111. CheckNoError(err);
  1112. CheckGet(db, roptions, "zap", "xyz");
  1113. rocksdb_writebatch_delete(wb, "zap", 3);
  1114. rocksdb_write(db, woptions, wb, &err);
  1115. CheckNoError(err);
  1116. CheckGet(db, roptions, "zap", NULL);
  1117. rocksdb_writebatch_destroy(wb);
  1118. }
  1119. StartPhase("writebatch_savepoint");
  1120. {
  1121. rocksdb_writebatch_t* wb = rocksdb_writebatch_create();
  1122. rocksdb_writebatch_set_save_point(wb);
  1123. rocksdb_writebatch_set_save_point(wb);
  1124. const char* k_list[2] = {"z", "ap"};
  1125. const size_t k_sizes[2] = {1, 2};
  1126. const char* v_list[3] = {"x", "y", "z"};
  1127. const size_t v_sizes[3] = {1, 1, 1};
  1128. rocksdb_writebatch_pop_save_point(wb, &err);
  1129. CheckNoError(err);
  1130. rocksdb_writebatch_putv(wb, 2, k_list, k_sizes, 3, v_list, v_sizes);
  1131. rocksdb_writebatch_rollback_to_save_point(wb, &err);
  1132. CheckNoError(err);
  1133. rocksdb_write(db, woptions, wb, &err);
  1134. CheckNoError(err);
  1135. CheckGet(db, roptions, "zap", NULL);
  1136. rocksdb_writebatch_destroy(wb);
  1137. }
  1138. StartPhase("writebatch_rep");
  1139. {
  1140. rocksdb_writebatch_t* wb1 = rocksdb_writebatch_create();
  1141. rocksdb_writebatch_put(wb1, "baz", 3, "d", 1);
  1142. rocksdb_writebatch_put(wb1, "quux", 4, "e", 1);
  1143. rocksdb_writebatch_delete(wb1, "quux", 4);
  1144. size_t repsize1 = 0;
  1145. const char* rep = rocksdb_writebatch_data(wb1, &repsize1);
  1146. rocksdb_writebatch_t* wb2 = rocksdb_writebatch_create_from(rep, repsize1);
  1147. CheckCondition(rocksdb_writebatch_count(wb1) ==
  1148. rocksdb_writebatch_count(wb2));
  1149. size_t repsize2 = 0;
  1150. CheckCondition(
  1151. memcmp(rep, rocksdb_writebatch_data(wb2, &repsize2), repsize1) == 0);
  1152. rocksdb_writebatch_destroy(wb1);
  1153. rocksdb_writebatch_destroy(wb2);
  1154. }
  1155. StartPhase("writebatch_wi");
  1156. {
  1157. rocksdb_writebatch_wi_t* wbi = rocksdb_writebatch_wi_create(0, 1);
  1158. rocksdb_writebatch_wi_put(wbi, "foo", 3, "a", 1);
  1159. rocksdb_writebatch_wi_clear(wbi);
  1160. rocksdb_writebatch_wi_put(wbi, "bar", 3, "b", 1);
  1161. rocksdb_writebatch_wi_put(wbi, "box", 3, "c", 1);
  1162. rocksdb_writebatch_wi_delete(wbi, "bar", 3);
  1163. int count = rocksdb_writebatch_wi_count(wbi);
  1164. CheckCondition(count == 3);
  1165. size_t size;
  1166. char* value;
  1167. const char* pinned_value;
  1168. rocksdb_pinnableslice_t* p;
  1169. value = rocksdb_writebatch_wi_get_from_batch(wbi, options, "box", 3, &size,
  1170. &err);
  1171. CheckValue(err, "c", &value, size);
  1172. value = rocksdb_writebatch_wi_get_from_batch(wbi, options, "bar", 3, &size,
  1173. &err);
  1174. CheckValue(err, NULL, &value, size);
  1175. value = rocksdb_writebatch_wi_get_from_batch_and_db(wbi, db, roptions,
  1176. "foo", 3, &size, &err);
  1177. CheckValue(err, "hello", &value, size);
  1178. p = rocksdb_writebatch_wi_get_pinned_from_batch_and_db(wbi, db, roptions,
  1179. "foo", 3, &err);
  1180. pinned_value = rocksdb_pinnableslice_value(p, &size);
  1181. CheckPinnedValue(err, "hello", &pinned_value, size);
  1182. rocksdb_pinnableslice_destroy(p);
  1183. value = rocksdb_writebatch_wi_get_from_batch_and_db(wbi, db, roptions,
  1184. "box", 3, &size, &err);
  1185. CheckValue(err, "c", &value, size);
  1186. p = rocksdb_writebatch_wi_get_pinned_from_batch_and_db(wbi, db, roptions,
  1187. "box", 3, &err);
  1188. pinned_value = rocksdb_pinnableslice_value(p, &size);
  1189. CheckPinnedValue(err, "c", &pinned_value, size);
  1190. rocksdb_pinnableslice_destroy(p);
  1191. rocksdb_write_writebatch_wi(db, woptions, wbi, &err);
  1192. CheckNoError(err);
  1193. CheckGet(db, roptions, "foo", "hello");
  1194. CheckGet(db, roptions, "bar", NULL);
  1195. CheckGet(db, roptions, "box", "c");
  1196. int pos = 0;
  1197. rocksdb_writebatch_wi_iterate(wbi, &pos, CheckPut, CheckDel);
  1198. CheckCondition(pos == 3);
  1199. rocksdb_writebatch_wi_clear(wbi);
  1200. rocksdb_writebatch_wi_destroy(wbi);
  1201. }
  1202. StartPhase("writebatch_wi_vectors");
  1203. {
  1204. rocksdb_writebatch_wi_t* wb = rocksdb_writebatch_wi_create(0, 1);
  1205. const char* k_list[2] = {"z", "ap"};
  1206. const size_t k_sizes[2] = {1, 2};
  1207. const char* v_list[3] = {"x", "y", "z"};
  1208. const size_t v_sizes[3] = {1, 1, 1};
  1209. rocksdb_writebatch_wi_putv(wb, 2, k_list, k_sizes, 3, v_list, v_sizes);
  1210. rocksdb_write_writebatch_wi(db, woptions, wb, &err);
  1211. CheckNoError(err);
  1212. CheckGet(db, roptions, "zap", "xyz");
  1213. rocksdb_writebatch_wi_delete(wb, "zap", 3);
  1214. rocksdb_write_writebatch_wi(db, woptions, wb, &err);
  1215. CheckNoError(err);
  1216. CheckGet(db, roptions, "zap", NULL);
  1217. rocksdb_writebatch_wi_destroy(wb);
  1218. }
  1219. StartPhase("writebatch_wi_savepoint");
  1220. {
  1221. rocksdb_writebatch_wi_t* wb = rocksdb_writebatch_wi_create(0, 1);
  1222. rocksdb_writebatch_wi_set_save_point(wb);
  1223. const char* k_list[2] = {"z", "ap"};
  1224. const size_t k_sizes[2] = {1, 2};
  1225. const char* v_list[3] = {"x", "y", "z"};
  1226. const size_t v_sizes[3] = {1, 1, 1};
  1227. rocksdb_writebatch_wi_putv(wb, 2, k_list, k_sizes, 3, v_list, v_sizes);
  1228. rocksdb_writebatch_wi_rollback_to_save_point(wb, &err);
  1229. CheckNoError(err);
  1230. rocksdb_write_writebatch_wi(db, woptions, wb, &err);
  1231. CheckNoError(err);
  1232. CheckGet(db, roptions, "zap", NULL);
  1233. rocksdb_writebatch_wi_destroy(wb);
  1234. }
  1235. StartPhase("iter");
  1236. {
  1237. rocksdb_iterator_t* iter = rocksdb_create_iterator(db, roptions);
  1238. CheckCondition(!rocksdb_iter_valid(iter));
  1239. rocksdb_iter_seek_to_first(iter);
  1240. CheckCondition(rocksdb_iter_valid(iter));
  1241. CheckIter(iter, "box", "c");
  1242. rocksdb_iter_next(iter);
  1243. CheckIter(iter, "foo", "hello");
  1244. rocksdb_iter_prev(iter);
  1245. CheckIter(iter, "box", "c");
  1246. rocksdb_iter_prev(iter);
  1247. CheckCondition(!rocksdb_iter_valid(iter));
  1248. rocksdb_iter_seek_to_last(iter);
  1249. CheckIter(iter, "foo", "hello");
  1250. rocksdb_iter_seek(iter, "b", 1);
  1251. CheckIter(iter, "box", "c");
  1252. rocksdb_iter_seek_for_prev(iter, "g", 1);
  1253. CheckIter(iter, "foo", "hello");
  1254. rocksdb_iter_seek_for_prev(iter, "box", 3);
  1255. CheckIter(iter, "box", "c");
  1256. rocksdb_iter_get_error(iter, &err);
  1257. CheckNoError(err);
  1258. rocksdb_iter_destroy(iter);
  1259. }
  1260. StartPhase("wbwi_iter");
  1261. {
  1262. rocksdb_iterator_t* base_iter = rocksdb_create_iterator(db, roptions);
  1263. rocksdb_writebatch_wi_t* wbi = rocksdb_writebatch_wi_create(0, 1);
  1264. rocksdb_writebatch_wi_put(wbi, "bar", 3, "b", 1);
  1265. rocksdb_writebatch_wi_delete(wbi, "foo", 3);
  1266. rocksdb_iterator_t* iter =
  1267. rocksdb_writebatch_wi_create_iterator_with_base(wbi, base_iter);
  1268. CheckCondition(!rocksdb_iter_valid(iter));
  1269. rocksdb_iter_seek_to_first(iter);
  1270. CheckCondition(rocksdb_iter_valid(iter));
  1271. CheckIter(iter, "bar", "b");
  1272. rocksdb_iter_next(iter);
  1273. CheckIter(iter, "box", "c");
  1274. rocksdb_iter_prev(iter);
  1275. CheckIter(iter, "bar", "b");
  1276. rocksdb_iter_prev(iter);
  1277. CheckCondition(!rocksdb_iter_valid(iter));
  1278. rocksdb_iter_seek_to_last(iter);
  1279. CheckIter(iter, "box", "c");
  1280. rocksdb_iter_seek(iter, "b", 1);
  1281. CheckIter(iter, "bar", "b");
  1282. rocksdb_iter_seek_for_prev(iter, "c", 1);
  1283. CheckIter(iter, "box", "c");
  1284. rocksdb_iter_seek_for_prev(iter, "box", 3);
  1285. CheckIter(iter, "box", "c");
  1286. rocksdb_iter_get_error(iter, &err);
  1287. CheckNoError(err);
  1288. rocksdb_iter_destroy(iter);
  1289. rocksdb_writebatch_wi_destroy(wbi);
  1290. }
  1291. StartPhase("wbwi_iter_readoptions");
  1292. {
  1293. rocksdb_readoptions_t* iter_roptions = rocksdb_readoptions_create();
  1294. rocksdb_readoptions_set_iterate_lower_bound(iter_roptions, "boy", 3);
  1295. rocksdb_readoptions_set_iterate_upper_bound(iter_roptions, "fool", 4);
  1296. rocksdb_iterator_t* base_iter = rocksdb_create_iterator(db, iter_roptions);
  1297. rocksdb_writebatch_wi_t* wbi = rocksdb_writebatch_wi_create(0, 1);
  1298. rocksdb_writebatch_wi_put(wbi, "bar", 3, "b",
  1299. 1); // should get filtered out
  1300. rocksdb_writebatch_wi_put(wbi, "cat", 3, "miau", 4);
  1301. rocksdb_writebatch_wi_put(wbi, "gnu", 3, "muh",
  1302. 3); // should get filtered out
  1303. rocksdb_iterator_t* iter =
  1304. rocksdb_writebatch_wi_create_iterator_with_base_readopts(wbi, base_iter,
  1305. iter_roptions);
  1306. CheckCondition(!rocksdb_iter_valid(iter));
  1307. rocksdb_iter_seek_to_first(iter);
  1308. CheckCondition(rocksdb_iter_valid(iter));
  1309. CheckIter(iter, "cat", "miau");
  1310. rocksdb_iter_next(iter);
  1311. CheckIter(iter, "foo", "hello");
  1312. rocksdb_iter_prev(iter);
  1313. CheckIter(iter, "cat", "miau");
  1314. rocksdb_iter_prev(iter);
  1315. CheckCondition(!rocksdb_iter_valid(iter));
  1316. rocksdb_iter_seek_to_last(iter);
  1317. CheckIter(iter, "foo", "hello");
  1318. rocksdb_iter_seek(iter, "b", 1);
  1319. CheckIter(iter, "cat", "miau");
  1320. rocksdb_iter_seek_for_prev(iter, "d", 1);
  1321. CheckIter(iter, "cat", "miau");
  1322. rocksdb_iter_seek_for_prev(iter, "fool", 3);
  1323. CheckIter(iter, "foo", "hello");
  1324. rocksdb_iter_get_error(iter, &err);
  1325. CheckNoError(err);
  1326. rocksdb_iter_destroy(iter);
  1327. rocksdb_writebatch_wi_destroy(wbi);
  1328. rocksdb_readoptions_destroy(iter_roptions);
  1329. }
  1330. StartPhase("multiget");
  1331. {
  1332. const char* keys[3] = {"box", "foo", "notfound"};
  1333. const size_t keys_sizes[3] = {3, 3, 8};
  1334. char* vals[3];
  1335. size_t vals_sizes[3];
  1336. char* errs[3];
  1337. const char* expected[3] = {"c", "hello", NULL};
  1338. rocksdb_multi_get(db, roptions, 3, keys, keys_sizes, vals, vals_sizes,
  1339. errs);
  1340. CheckMultiGetValues(3, vals, vals_sizes, errs, expected);
  1341. }
  1342. StartPhase("pin_get");
  1343. {
  1344. CheckPinGet(db, roptions, "box", "c");
  1345. CheckPinGet(db, roptions, "foo", "hello");
  1346. CheckPinGet(db, roptions, "notfound", NULL);
  1347. }
  1348. StartPhase("approximate_sizes");
  1349. {
  1350. int i;
  1351. int n = 20000;
  1352. char keybuf[100];
  1353. char valbuf[100];
  1354. uint64_t sizes[2];
  1355. const char* start[2] = {"a", "k00000000000000010000"};
  1356. size_t start_len[2] = {1, 21};
  1357. const char* limit[2] = {"k00000000000000010000", "z"};
  1358. size_t limit_len[2] = {21, 1};
  1359. rocksdb_writeoptions_set_sync(woptions, 0);
  1360. for (i = 0; i < n; i++) {
  1361. snprintf(keybuf, sizeof(keybuf), "k%020d", i);
  1362. snprintf(valbuf, sizeof(valbuf), "v%020d", i);
  1363. rocksdb_put(db, woptions, keybuf, strlen(keybuf), valbuf, strlen(valbuf),
  1364. &err);
  1365. CheckNoError(err);
  1366. }
  1367. rocksdb_approximate_sizes(db, 2, start, start_len, limit, limit_len, sizes,
  1368. &err);
  1369. CheckNoError(err);
  1370. CheckCondition(sizes[0] > 0);
  1371. CheckCondition(sizes[1] > 0);
  1372. }
  1373. StartPhase("property");
  1374. {
  1375. char* prop = rocksdb_property_value(db, "nosuchprop");
  1376. CheckCondition(prop == NULL);
  1377. prop = rocksdb_property_value(db, "rocksdb.stats");
  1378. CheckCondition(prop != NULL);
  1379. Free(&prop);
  1380. }
  1381. StartPhase("snapshot");
  1382. {
  1383. const rocksdb_snapshot_t* snap;
  1384. snap = rocksdb_create_snapshot(db);
  1385. rocksdb_delete(db, woptions, "foo", 3, &err);
  1386. CheckNoError(err);
  1387. rocksdb_readoptions_set_snapshot(roptions, snap);
  1388. CheckGet(db, roptions, "foo", "hello");
  1389. rocksdb_readoptions_set_snapshot(roptions, NULL);
  1390. CheckGet(db, roptions, "foo", NULL);
  1391. rocksdb_release_snapshot(db, snap);
  1392. }
  1393. StartPhase("snapshot_with_memtable_inplace_update");
  1394. {
  1395. rocksdb_close(db);
  1396. const rocksdb_snapshot_t* snap = NULL;
  1397. const char* s_key = "foo_snap";
  1398. const char* value1 = "hello_s1";
  1399. const char* value2 = "hello_s2";
  1400. rocksdb_options_set_allow_concurrent_memtable_write(options, 0);
  1401. rocksdb_options_set_inplace_update_support(options, 1);
  1402. rocksdb_options_set_error_if_exists(options, 0);
  1403. db = rocksdb_open(options, dbname, &err);
  1404. CheckNoError(err);
  1405. rocksdb_put(db, woptions, s_key, 8, value1, 8, &err);
  1406. snap = rocksdb_create_snapshot(db);
  1407. assert(snap != NULL);
  1408. rocksdb_put(db, woptions, s_key, 8, value2, 8, &err);
  1409. CheckNoError(err);
  1410. rocksdb_readoptions_set_snapshot(roptions, snap);
  1411. CheckGet(db, roptions, "foo", NULL);
  1412. // snapshot syntax is invalid, because of inplace update supported is set
  1413. CheckGet(db, roptions, s_key, value2);
  1414. // restore the data and options
  1415. rocksdb_delete(db, woptions, s_key, 8, &err);
  1416. CheckGet(db, roptions, s_key, NULL);
  1417. rocksdb_release_snapshot(db, snap);
  1418. rocksdb_readoptions_set_snapshot(roptions, NULL);
  1419. rocksdb_options_set_inplace_update_support(options, 0);
  1420. rocksdb_options_set_allow_concurrent_memtable_write(options, 1);
  1421. rocksdb_options_set_error_if_exists(options, 1);
  1422. }
  1423. StartPhase("repair");
  1424. {
  1425. // If we do not compact here, then the lazy deletion of
  1426. // files (https://reviews.facebook.net/D6123) would leave
  1427. // around deleted files and the repair process will find
  1428. // those files and put them back into the database.
  1429. rocksdb_compact_range(db, NULL, 0, NULL, 0);
  1430. rocksdb_close(db);
  1431. rocksdb_options_set_create_if_missing(options, 0);
  1432. rocksdb_options_set_error_if_exists(options, 0);
  1433. rocksdb_options_set_wal_recovery_mode(options, 2);
  1434. rocksdb_repair_db(options, dbname, &err);
  1435. CheckNoError(err);
  1436. db = rocksdb_open(options, dbname, &err);
  1437. CheckNoError(err);
  1438. CheckGet(db, roptions, "foo", NULL);
  1439. CheckGet(db, roptions, "bar", NULL);
  1440. CheckGet(db, roptions, "box", "c");
  1441. rocksdb_options_set_create_if_missing(options, 1);
  1442. rocksdb_options_set_error_if_exists(options, 1);
  1443. }
  1444. StartPhase("filter");
  1445. for (run = 1; run <= 4; run++) {
  1446. // run=0 uses custom filter (not currently supported)
  1447. // run=1 uses old block-based bloom filter
  1448. // run=2 run uses full bloom filter
  1449. // run=3 uses Ribbon
  1450. // run=4 uses Ribbon-Bloom hybrid configuration
  1451. CheckNoError(err);
  1452. rocksdb_filterpolicy_t* policy;
  1453. if (run == 1) {
  1454. policy = rocksdb_filterpolicy_create_bloom(8.0);
  1455. } else if (run == 2) {
  1456. policy = rocksdb_filterpolicy_create_bloom_full(8.0);
  1457. } else if (run == 3) {
  1458. policy = rocksdb_filterpolicy_create_ribbon(8.0);
  1459. } else {
  1460. policy = rocksdb_filterpolicy_create_ribbon_hybrid(8.0, 1);
  1461. }
  1462. rocksdb_block_based_options_set_filter_policy(table_options, policy);
  1463. rocksdb_block_based_options_set_optimize_filters_for_memory(table_options,
  1464. 0);
  1465. // Create new database
  1466. rocksdb_close(db);
  1467. rocksdb_destroy_db(options, dbname, &err);
  1468. rocksdb_options_set_block_based_table_factory(options, table_options);
  1469. db = rocksdb_open(options, dbname, &err);
  1470. CheckNoError(err);
  1471. rocksdb_put(db, woptions, "foo", 3, "foovalue", 8, &err);
  1472. CheckNoError(err);
  1473. rocksdb_put(db, woptions, "bar", 3, "barvalue", 8, &err);
  1474. CheckNoError(err);
  1475. {
  1476. // Add enough keys to get just one reasonably populated Bloom filter
  1477. const int keys_to_add = 1500;
  1478. int i;
  1479. char keybuf[100];
  1480. for (i = 0; i < keys_to_add; i++) {
  1481. snprintf(keybuf, sizeof(keybuf), "yes%020d", i);
  1482. rocksdb_put(db, woptions, keybuf, strlen(keybuf), "val", 3, &err);
  1483. CheckNoError(err);
  1484. }
  1485. }
  1486. rocksdb_compact_range(db, NULL, 0, NULL, 0);
  1487. CheckGet(db, roptions, "foo", "foovalue");
  1488. CheckGet(db, roptions, "bar", "barvalue");
  1489. {
  1490. // Query some keys not added to identify Bloom filter implementation
  1491. // from false positive queries, using perfcontext to detect Bloom
  1492. // filter behavior
  1493. rocksdb_perfcontext_t* perf = rocksdb_perfcontext_create();
  1494. rocksdb_perfcontext_reset(perf);
  1495. const int keys_to_query = 10000;
  1496. int i;
  1497. char keybuf[100];
  1498. for (i = 0; i < keys_to_query; i++) {
  1499. snprintf(keybuf, sizeof(keybuf), "no%020d", i);
  1500. CheckGet(db, roptions, keybuf, NULL);
  1501. }
  1502. const int hits =
  1503. (int)rocksdb_perfcontext_metric(perf, rocksdb_bloom_sst_hit_count);
  1504. if (run == 0) {
  1505. // Due to half true, half false with fake filter result
  1506. CheckCondition(hits == keys_to_query / 2);
  1507. } else if (run == 1 || run == 2 || run == 4) {
  1508. // For run == 1, block-based Bloom is no longer available in public
  1509. // API; attempting to enable it enables full Bloom instead.
  1510. //
  1511. // Essentially a fingerprint of full Bloom schema, format_version=5
  1512. CheckCondition(hits == 188);
  1513. } else {
  1514. // Essentially a fingerprint of Ribbon schema
  1515. CheckCondition(hits == 226);
  1516. }
  1517. CheckCondition(
  1518. (keys_to_query - hits) ==
  1519. (int)rocksdb_perfcontext_metric(perf, rocksdb_bloom_sst_miss_count));
  1520. rocksdb_perfcontext_destroy(perf);
  1521. }
  1522. // Reset the policy
  1523. rocksdb_block_based_options_set_filter_policy(table_options, NULL);
  1524. rocksdb_options_set_block_based_table_factory(options, table_options);
  1525. }
  1526. StartPhase("compaction_filter");
  1527. {
  1528. rocksdb_options_t* options_with_filter = rocksdb_options_create();
  1529. rocksdb_options_set_create_if_missing(options_with_filter, 1);
  1530. rocksdb_compactionfilter_t* cfilter;
  1531. cfilter = rocksdb_compactionfilter_create(NULL, CFilterDestroy,
  1532. CFilterFilter, CFilterName);
  1533. // Create new database
  1534. rocksdb_close(db);
  1535. rocksdb_destroy_db(options_with_filter, dbname, &err);
  1536. rocksdb_options_set_compaction_filter(options_with_filter, cfilter);
  1537. db = CheckCompaction(db, options_with_filter, roptions, woptions);
  1538. rocksdb_options_set_compaction_filter(options_with_filter, NULL);
  1539. rocksdb_compactionfilter_destroy(cfilter);
  1540. rocksdb_options_destroy(options_with_filter);
  1541. }
  1542. StartPhase("compaction_filter_factory");
  1543. {
  1544. rocksdb_options_t* options_with_filter_factory = rocksdb_options_create();
  1545. rocksdb_options_set_create_if_missing(options_with_filter_factory, 1);
  1546. rocksdb_compactionfilterfactory_t* factory;
  1547. factory = rocksdb_compactionfilterfactory_create(
  1548. NULL, CFilterFactoryDestroy, CFilterCreate, CFilterFactoryName);
  1549. // Create new database
  1550. rocksdb_close(db);
  1551. rocksdb_destroy_db(options_with_filter_factory, dbname, &err);
  1552. rocksdb_options_set_compaction_filter_factory(options_with_filter_factory,
  1553. factory);
  1554. db = CheckCompaction(db, options_with_filter_factory, roptions, woptions);
  1555. rocksdb_options_set_compaction_filter_factory(options_with_filter_factory,
  1556. NULL);
  1557. rocksdb_options_destroy(options_with_filter_factory);
  1558. }
  1559. StartPhase("merge_operator");
  1560. {
  1561. rocksdb_mergeoperator_t* merge_operator;
  1562. merge_operator = rocksdb_mergeoperator_create(
  1563. NULL, MergeOperatorDestroy, MergeOperatorFullMerge,
  1564. MergeOperatorPartialMerge, NULL, MergeOperatorName);
  1565. // Create new database
  1566. rocksdb_close(db);
  1567. rocksdb_destroy_db(options, dbname, &err);
  1568. rocksdb_options_set_merge_operator(options, merge_operator);
  1569. db = rocksdb_open(options, dbname, &err);
  1570. CheckNoError(err);
  1571. rocksdb_put(db, woptions, "foo", 3, "foovalue", 8, &err);
  1572. CheckNoError(err);
  1573. CheckGet(db, roptions, "foo", "foovalue");
  1574. rocksdb_merge(db, woptions, "foo", 3, "barvalue", 8, &err);
  1575. CheckNoError(err);
  1576. CheckGet(db, roptions, "foo", "fake");
  1577. // Merge of a non-existing value
  1578. rocksdb_merge(db, woptions, "bar", 3, "barvalue", 8, &err);
  1579. CheckNoError(err);
  1580. CheckGet(db, roptions, "bar", "fake");
  1581. }
  1582. StartPhase("columnfamilies");
  1583. {
  1584. rocksdb_close(db);
  1585. rocksdb_destroy_db(options, dbname, &err);
  1586. CheckNoError(err);
  1587. rocksdb_options_t* db_options = rocksdb_options_create();
  1588. rocksdb_options_set_create_if_missing(db_options, 1);
  1589. db = rocksdb_open(db_options, dbname, &err);
  1590. CheckNoError(err);
  1591. rocksdb_close(db);
  1592. {
  1593. const char* expected_cf_names[1] = {"default"};
  1594. LoadAndCheckLatestOptions(dbname, env, false, cache, NULL, 1,
  1595. expected_cf_names, NULL);
  1596. }
  1597. rocksdb_options_set_create_if_missing(db_options, 0);
  1598. db = rocksdb_open(db_options, dbname, &err);
  1599. rocksdb_column_family_handle_t* cfh;
  1600. cfh = rocksdb_create_column_family(db, db_options, "cf1", &err);
  1601. rocksdb_column_family_handle_destroy(cfh);
  1602. CheckNoError(err);
  1603. rocksdb_close(db);
  1604. size_t cflen;
  1605. char** column_fams =
  1606. rocksdb_list_column_families(db_options, dbname, &cflen, &err);
  1607. CheckNoError(err);
  1608. CheckEqual("default", column_fams[0], 7);
  1609. CheckEqual("cf1", column_fams[1], 3);
  1610. CheckCondition(cflen == 2);
  1611. rocksdb_list_column_families_destroy(column_fams, cflen);
  1612. rocksdb_options_t* cf_options_1 = rocksdb_options_create();
  1613. rocksdb_options_t* cf_options_2 = rocksdb_options_create();
  1614. // use dbpathname2 as the cf_path for "cf1"
  1615. rocksdb_dbpath_t* dbpath2;
  1616. char dbpathname2[200];
  1617. snprintf(dbpathname2, sizeof(dbpathname2), "%s/rocksdb_c_test-%d-dbpath2",
  1618. GetTempDir(), ((int)geteuid()));
  1619. dbpath2 = rocksdb_dbpath_create(dbpathname2, 1024 * 1024);
  1620. const rocksdb_dbpath_t* cf_paths[1] = {dbpath2};
  1621. rocksdb_options_set_cf_paths(cf_options_2, cf_paths, 1);
  1622. const char* cf_names[2] = {"default", "cf1"};
  1623. const rocksdb_options_t* cf_opts[2] = {cf_options_1, cf_options_2};
  1624. rocksdb_column_family_handle_t* handles[2];
  1625. LoadAndCheckLatestOptions(dbname, env, false, cache, NULL, 2, cf_names,
  1626. NULL);
  1627. db = rocksdb_open_column_families(db_options, dbname, 2, cf_names, cf_opts,
  1628. handles, &err);
  1629. CheckNoError(err);
  1630. rocksdb_put_cf(db, woptions, handles[1], "foo", 3, "hello", 5, &err);
  1631. CheckNoError(err);
  1632. rocksdb_put_cf(db, woptions, handles[1], "foobar1", 7, "hello1", 6, &err);
  1633. CheckNoError(err);
  1634. rocksdb_put_cf(db, woptions, handles[1], "foobar2", 7, "hello2", 6, &err);
  1635. CheckNoError(err);
  1636. rocksdb_put_cf(db, woptions, handles[1], "foobar3", 7, "hello3", 6, &err);
  1637. CheckNoError(err);
  1638. rocksdb_put_cf(db, woptions, handles[1], "foobar4", 7, "hello4", 6, &err);
  1639. CheckNoError(err);
  1640. rocksdb_suggest_compact_range_cf(db, handles[1], "foo", 3, "foobar9", 7,
  1641. &err);
  1642. CheckNoError(err);
  1643. rocksdb_flushoptions_t* flush_options = rocksdb_flushoptions_create();
  1644. rocksdb_flushoptions_set_wait(flush_options, 1);
  1645. rocksdb_flush_cf(db, flush_options, handles[1], &err);
  1646. // make sure all files in "cf1" are under the specified cf path
  1647. {
  1648. rocksdb_column_family_metadata_t* cf_meta =
  1649. rocksdb_get_column_family_metadata_cf(db, handles[1]);
  1650. size_t cf_file_count = rocksdb_column_family_metadata_get_size(cf_meta);
  1651. assert(cf_file_count > 0);
  1652. size_t level_count =
  1653. rocksdb_column_family_metadata_get_level_count(cf_meta);
  1654. assert(level_count > 0);
  1655. for (size_t l = 0; l < level_count; ++l) {
  1656. rocksdb_level_metadata_t* level_meta =
  1657. rocksdb_column_family_metadata_get_level_metadata(cf_meta, l);
  1658. assert(level_meta);
  1659. size_t file_count = rocksdb_level_metadata_get_file_count(level_meta);
  1660. for (size_t f = 0; f < file_count; ++f) {
  1661. rocksdb_sst_file_metadata_t* file_meta =
  1662. rocksdb_level_metadata_get_sst_file_metadata(level_meta, f);
  1663. assert(file_meta);
  1664. char* file_path = rocksdb_sst_file_metadata_get_directory(file_meta);
  1665. assert(strcmp(file_path, dbpathname2) == 0);
  1666. Free(&file_path);
  1667. rocksdb_sst_file_metadata_destroy(file_meta);
  1668. }
  1669. rocksdb_level_metadata_destroy(level_meta);
  1670. }
  1671. rocksdb_column_family_metadata_destroy(cf_meta);
  1672. }
  1673. CheckNoError(err) rocksdb_flushoptions_destroy(flush_options);
  1674. CheckGetCF(db, roptions, handles[1], "foo", "hello");
  1675. CheckPinGetCF(db, roptions, handles[1], "foo", "hello");
  1676. rocksdb_delete_cf(db, woptions, handles[1], "foo", 3, &err);
  1677. CheckNoError(err);
  1678. rocksdb_delete_range_cf(db, woptions, handles[1], "foobar2", 7, "foobar4",
  1679. 7, &err);
  1680. CheckNoError(err);
  1681. CheckGetCF(db, roptions, handles[1], "foo", NULL);
  1682. CheckPinGetCF(db, roptions, handles[1], "foo", NULL);
  1683. rocksdb_writebatch_t* wb = rocksdb_writebatch_create();
  1684. rocksdb_writebatch_put_cf(wb, handles[1], "baz", 3, "a", 1);
  1685. rocksdb_writebatch_clear(wb);
  1686. rocksdb_writebatch_put_cf(wb, handles[1], "bar", 3, "b", 1);
  1687. rocksdb_writebatch_put_cf(wb, handles[1], "box", 3, "c", 1);
  1688. rocksdb_writebatch_put_cf(wb, handles[1], "buff", 4, "rocksdb", 7);
  1689. rocksdb_writebatch_delete_cf(wb, handles[1], "bar", 3);
  1690. rocksdb_write(db, woptions, wb, &err);
  1691. CheckNoError(err);
  1692. CheckGetCF(db, roptions, handles[1], "baz", NULL);
  1693. CheckGetCF(db, roptions, handles[1], "bar", NULL);
  1694. CheckGetCF(db, roptions, handles[1], "box", "c");
  1695. CheckGetCF(db, roptions, handles[1], "buff", "rocksdb");
  1696. CheckPinGetCF(db, roptions, handles[1], "baz", NULL);
  1697. CheckPinGetCF(db, roptions, handles[1], "bar", NULL);
  1698. CheckPinGetCF(db, roptions, handles[1], "box", "c");
  1699. CheckPinGetCF(db, roptions, handles[1], "buff", "rocksdb");
  1700. rocksdb_writebatch_clear(wb);
  1701. // Test WriteBatch iteration with Column Family
  1702. int pos = 0;
  1703. rocksdb_writebatch_put_cf(wb, handles[1], "bar", 3, "b", 1);
  1704. rocksdb_writebatch_put_cf(wb, handles[1], "box", 3, "c", 1);
  1705. rocksdb_writebatch_delete_cf(wb, handles[1], "bar", 3);
  1706. rocksdb_writebatch_merge_cf(wb, handles[1], "box", 3, "cc", 2);
  1707. rocksdb_writebatch_put(wb, "foo", 3, "f", 1);
  1708. rocksdb_writebatch_delete(wb, "foo", 3);
  1709. rocksdb_writebatch_put(wb, "baz", 3, "a", 1);
  1710. rocksdb_writebatch_merge(wb, "baz", 3, "aa", 2);
  1711. rocksdb_writebatch_iterate_cf(wb, &pos, CheckPutCF, CheckDelCF,
  1712. CheckMergeCF);
  1713. CheckCondition(pos == 8);
  1714. rocksdb_writebatch_clear(wb);
  1715. rocksdb_writebatch_destroy(wb);
  1716. rocksdb_flush_wal(db, 1, &err);
  1717. CheckNoError(err);
  1718. // Test WriteBatchWithIndex iteration with Column Family
  1719. rocksdb_writebatch_wi_t* wbwi = rocksdb_writebatch_wi_create(0, true);
  1720. rocksdb_writebatch_wi_put_cf(wbwi, handles[1], "boat", 4, "row",
  1721. 3); // should be filtered out
  1722. rocksdb_writebatch_wi_put_cf(wbwi, handles[1], "buffy", 5, "charmed", 7);
  1723. rocksdb_writebatch_wi_put_cf(wbwi, handles[1], "bus", 3, "yellow",
  1724. 6); // should be filtered out
  1725. rocksdb_readoptions_t* iter_roptions = rocksdb_readoptions_create();
  1726. rocksdb_readoptions_set_iterate_lower_bound(iter_roptions, "bu", 2);
  1727. rocksdb_readoptions_set_iterate_upper_bound(iter_roptions, "buffz", 5);
  1728. rocksdb_iterator_t* base_iter =
  1729. rocksdb_create_iterator_cf(db, iter_roptions, handles[1]);
  1730. rocksdb_iterator_t* wbwi_iter =
  1731. rocksdb_writebatch_wi_create_iterator_with_base_cf_readopts(
  1732. wbwi, base_iter, handles[1], iter_roptions);
  1733. CheckCondition(!rocksdb_iter_valid(wbwi_iter));
  1734. rocksdb_iter_seek_to_first(wbwi_iter);
  1735. CheckCondition(rocksdb_iter_valid(wbwi_iter));
  1736. CheckIter(wbwi_iter, "buff", "rocksdb");
  1737. rocksdb_iter_next(wbwi_iter);
  1738. CheckIter(wbwi_iter, "buffy", "charmed");
  1739. rocksdb_iter_next(wbwi_iter);
  1740. CheckCondition(!rocksdb_iter_valid(wbwi_iter));
  1741. rocksdb_iter_destroy(wbwi_iter);
  1742. rocksdb_writebatch_wi_destroy(wbwi);
  1743. rocksdb_readoptions_destroy(iter_roptions);
  1744. const char* keys[3] = {"box", "box", "barfooxx"};
  1745. const rocksdb_column_family_handle_t* get_handles[3] = {
  1746. handles[0], handles[1], handles[1]};
  1747. const size_t keys_sizes[3] = {3, 3, 8};
  1748. char* vals[3];
  1749. size_t vals_sizes[3];
  1750. char* errs[3];
  1751. rocksdb_multi_get_cf(db, roptions, get_handles, 3, keys, keys_sizes, vals,
  1752. vals_sizes, errs);
  1753. int i;
  1754. for (i = 0; i < 3; i++) {
  1755. CheckEqual(NULL, errs[i], 0);
  1756. switch (i) {
  1757. case 0:
  1758. CheckEqual(NULL, vals[i], vals_sizes[i]); // wrong cf
  1759. break;
  1760. case 1:
  1761. CheckEqual("c", vals[i], vals_sizes[i]); // bingo
  1762. break;
  1763. case 2:
  1764. CheckEqual(NULL, vals[i], vals_sizes[i]); // normal not found
  1765. break;
  1766. }
  1767. Free(&vals[i]);
  1768. }
  1769. {
  1770. const char* batched_keys[4] = {"box", "buff", "barfooxx", "box"};
  1771. const size_t batched_keys_sizes[4] = {3, 4, 8, 3};
  1772. const char* expected_value[4] = {"c", "rocksdb", NULL, "c"};
  1773. char* batched_errs[4];
  1774. rocksdb_pinnableslice_t* pvals[4];
  1775. rocksdb_batched_multi_get_cf(db, roptions, handles[1], 4, batched_keys,
  1776. batched_keys_sizes, pvals, batched_errs,
  1777. false);
  1778. const char* val;
  1779. size_t val_len;
  1780. for (i = 0; i < 4; ++i) {
  1781. val = rocksdb_pinnableslice_value(pvals[i], &val_len);
  1782. CheckNoError(batched_errs[i]);
  1783. CheckEqual(expected_value[i], val, val_len);
  1784. rocksdb_pinnableslice_destroy(pvals[i]);
  1785. }
  1786. }
  1787. {
  1788. unsigned char value_found = 0;
  1789. CheckCondition(!rocksdb_key_may_exist(db, roptions, "invalid_key", 11,
  1790. NULL, NULL, NULL, 0, NULL));
  1791. CheckCondition(!rocksdb_key_may_exist(db, roptions, "invalid_key", 11,
  1792. &vals[0], &vals_sizes[0], NULL, 0,
  1793. &value_found));
  1794. if (value_found) {
  1795. Free(&vals[0]);
  1796. }
  1797. CheckCondition(!rocksdb_key_may_exist_cf(db, roptions, handles[1],
  1798. "invalid_key", 11, NULL, NULL,
  1799. NULL, 0, NULL));
  1800. CheckCondition(!rocksdb_key_may_exist_cf(db, roptions, handles[1],
  1801. "invalid_key", 11, &vals[0],
  1802. &vals_sizes[0], NULL, 0, NULL));
  1803. if (value_found) {
  1804. Free(&vals[0]);
  1805. }
  1806. }
  1807. rocksdb_iterator_t* iter =
  1808. rocksdb_create_iterator_cf(db, roptions, handles[1]);
  1809. CheckCondition(!rocksdb_iter_valid(iter));
  1810. rocksdb_iter_seek_to_first(iter);
  1811. CheckCondition(rocksdb_iter_valid(iter));
  1812. for (i = 0; rocksdb_iter_valid(iter) != 0; rocksdb_iter_next(iter)) {
  1813. i++;
  1814. }
  1815. CheckCondition(i == 4);
  1816. rocksdb_iter_get_error(iter, &err);
  1817. CheckNoError(err);
  1818. rocksdb_iter_destroy(iter);
  1819. rocksdb_column_family_handle_t* iters_cf_handles[2] = {handles[0],
  1820. handles[1]};
  1821. rocksdb_iterator_t* iters_handles[2];
  1822. rocksdb_create_iterators(db, roptions, iters_cf_handles, iters_handles, 2,
  1823. &err);
  1824. CheckNoError(err);
  1825. iter = iters_handles[0];
  1826. CheckCondition(!rocksdb_iter_valid(iter));
  1827. rocksdb_iter_seek_to_first(iter);
  1828. CheckCondition(!rocksdb_iter_valid(iter));
  1829. rocksdb_iter_destroy(iter);
  1830. iter = iters_handles[1];
  1831. CheckCondition(!rocksdb_iter_valid(iter));
  1832. rocksdb_iter_seek_to_first(iter);
  1833. CheckCondition(rocksdb_iter_valid(iter));
  1834. for (i = 0; rocksdb_iter_valid(iter) != 0; rocksdb_iter_next(iter)) {
  1835. i++;
  1836. }
  1837. CheckCondition(i == 4);
  1838. rocksdb_iter_get_error(iter, &err);
  1839. CheckNoError(err);
  1840. rocksdb_iter_destroy(iter);
  1841. GetAndCheckMetaDataCf(db, handles[1], cf_names[1]);
  1842. rocksdb_drop_column_family(db, handles[1], &err);
  1843. CheckNoError(err);
  1844. for (i = 0; i < 2; i++) {
  1845. rocksdb_column_family_handle_destroy(handles[i]);
  1846. }
  1847. rocksdb_close(db);
  1848. {
  1849. // As column family has been dropped, we expect only one column family.
  1850. const char* expected_cf_names[1] = {"default"};
  1851. LoadAndCheckLatestOptions(dbname, env, false, cache, NULL, 1,
  1852. expected_cf_names, NULL);
  1853. }
  1854. rocksdb_destroy_db(options, dbname, &err);
  1855. rocksdb_options_destroy(db_options);
  1856. rocksdb_options_destroy(cf_options_1);
  1857. rocksdb_options_destroy(cf_options_2);
  1858. rocksdb_dbpath_destroy(dbpath2);
  1859. }
  1860. StartPhase("prefix");
  1861. {
  1862. // Create new database
  1863. rocksdb_options_set_allow_mmap_reads(options, 1);
  1864. rocksdb_options_set_prefix_extractor(
  1865. options, rocksdb_slicetransform_create_fixed_prefix(3));
  1866. rocksdb_options_set_hash_skip_list_rep(options, 5000, 4, 4);
  1867. rocksdb_options_set_plain_table_factory(options, 4, 10, 0.75, 16, 0, 0, 0,
  1868. 0);
  1869. rocksdb_options_set_allow_concurrent_memtable_write(options, 0);
  1870. db = rocksdb_open(options, dbname, &err);
  1871. CheckNoError(err);
  1872. rocksdb_put(db, woptions, "foo1", 4, "foo", 3, &err);
  1873. CheckNoError(err);
  1874. rocksdb_put(db, woptions, "foo2", 4, "foo", 3, &err);
  1875. CheckNoError(err);
  1876. rocksdb_put(db, woptions, "foo3", 4, "foo", 3, &err);
  1877. CheckNoError(err);
  1878. rocksdb_put(db, woptions, "bar1", 4, "bar", 3, &err);
  1879. CheckNoError(err);
  1880. rocksdb_put(db, woptions, "bar2", 4, "bar", 3, &err);
  1881. CheckNoError(err);
  1882. rocksdb_put(db, woptions, "bar3", 4, "bar", 3, &err);
  1883. CheckNoError(err);
  1884. rocksdb_iterator_t* iter = rocksdb_create_iterator(db, roptions);
  1885. CheckCondition(!rocksdb_iter_valid(iter));
  1886. rocksdb_iter_seek(iter, "bar", 3);
  1887. rocksdb_iter_get_error(iter, &err);
  1888. CheckNoError(err);
  1889. CheckCondition(rocksdb_iter_valid(iter));
  1890. CheckIter(iter, "bar1", "bar");
  1891. rocksdb_iter_next(iter);
  1892. CheckIter(iter, "bar2", "bar");
  1893. rocksdb_iter_next(iter);
  1894. CheckIter(iter, "bar3", "bar");
  1895. rocksdb_iter_get_error(iter, &err);
  1896. CheckNoError(err);
  1897. rocksdb_iter_destroy(iter);
  1898. rocksdb_readoptions_set_total_order_seek(roptions, 1);
  1899. iter = rocksdb_create_iterator(db, roptions);
  1900. CheckCondition(!rocksdb_iter_valid(iter));
  1901. rocksdb_iter_seek(iter, "ba", 2);
  1902. rocksdb_iter_get_error(iter, &err);
  1903. CheckNoError(err);
  1904. CheckCondition(rocksdb_iter_valid(iter));
  1905. CheckIter(iter, "bar1", "bar");
  1906. rocksdb_iter_destroy(iter);
  1907. rocksdb_readoptions_set_total_order_seek(roptions, 0);
  1908. rocksdb_close(db);
  1909. {
  1910. const char* expected_cf_names[1] = {"default"};
  1911. LoadAndCheckLatestOptions(dbname, env, false, cache, NULL, 1,
  1912. expected_cf_names,
  1913. "Invalid argument: leveldb.BytewiseComparator: "
  1914. "does not match existing comparator foo");
  1915. LoadAndCheckLatestOptions(dbname, env, false, cache, cmp, 1,
  1916. expected_cf_names, NULL);
  1917. }
  1918. rocksdb_destroy_db(options, dbname, &err);
  1919. }
  1920. // Check memory usage stats
  1921. StartPhase("approximate_memory_usage");
  1922. {
  1923. // Create database
  1924. db = rocksdb_open(options, dbname, &err);
  1925. CheckNoError(err);
  1926. rocksdb_memory_consumers_t* consumers;
  1927. consumers = rocksdb_memory_consumers_create();
  1928. rocksdb_memory_consumers_add_db(consumers, db);
  1929. rocksdb_memory_consumers_add_cache(consumers, cache);
  1930. // take memory usage report before write-read operation
  1931. rocksdb_memory_usage_t* mu1;
  1932. mu1 = rocksdb_approximate_memory_usage_create(consumers, &err);
  1933. CheckNoError(err);
  1934. // Put data (this should affect memtables)
  1935. rocksdb_put(db, woptions, "memory", 6, "test", 4, &err);
  1936. CheckNoError(err);
  1937. CheckGet(db, roptions, "memory", "test");
  1938. // take memory usage report after write-read operation
  1939. rocksdb_memory_usage_t* mu2;
  1940. mu2 = rocksdb_approximate_memory_usage_create(consumers, &err);
  1941. CheckNoError(err);
  1942. // amount of memory used within memtables should grow
  1943. CheckCondition(rocksdb_approximate_memory_usage_get_mem_table_total(mu2) >=
  1944. rocksdb_approximate_memory_usage_get_mem_table_total(mu1));
  1945. CheckCondition(
  1946. rocksdb_approximate_memory_usage_get_mem_table_unflushed(mu2) >=
  1947. rocksdb_approximate_memory_usage_get_mem_table_unflushed(mu1));
  1948. rocksdb_memory_consumers_destroy(consumers);
  1949. rocksdb_approximate_memory_usage_destroy(mu1);
  1950. rocksdb_approximate_memory_usage_destroy(mu2);
  1951. rocksdb_close(db);
  1952. rocksdb_destroy_db(options, dbname, &err);
  1953. CheckNoError(err);
  1954. }
  1955. StartPhase("cuckoo_options");
  1956. {
  1957. rocksdb_cuckoo_table_options_t* cuckoo_options;
  1958. cuckoo_options = rocksdb_cuckoo_options_create();
  1959. rocksdb_cuckoo_options_set_hash_ratio(cuckoo_options, 0.5);
  1960. rocksdb_cuckoo_options_set_max_search_depth(cuckoo_options, 200);
  1961. rocksdb_cuckoo_options_set_cuckoo_block_size(cuckoo_options, 10);
  1962. rocksdb_cuckoo_options_set_identity_as_first_hash(cuckoo_options, 1);
  1963. rocksdb_cuckoo_options_set_use_module_hash(cuckoo_options, 0);
  1964. rocksdb_options_set_cuckoo_table_factory(options, cuckoo_options);
  1965. db = rocksdb_open(options, dbname, &err);
  1966. CheckNoError(err);
  1967. rocksdb_cuckoo_options_destroy(cuckoo_options);
  1968. }
  1969. StartPhase("options");
  1970. {
  1971. rocksdb_options_t* o;
  1972. o = rocksdb_options_create();
  1973. // Set and check options.
  1974. rocksdb_options_set_allow_ingest_behind(o, 1);
  1975. CheckCondition(1 == rocksdb_options_get_allow_ingest_behind(o));
  1976. rocksdb_options_compaction_readahead_size(o, 10);
  1977. CheckCondition(10 == rocksdb_options_get_compaction_readahead_size(o));
  1978. rocksdb_options_set_create_if_missing(o, 1);
  1979. CheckCondition(1 == rocksdb_options_get_create_if_missing(o));
  1980. rocksdb_options_set_create_missing_column_families(o, 1);
  1981. CheckCondition(1 == rocksdb_options_get_create_missing_column_families(o));
  1982. rocksdb_options_set_error_if_exists(o, 1);
  1983. CheckCondition(1 == rocksdb_options_get_error_if_exists(o));
  1984. rocksdb_options_set_paranoid_checks(o, 1);
  1985. CheckCondition(1 == rocksdb_options_get_paranoid_checks(o));
  1986. rocksdb_options_set_info_log_level(o, 3);
  1987. CheckCondition(3 == rocksdb_options_get_info_log_level(o));
  1988. rocksdb_options_set_write_buffer_size(o, 100);
  1989. CheckCondition(100 == rocksdb_options_get_write_buffer_size(o));
  1990. rocksdb_options_set_db_write_buffer_size(o, 1000);
  1991. CheckCondition(1000 == rocksdb_options_get_db_write_buffer_size(o));
  1992. rocksdb_options_set_max_open_files(o, 21);
  1993. CheckCondition(21 == rocksdb_options_get_max_open_files(o));
  1994. rocksdb_options_set_max_file_opening_threads(o, 5);
  1995. CheckCondition(5 == rocksdb_options_get_max_file_opening_threads(o));
  1996. rocksdb_options_set_max_total_wal_size(o, 400);
  1997. CheckCondition(400 == rocksdb_options_get_max_total_wal_size(o));
  1998. rocksdb_options_set_num_levels(o, 7);
  1999. CheckCondition(7 == rocksdb_options_get_num_levels(o));
  2000. rocksdb_options_set_level0_file_num_compaction_trigger(o, 4);
  2001. CheckCondition(4 ==
  2002. rocksdb_options_get_level0_file_num_compaction_trigger(o));
  2003. rocksdb_options_set_level0_slowdown_writes_trigger(o, 6);
  2004. CheckCondition(6 == rocksdb_options_get_level0_slowdown_writes_trigger(o));
  2005. rocksdb_options_set_level0_stop_writes_trigger(o, 8);
  2006. CheckCondition(8 == rocksdb_options_get_level0_stop_writes_trigger(o));
  2007. rocksdb_options_set_target_file_size_base(o, 256);
  2008. CheckCondition(256 == rocksdb_options_get_target_file_size_base(o));
  2009. rocksdb_options_set_target_file_size_multiplier(o, 3);
  2010. CheckCondition(3 == rocksdb_options_get_target_file_size_multiplier(o));
  2011. rocksdb_options_set_max_bytes_for_level_base(o, 1024);
  2012. CheckCondition(1024 == rocksdb_options_get_max_bytes_for_level_base(o));
  2013. rocksdb_options_set_level_compaction_dynamic_level_bytes(o, 1);
  2014. CheckCondition(1 ==
  2015. rocksdb_options_get_level_compaction_dynamic_level_bytes(o));
  2016. rocksdb_options_set_max_bytes_for_level_multiplier(o, 2.0);
  2017. CheckCondition(2.0 ==
  2018. rocksdb_options_get_max_bytes_for_level_multiplier(o));
  2019. rocksdb_options_set_periodic_compaction_seconds(o, 100000);
  2020. CheckCondition(100000 ==
  2021. rocksdb_options_get_periodic_compaction_seconds(o));
  2022. rocksdb_options_set_memtable_op_scan_flush_trigger(o, 100);
  2023. CheckCondition(100 ==
  2024. rocksdb_options_get_memtable_op_scan_flush_trigger(o));
  2025. rocksdb_options_set_memtable_avg_op_scan_flush_trigger(o, 150);
  2026. CheckCondition(150 ==
  2027. rocksdb_options_get_memtable_avg_op_scan_flush_trigger(o));
  2028. rocksdb_options_set_ttl(o, 5000);
  2029. CheckCondition(5000 == rocksdb_options_get_ttl(o));
  2030. rocksdb_options_set_skip_stats_update_on_db_open(o, 1);
  2031. CheckCondition(1 == rocksdb_options_get_skip_stats_update_on_db_open(o));
  2032. rocksdb_options_set_max_write_buffer_number(o, 97);
  2033. CheckCondition(97 == rocksdb_options_get_max_write_buffer_number(o));
  2034. rocksdb_options_set_min_write_buffer_number_to_merge(o, 23);
  2035. CheckCondition(23 ==
  2036. rocksdb_options_get_min_write_buffer_number_to_merge(o));
  2037. rocksdb_options_set_max_write_buffer_size_to_maintain(o, 50000);
  2038. CheckCondition(50000 ==
  2039. rocksdb_options_get_max_write_buffer_size_to_maintain(o));
  2040. rocksdb_options_set_enable_pipelined_write(o, 1);
  2041. CheckCondition(1 == rocksdb_options_get_enable_pipelined_write(o));
  2042. rocksdb_options_set_unordered_write(o, 1);
  2043. CheckCondition(1 == rocksdb_options_get_unordered_write(o));
  2044. rocksdb_options_set_max_subcompactions(o, 123456);
  2045. CheckCondition(123456 == rocksdb_options_get_max_subcompactions(o));
  2046. rocksdb_options_set_max_background_jobs(o, 2);
  2047. CheckCondition(2 == rocksdb_options_get_max_background_jobs(o));
  2048. rocksdb_options_set_max_background_compactions(o, 3);
  2049. CheckCondition(3 == rocksdb_options_get_max_background_compactions(o));
  2050. rocksdb_options_set_max_background_flushes(o, 5);
  2051. CheckCondition(5 == rocksdb_options_get_max_background_flushes(o));
  2052. rocksdb_options_set_max_log_file_size(o, 6);
  2053. CheckCondition(6 == rocksdb_options_get_max_log_file_size(o));
  2054. rocksdb_options_set_log_file_time_to_roll(o, 7);
  2055. CheckCondition(7 == rocksdb_options_get_log_file_time_to_roll(o));
  2056. rocksdb_options_set_keep_log_file_num(o, 8);
  2057. CheckCondition(8 == rocksdb_options_get_keep_log_file_num(o));
  2058. rocksdb_options_set_recycle_log_file_num(o, 9);
  2059. CheckCondition(9 == rocksdb_options_get_recycle_log_file_num(o));
  2060. rocksdb_options_set_soft_pending_compaction_bytes_limit(o, 10);
  2061. CheckCondition(10 ==
  2062. rocksdb_options_get_soft_pending_compaction_bytes_limit(o));
  2063. rocksdb_options_set_hard_pending_compaction_bytes_limit(o, 11);
  2064. CheckCondition(11 ==
  2065. rocksdb_options_get_hard_pending_compaction_bytes_limit(o));
  2066. rocksdb_options_set_max_manifest_file_size(o, 12);
  2067. CheckCondition(12 == rocksdb_options_get_max_manifest_file_size(o));
  2068. rocksdb_options_set_table_cache_numshardbits(o, 13);
  2069. CheckCondition(13 == rocksdb_options_get_table_cache_numshardbits(o));
  2070. rocksdb_options_set_arena_block_size(o, 14);
  2071. CheckCondition(14 == rocksdb_options_get_arena_block_size(o));
  2072. rocksdb_options_set_use_fsync(o, 1);
  2073. CheckCondition(1 == rocksdb_options_get_use_fsync(o));
  2074. rocksdb_options_set_WAL_ttl_seconds(o, 15);
  2075. CheckCondition(15 == rocksdb_options_get_WAL_ttl_seconds(o));
  2076. rocksdb_options_set_WAL_size_limit_MB(o, 16);
  2077. CheckCondition(16 == rocksdb_options_get_WAL_size_limit_MB(o));
  2078. rocksdb_options_set_manifest_preallocation_size(o, 17);
  2079. CheckCondition(17 == rocksdb_options_get_manifest_preallocation_size(o));
  2080. rocksdb_options_set_allow_mmap_reads(o, 1);
  2081. CheckCondition(1 == rocksdb_options_get_allow_mmap_reads(o));
  2082. rocksdb_options_set_allow_mmap_writes(o, 1);
  2083. CheckCondition(1 == rocksdb_options_get_allow_mmap_writes(o));
  2084. rocksdb_options_set_use_direct_reads(o, 1);
  2085. CheckCondition(1 == rocksdb_options_get_use_direct_reads(o));
  2086. rocksdb_options_set_use_direct_io_for_flush_and_compaction(o, 1);
  2087. CheckCondition(
  2088. 1 == rocksdb_options_get_use_direct_io_for_flush_and_compaction(o));
  2089. rocksdb_options_set_is_fd_close_on_exec(o, 1);
  2090. CheckCondition(1 == rocksdb_options_get_is_fd_close_on_exec(o));
  2091. rocksdb_options_set_stats_dump_period_sec(o, 18);
  2092. CheckCondition(18 == rocksdb_options_get_stats_dump_period_sec(o));
  2093. rocksdb_options_set_stats_persist_period_sec(o, 5);
  2094. CheckCondition(5 == rocksdb_options_get_stats_persist_period_sec(o));
  2095. rocksdb_options_set_advise_random_on_open(o, 1);
  2096. CheckCondition(1 == rocksdb_options_get_advise_random_on_open(o));
  2097. rocksdb_options_set_use_adaptive_mutex(o, 1);
  2098. CheckCondition(1 == rocksdb_options_get_use_adaptive_mutex(o));
  2099. rocksdb_options_set_bytes_per_sync(o, 19);
  2100. CheckCondition(19 == rocksdb_options_get_bytes_per_sync(o));
  2101. rocksdb_options_set_wal_bytes_per_sync(o, 20);
  2102. CheckCondition(20 == rocksdb_options_get_wal_bytes_per_sync(o));
  2103. rocksdb_options_set_writable_file_max_buffer_size(o, 21);
  2104. CheckCondition(21 == rocksdb_options_get_writable_file_max_buffer_size(o));
  2105. rocksdb_options_set_allow_concurrent_memtable_write(o, 1);
  2106. CheckCondition(1 == rocksdb_options_get_allow_concurrent_memtable_write(o));
  2107. rocksdb_options_set_enable_write_thread_adaptive_yield(o, 1);
  2108. CheckCondition(1 ==
  2109. rocksdb_options_get_enable_write_thread_adaptive_yield(o));
  2110. rocksdb_options_set_max_sequential_skip_in_iterations(o, 22);
  2111. CheckCondition(22 ==
  2112. rocksdb_options_get_max_sequential_skip_in_iterations(o));
  2113. rocksdb_options_set_disable_auto_compactions(o, 1);
  2114. CheckCondition(1 == rocksdb_options_get_disable_auto_compactions(o));
  2115. rocksdb_options_set_optimize_filters_for_hits(o, 1);
  2116. CheckCondition(1 == rocksdb_options_get_optimize_filters_for_hits(o));
  2117. rocksdb_options_set_delete_obsolete_files_period_micros(o, 23);
  2118. CheckCondition(23 ==
  2119. rocksdb_options_get_delete_obsolete_files_period_micros(o));
  2120. rocksdb_options_set_memtable_prefix_bloom_size_ratio(o, 2.0);
  2121. CheckCondition(2.0 ==
  2122. rocksdb_options_get_memtable_prefix_bloom_size_ratio(o));
  2123. rocksdb_options_set_max_compaction_bytes(o, 24);
  2124. CheckCondition(24 == rocksdb_options_get_max_compaction_bytes(o));
  2125. rocksdb_options_set_memtable_huge_page_size(o, 25);
  2126. CheckCondition(25 == rocksdb_options_get_memtable_huge_page_size(o));
  2127. rocksdb_options_set_max_successive_merges(o, 26);
  2128. CheckCondition(26 == rocksdb_options_get_max_successive_merges(o));
  2129. rocksdb_options_set_bloom_locality(o, 27);
  2130. CheckCondition(27 == rocksdb_options_get_bloom_locality(o));
  2131. rocksdb_options_set_inplace_update_support(o, 1);
  2132. CheckCondition(1 == rocksdb_options_get_inplace_update_support(o));
  2133. rocksdb_options_set_inplace_update_num_locks(o, 28);
  2134. CheckCondition(28 == rocksdb_options_get_inplace_update_num_locks(o));
  2135. rocksdb_options_set_report_bg_io_stats(o, 1);
  2136. CheckCondition(1 == rocksdb_options_get_report_bg_io_stats(o));
  2137. rocksdb_options_set_wal_recovery_mode(o, 2);
  2138. CheckCondition(2 == rocksdb_options_get_wal_recovery_mode(o));
  2139. rocksdb_options_set_compression(o, 5);
  2140. CheckCondition(5 == rocksdb_options_get_compression(o));
  2141. rocksdb_options_set_bottommost_compression(o, 4);
  2142. CheckCondition(4 == rocksdb_options_get_bottommost_compression(o));
  2143. rocksdb_options_set_compaction_style(o, 2);
  2144. CheckCondition(2 == rocksdb_options_get_compaction_style(o));
  2145. rocksdb_options_set_compaction_pri(o, 4);
  2146. CheckCondition(4 == rocksdb_options_get_compaction_pri(o));
  2147. rocksdb_options_set_atomic_flush(o, 1);
  2148. CheckCondition(1 == rocksdb_options_get_atomic_flush(o));
  2149. rocksdb_options_set_manual_wal_flush(o, 1);
  2150. CheckCondition(1 == rocksdb_options_get_manual_wal_flush(o));
  2151. rocksdb_options_set_wal_compression(o, 1);
  2152. CheckCondition(1 == rocksdb_options_get_wal_compression(o));
  2153. rocksdb_options_set_experimental_mempurge_threshold(o, 29.0);
  2154. CheckCondition(29.0 ==
  2155. rocksdb_options_get_experimental_mempurge_threshold(o));
  2156. CheckCondition(rocksdb_statistics_level_disable_all ==
  2157. rocksdb_options_get_statistics_level(o));
  2158. rocksdb_options_enable_statistics(o);
  2159. CheckCondition(rocksdb_statistics_level_disable_all !=
  2160. rocksdb_options_get_statistics_level(o));
  2161. rocksdb_options_set_statistics_level(o, rocksdb_statistics_level_all);
  2162. CheckCondition(rocksdb_statistics_level_all ==
  2163. rocksdb_options_get_statistics_level(o));
  2164. CheckCondition(0 ==
  2165. rocksdb_options_get_track_and_verify_wals_in_manifest(o));
  2166. rocksdb_options_set_track_and_verify_wals_in_manifest(o, 42);
  2167. CheckCondition(1 ==
  2168. rocksdb_options_get_track_and_verify_wals_in_manifest(o));
  2169. /* Blob Options */
  2170. rocksdb_options_set_enable_blob_files(o, 1);
  2171. CheckCondition(1 == rocksdb_options_get_enable_blob_files(o));
  2172. rocksdb_options_set_min_blob_size(o, 29);
  2173. CheckCondition(29 == rocksdb_options_get_min_blob_size(o));
  2174. rocksdb_options_set_blob_file_size(o, 30);
  2175. CheckCondition(30 == rocksdb_options_get_blob_file_size(o));
  2176. rocksdb_options_set_blob_compression_type(o, 4);
  2177. CheckCondition(4 == rocksdb_options_get_blob_compression_type(o));
  2178. rocksdb_options_set_enable_blob_gc(o, 1);
  2179. CheckCondition(1 == rocksdb_options_get_enable_blob_gc(o));
  2180. rocksdb_options_set_blob_gc_age_cutoff(o, 0.5);
  2181. CheckCondition(0.5 == rocksdb_options_get_blob_gc_age_cutoff(o));
  2182. rocksdb_options_set_blob_gc_force_threshold(o, 0.75);
  2183. CheckCondition(0.75 == rocksdb_options_get_blob_gc_force_threshold(o));
  2184. rocksdb_options_set_blob_compaction_readahead_size(o, 262144);
  2185. CheckCondition(262144 ==
  2186. rocksdb_options_get_blob_compaction_readahead_size(o));
  2187. rocksdb_options_set_blob_file_starting_level(o, 5);
  2188. CheckCondition(5 == rocksdb_options_get_blob_file_starting_level(o));
  2189. rocksdb_options_set_prepopulate_blob_cache(o, 1 /* flush only */);
  2190. CheckCondition(1 == rocksdb_options_get_prepopulate_blob_cache(o));
  2191. // Create a copy that should be equal to the original.
  2192. rocksdb_options_t* copy;
  2193. copy = rocksdb_options_create_copy(o);
  2194. CheckCondition(1 == rocksdb_options_get_allow_ingest_behind(copy));
  2195. CheckCondition(10 == rocksdb_options_get_compaction_readahead_size(copy));
  2196. CheckCondition(1 == rocksdb_options_get_create_if_missing(copy));
  2197. CheckCondition(1 ==
  2198. rocksdb_options_get_create_missing_column_families(copy));
  2199. CheckCondition(1 == rocksdb_options_get_error_if_exists(copy));
  2200. CheckCondition(1 == rocksdb_options_get_paranoid_checks(copy));
  2201. CheckCondition(3 == rocksdb_options_get_info_log_level(copy));
  2202. CheckCondition(100 == rocksdb_options_get_write_buffer_size(copy));
  2203. CheckCondition(1000 == rocksdb_options_get_db_write_buffer_size(copy));
  2204. CheckCondition(21 == rocksdb_options_get_max_open_files(copy));
  2205. CheckCondition(5 == rocksdb_options_get_max_file_opening_threads(copy));
  2206. CheckCondition(400 == rocksdb_options_get_max_total_wal_size(copy));
  2207. CheckCondition(7 == rocksdb_options_get_num_levels(copy));
  2208. CheckCondition(
  2209. 4 == rocksdb_options_get_level0_file_num_compaction_trigger(copy));
  2210. CheckCondition(6 ==
  2211. rocksdb_options_get_level0_slowdown_writes_trigger(copy));
  2212. CheckCondition(8 == rocksdb_options_get_level0_stop_writes_trigger(copy));
  2213. CheckCondition(256 == rocksdb_options_get_target_file_size_base(copy));
  2214. CheckCondition(3 == rocksdb_options_get_target_file_size_multiplier(copy));
  2215. CheckCondition(1024 == rocksdb_options_get_max_bytes_for_level_base(copy));
  2216. CheckCondition(
  2217. 1 == rocksdb_options_get_level_compaction_dynamic_level_bytes(copy));
  2218. CheckCondition(2.0 ==
  2219. rocksdb_options_get_max_bytes_for_level_multiplier(copy));
  2220. CheckCondition(1 == rocksdb_options_get_skip_stats_update_on_db_open(copy));
  2221. CheckCondition(97 == rocksdb_options_get_max_write_buffer_number(copy));
  2222. CheckCondition(23 ==
  2223. rocksdb_options_get_min_write_buffer_number_to_merge(copy));
  2224. CheckCondition(50000 ==
  2225. rocksdb_options_get_max_write_buffer_size_to_maintain(copy));
  2226. CheckCondition(1 == rocksdb_options_get_enable_pipelined_write(copy));
  2227. CheckCondition(1 == rocksdb_options_get_unordered_write(copy));
  2228. CheckCondition(123456 == rocksdb_options_get_max_subcompactions(copy));
  2229. CheckCondition(2 == rocksdb_options_get_max_background_jobs(copy));
  2230. CheckCondition(3 == rocksdb_options_get_max_background_compactions(copy));
  2231. CheckCondition(5 == rocksdb_options_get_max_background_flushes(copy));
  2232. CheckCondition(6 == rocksdb_options_get_max_log_file_size(copy));
  2233. CheckCondition(7 == rocksdb_options_get_log_file_time_to_roll(copy));
  2234. CheckCondition(8 == rocksdb_options_get_keep_log_file_num(copy));
  2235. CheckCondition(9 == rocksdb_options_get_recycle_log_file_num(copy));
  2236. CheckCondition(
  2237. 10 == rocksdb_options_get_soft_pending_compaction_bytes_limit(copy));
  2238. CheckCondition(
  2239. 11 == rocksdb_options_get_hard_pending_compaction_bytes_limit(copy));
  2240. CheckCondition(12 == rocksdb_options_get_max_manifest_file_size(copy));
  2241. CheckCondition(13 == rocksdb_options_get_table_cache_numshardbits(copy));
  2242. CheckCondition(14 == rocksdb_options_get_arena_block_size(copy));
  2243. CheckCondition(1 == rocksdb_options_get_use_fsync(copy));
  2244. CheckCondition(15 == rocksdb_options_get_WAL_ttl_seconds(copy));
  2245. CheckCondition(16 == rocksdb_options_get_WAL_size_limit_MB(copy));
  2246. CheckCondition(17 == rocksdb_options_get_manifest_preallocation_size(copy));
  2247. CheckCondition(1 == rocksdb_options_get_allow_mmap_reads(copy));
  2248. CheckCondition(1 == rocksdb_options_get_allow_mmap_writes(copy));
  2249. CheckCondition(1 == rocksdb_options_get_use_direct_reads(copy));
  2250. CheckCondition(
  2251. 1 == rocksdb_options_get_use_direct_io_for_flush_and_compaction(copy));
  2252. CheckCondition(1 == rocksdb_options_get_is_fd_close_on_exec(copy));
  2253. CheckCondition(18 == rocksdb_options_get_stats_dump_period_sec(copy));
  2254. CheckCondition(5 == rocksdb_options_get_stats_persist_period_sec(copy));
  2255. CheckCondition(1 == rocksdb_options_get_advise_random_on_open(copy));
  2256. CheckCondition(1 == rocksdb_options_get_use_adaptive_mutex(copy));
  2257. CheckCondition(19 == rocksdb_options_get_bytes_per_sync(copy));
  2258. CheckCondition(20 == rocksdb_options_get_wal_bytes_per_sync(copy));
  2259. CheckCondition(21 ==
  2260. rocksdb_options_get_writable_file_max_buffer_size(copy));
  2261. CheckCondition(1 ==
  2262. rocksdb_options_get_allow_concurrent_memtable_write(copy));
  2263. CheckCondition(
  2264. 1 == rocksdb_options_get_enable_write_thread_adaptive_yield(copy));
  2265. CheckCondition(22 ==
  2266. rocksdb_options_get_max_sequential_skip_in_iterations(copy));
  2267. CheckCondition(1 == rocksdb_options_get_disable_auto_compactions(copy));
  2268. CheckCondition(1 == rocksdb_options_get_optimize_filters_for_hits(copy));
  2269. CheckCondition(
  2270. 23 == rocksdb_options_get_delete_obsolete_files_period_micros(copy));
  2271. CheckCondition(2.0 ==
  2272. rocksdb_options_get_memtable_prefix_bloom_size_ratio(copy));
  2273. CheckCondition(24 == rocksdb_options_get_max_compaction_bytes(copy));
  2274. CheckCondition(25 == rocksdb_options_get_memtable_huge_page_size(copy));
  2275. CheckCondition(26 == rocksdb_options_get_max_successive_merges(copy));
  2276. CheckCondition(27 == rocksdb_options_get_bloom_locality(copy));
  2277. CheckCondition(1 == rocksdb_options_get_inplace_update_support(copy));
  2278. CheckCondition(28 == rocksdb_options_get_inplace_update_num_locks(copy));
  2279. CheckCondition(1 == rocksdb_options_get_report_bg_io_stats(copy));
  2280. CheckCondition(2 == rocksdb_options_get_wal_recovery_mode(copy));
  2281. CheckCondition(5 == rocksdb_options_get_compression(copy));
  2282. CheckCondition(4 == rocksdb_options_get_bottommost_compression(copy));
  2283. CheckCondition(2 == rocksdb_options_get_compaction_style(copy));
  2284. CheckCondition(1 == rocksdb_options_get_atomic_flush(copy));
  2285. CheckCondition(29.0 ==
  2286. rocksdb_options_get_experimental_mempurge_threshold(copy));
  2287. // Copies should be independent.
  2288. rocksdb_options_set_allow_ingest_behind(copy, 0);
  2289. CheckCondition(0 == rocksdb_options_get_allow_ingest_behind(copy));
  2290. CheckCondition(1 == rocksdb_options_get_allow_ingest_behind(o));
  2291. rocksdb_options_compaction_readahead_size(copy, 20);
  2292. CheckCondition(20 == rocksdb_options_get_compaction_readahead_size(copy));
  2293. CheckCondition(10 == rocksdb_options_get_compaction_readahead_size(o));
  2294. rocksdb_options_set_create_if_missing(copy, 0);
  2295. CheckCondition(0 == rocksdb_options_get_create_if_missing(copy));
  2296. CheckCondition(1 == rocksdb_options_get_create_if_missing(o));
  2297. rocksdb_options_set_create_missing_column_families(copy, 0);
  2298. CheckCondition(0 ==
  2299. rocksdb_options_get_create_missing_column_families(copy));
  2300. CheckCondition(1 == rocksdb_options_get_create_missing_column_families(o));
  2301. rocksdb_options_set_error_if_exists(copy, 0);
  2302. CheckCondition(0 == rocksdb_options_get_error_if_exists(copy));
  2303. CheckCondition(1 == rocksdb_options_get_error_if_exists(o));
  2304. rocksdb_options_set_paranoid_checks(copy, 0);
  2305. CheckCondition(0 == rocksdb_options_get_paranoid_checks(copy));
  2306. CheckCondition(1 == rocksdb_options_get_paranoid_checks(o));
  2307. rocksdb_options_set_info_log_level(copy, 2);
  2308. CheckCondition(2 == rocksdb_options_get_info_log_level(copy));
  2309. CheckCondition(3 == rocksdb_options_get_info_log_level(o));
  2310. rocksdb_options_set_write_buffer_size(copy, 200);
  2311. CheckCondition(200 == rocksdb_options_get_write_buffer_size(copy));
  2312. CheckCondition(100 == rocksdb_options_get_write_buffer_size(o));
  2313. rocksdb_options_set_db_write_buffer_size(copy, 2000);
  2314. CheckCondition(2000 == rocksdb_options_get_db_write_buffer_size(copy));
  2315. CheckCondition(1000 == rocksdb_options_get_db_write_buffer_size(o));
  2316. rocksdb_options_set_max_open_files(copy, 42);
  2317. CheckCondition(42 == rocksdb_options_get_max_open_files(copy));
  2318. CheckCondition(21 == rocksdb_options_get_max_open_files(o));
  2319. rocksdb_options_set_max_file_opening_threads(copy, 3);
  2320. CheckCondition(3 == rocksdb_options_get_max_file_opening_threads(copy));
  2321. CheckCondition(5 == rocksdb_options_get_max_file_opening_threads(o));
  2322. rocksdb_options_set_max_total_wal_size(copy, 4000);
  2323. CheckCondition(4000 == rocksdb_options_get_max_total_wal_size(copy));
  2324. CheckCondition(400 == rocksdb_options_get_max_total_wal_size(o));
  2325. rocksdb_options_set_num_levels(copy, 6);
  2326. CheckCondition(6 == rocksdb_options_get_num_levels(copy));
  2327. CheckCondition(7 == rocksdb_options_get_num_levels(o));
  2328. rocksdb_options_set_level0_file_num_compaction_trigger(copy, 14);
  2329. CheckCondition(
  2330. 14 == rocksdb_options_get_level0_file_num_compaction_trigger(copy));
  2331. CheckCondition(4 ==
  2332. rocksdb_options_get_level0_file_num_compaction_trigger(o));
  2333. rocksdb_options_set_level0_slowdown_writes_trigger(copy, 61);
  2334. CheckCondition(61 ==
  2335. rocksdb_options_get_level0_slowdown_writes_trigger(copy));
  2336. CheckCondition(6 == rocksdb_options_get_level0_slowdown_writes_trigger(o));
  2337. rocksdb_options_set_level0_stop_writes_trigger(copy, 17);
  2338. CheckCondition(17 == rocksdb_options_get_level0_stop_writes_trigger(copy));
  2339. CheckCondition(8 == rocksdb_options_get_level0_stop_writes_trigger(o));
  2340. rocksdb_options_set_target_file_size_base(copy, 128);
  2341. CheckCondition(128 == rocksdb_options_get_target_file_size_base(copy));
  2342. CheckCondition(256 == rocksdb_options_get_target_file_size_base(o));
  2343. rocksdb_options_set_target_file_size_multiplier(copy, 13);
  2344. CheckCondition(13 == rocksdb_options_get_target_file_size_multiplier(copy));
  2345. CheckCondition(3 == rocksdb_options_get_target_file_size_multiplier(o));
  2346. rocksdb_options_set_max_bytes_for_level_base(copy, 900);
  2347. CheckCondition(900 == rocksdb_options_get_max_bytes_for_level_base(copy));
  2348. CheckCondition(1024 == rocksdb_options_get_max_bytes_for_level_base(o));
  2349. rocksdb_options_set_level_compaction_dynamic_level_bytes(copy, 0);
  2350. CheckCondition(
  2351. 0 == rocksdb_options_get_level_compaction_dynamic_level_bytes(copy));
  2352. CheckCondition(1 ==
  2353. rocksdb_options_get_level_compaction_dynamic_level_bytes(o));
  2354. rocksdb_options_set_max_bytes_for_level_multiplier(copy, 8.0);
  2355. CheckCondition(8.0 ==
  2356. rocksdb_options_get_max_bytes_for_level_multiplier(copy));
  2357. CheckCondition(2.0 ==
  2358. rocksdb_options_get_max_bytes_for_level_multiplier(o));
  2359. rocksdb_options_set_periodic_compaction_seconds(copy, 8000);
  2360. CheckCondition(8000 ==
  2361. rocksdb_options_get_periodic_compaction_seconds(copy));
  2362. CheckCondition(100000 ==
  2363. rocksdb_options_get_periodic_compaction_seconds(o));
  2364. rocksdb_options_set_memtable_op_scan_flush_trigger(copy, 800);
  2365. CheckCondition(800 ==
  2366. rocksdb_options_get_memtable_op_scan_flush_trigger(copy));
  2367. CheckCondition(100 ==
  2368. rocksdb_options_get_memtable_op_scan_flush_trigger(o));
  2369. rocksdb_options_set_memtable_avg_op_scan_flush_trigger(copy, 900);
  2370. CheckCondition(
  2371. 900 == rocksdb_options_get_memtable_avg_op_scan_flush_trigger(copy));
  2372. CheckCondition(150 ==
  2373. rocksdb_options_get_memtable_avg_op_scan_flush_trigger(o));
  2374. rocksdb_options_set_ttl(copy, 8000);
  2375. CheckCondition(8000 == rocksdb_options_get_ttl(copy));
  2376. CheckCondition(5000 == rocksdb_options_get_ttl(o));
  2377. rocksdb_options_set_skip_stats_update_on_db_open(copy, 0);
  2378. CheckCondition(0 == rocksdb_options_get_skip_stats_update_on_db_open(copy));
  2379. CheckCondition(1 == rocksdb_options_get_skip_stats_update_on_db_open(o));
  2380. rocksdb_options_set_max_write_buffer_number(copy, 2000);
  2381. CheckCondition(2000 == rocksdb_options_get_max_write_buffer_number(copy));
  2382. CheckCondition(97 == rocksdb_options_get_max_write_buffer_number(o));
  2383. rocksdb_options_set_min_write_buffer_number_to_merge(copy, 146);
  2384. CheckCondition(146 ==
  2385. rocksdb_options_get_min_write_buffer_number_to_merge(copy));
  2386. CheckCondition(23 ==
  2387. rocksdb_options_get_min_write_buffer_number_to_merge(o));
  2388. rocksdb_options_set_max_write_buffer_size_to_maintain(copy, 9000);
  2389. CheckCondition(9000 ==
  2390. rocksdb_options_get_max_write_buffer_size_to_maintain(copy));
  2391. CheckCondition(50000 ==
  2392. rocksdb_options_get_max_write_buffer_size_to_maintain(o));
  2393. rocksdb_options_set_enable_pipelined_write(copy, 0);
  2394. CheckCondition(0 == rocksdb_options_get_enable_pipelined_write(copy));
  2395. CheckCondition(1 == rocksdb_options_get_enable_pipelined_write(o));
  2396. rocksdb_options_set_unordered_write(copy, 0);
  2397. CheckCondition(0 == rocksdb_options_get_unordered_write(copy));
  2398. CheckCondition(1 == rocksdb_options_get_unordered_write(o));
  2399. rocksdb_options_set_max_subcompactions(copy, 90001);
  2400. CheckCondition(90001 == rocksdb_options_get_max_subcompactions(copy));
  2401. CheckCondition(123456 == rocksdb_options_get_max_subcompactions(o));
  2402. rocksdb_options_set_max_background_jobs(copy, 12);
  2403. CheckCondition(12 == rocksdb_options_get_max_background_jobs(copy));
  2404. CheckCondition(2 == rocksdb_options_get_max_background_jobs(o));
  2405. rocksdb_options_set_max_background_compactions(copy, 13);
  2406. CheckCondition(13 == rocksdb_options_get_max_background_compactions(copy));
  2407. CheckCondition(3 == rocksdb_options_get_max_background_compactions(o));
  2408. rocksdb_options_set_max_background_flushes(copy, 15);
  2409. CheckCondition(15 == rocksdb_options_get_max_background_flushes(copy));
  2410. CheckCondition(5 == rocksdb_options_get_max_background_flushes(o));
  2411. rocksdb_options_set_max_log_file_size(copy, 16);
  2412. CheckCondition(16 == rocksdb_options_get_max_log_file_size(copy));
  2413. CheckCondition(6 == rocksdb_options_get_max_log_file_size(o));
  2414. rocksdb_options_set_log_file_time_to_roll(copy, 17);
  2415. CheckCondition(17 == rocksdb_options_get_log_file_time_to_roll(copy));
  2416. CheckCondition(7 == rocksdb_options_get_log_file_time_to_roll(o));
  2417. rocksdb_options_set_keep_log_file_num(copy, 18);
  2418. CheckCondition(18 == rocksdb_options_get_keep_log_file_num(copy));
  2419. CheckCondition(8 == rocksdb_options_get_keep_log_file_num(o));
  2420. rocksdb_options_set_recycle_log_file_num(copy, 19);
  2421. CheckCondition(19 == rocksdb_options_get_recycle_log_file_num(copy));
  2422. CheckCondition(9 == rocksdb_options_get_recycle_log_file_num(o));
  2423. rocksdb_options_set_soft_pending_compaction_bytes_limit(copy, 110);
  2424. CheckCondition(
  2425. 110 == rocksdb_options_get_soft_pending_compaction_bytes_limit(copy));
  2426. CheckCondition(10 ==
  2427. rocksdb_options_get_soft_pending_compaction_bytes_limit(o));
  2428. rocksdb_options_set_hard_pending_compaction_bytes_limit(copy, 111);
  2429. CheckCondition(
  2430. 111 == rocksdb_options_get_hard_pending_compaction_bytes_limit(copy));
  2431. CheckCondition(11 ==
  2432. rocksdb_options_get_hard_pending_compaction_bytes_limit(o));
  2433. rocksdb_options_set_max_manifest_file_size(copy, 112);
  2434. CheckCondition(112 == rocksdb_options_get_max_manifest_file_size(copy));
  2435. CheckCondition(12 == rocksdb_options_get_max_manifest_file_size(o));
  2436. rocksdb_options_set_table_cache_numshardbits(copy, 113);
  2437. CheckCondition(113 == rocksdb_options_get_table_cache_numshardbits(copy));
  2438. CheckCondition(13 == rocksdb_options_get_table_cache_numshardbits(o));
  2439. rocksdb_options_set_arena_block_size(copy, 114);
  2440. CheckCondition(114 == rocksdb_options_get_arena_block_size(copy));
  2441. CheckCondition(14 == rocksdb_options_get_arena_block_size(o));
  2442. rocksdb_options_set_use_fsync(copy, 0);
  2443. CheckCondition(0 == rocksdb_options_get_use_fsync(copy));
  2444. CheckCondition(1 == rocksdb_options_get_use_fsync(o));
  2445. rocksdb_options_set_WAL_ttl_seconds(copy, 115);
  2446. CheckCondition(115 == rocksdb_options_get_WAL_ttl_seconds(copy));
  2447. CheckCondition(15 == rocksdb_options_get_WAL_ttl_seconds(o));
  2448. rocksdb_options_set_WAL_size_limit_MB(copy, 116);
  2449. CheckCondition(116 == rocksdb_options_get_WAL_size_limit_MB(copy));
  2450. CheckCondition(16 == rocksdb_options_get_WAL_size_limit_MB(o));
  2451. rocksdb_options_set_manifest_preallocation_size(copy, 117);
  2452. CheckCondition(117 ==
  2453. rocksdb_options_get_manifest_preallocation_size(copy));
  2454. CheckCondition(17 == rocksdb_options_get_manifest_preallocation_size(o));
  2455. rocksdb_options_set_allow_mmap_reads(copy, 0);
  2456. CheckCondition(0 == rocksdb_options_get_allow_mmap_reads(copy));
  2457. CheckCondition(1 == rocksdb_options_get_allow_mmap_reads(o));
  2458. rocksdb_options_set_allow_mmap_writes(copy, 0);
  2459. CheckCondition(0 == rocksdb_options_get_allow_mmap_writes(copy));
  2460. CheckCondition(1 == rocksdb_options_get_allow_mmap_writes(o));
  2461. rocksdb_options_set_use_direct_reads(copy, 0);
  2462. CheckCondition(0 == rocksdb_options_get_use_direct_reads(copy));
  2463. CheckCondition(1 == rocksdb_options_get_use_direct_reads(o));
  2464. rocksdb_options_set_use_direct_io_for_flush_and_compaction(copy, 0);
  2465. CheckCondition(
  2466. 0 == rocksdb_options_get_use_direct_io_for_flush_and_compaction(copy));
  2467. CheckCondition(
  2468. 1 == rocksdb_options_get_use_direct_io_for_flush_and_compaction(o));
  2469. rocksdb_options_set_is_fd_close_on_exec(copy, 0);
  2470. CheckCondition(0 == rocksdb_options_get_is_fd_close_on_exec(copy));
  2471. CheckCondition(1 == rocksdb_options_get_is_fd_close_on_exec(o));
  2472. rocksdb_options_set_stats_dump_period_sec(copy, 218);
  2473. CheckCondition(218 == rocksdb_options_get_stats_dump_period_sec(copy));
  2474. CheckCondition(18 == rocksdb_options_get_stats_dump_period_sec(o));
  2475. rocksdb_options_set_stats_persist_period_sec(copy, 600);
  2476. CheckCondition(600 == rocksdb_options_get_stats_persist_period_sec(copy));
  2477. CheckCondition(5 == rocksdb_options_get_stats_persist_period_sec(o));
  2478. rocksdb_options_set_advise_random_on_open(copy, 0);
  2479. CheckCondition(0 == rocksdb_options_get_advise_random_on_open(copy));
  2480. CheckCondition(1 == rocksdb_options_get_advise_random_on_open(o));
  2481. rocksdb_options_set_use_adaptive_mutex(copy, 0);
  2482. CheckCondition(0 == rocksdb_options_get_use_adaptive_mutex(copy));
  2483. CheckCondition(1 == rocksdb_options_get_use_adaptive_mutex(o));
  2484. rocksdb_options_set_bytes_per_sync(copy, 219);
  2485. CheckCondition(219 == rocksdb_options_get_bytes_per_sync(copy));
  2486. CheckCondition(19 == rocksdb_options_get_bytes_per_sync(o));
  2487. rocksdb_options_set_wal_bytes_per_sync(copy, 120);
  2488. CheckCondition(120 == rocksdb_options_get_wal_bytes_per_sync(copy));
  2489. CheckCondition(20 == rocksdb_options_get_wal_bytes_per_sync(o));
  2490. rocksdb_options_set_writable_file_max_buffer_size(copy, 121);
  2491. CheckCondition(121 ==
  2492. rocksdb_options_get_writable_file_max_buffer_size(copy));
  2493. CheckCondition(21 == rocksdb_options_get_writable_file_max_buffer_size(o));
  2494. rocksdb_options_set_allow_concurrent_memtable_write(copy, 0);
  2495. CheckCondition(0 ==
  2496. rocksdb_options_get_allow_concurrent_memtable_write(copy));
  2497. CheckCondition(1 == rocksdb_options_get_allow_concurrent_memtable_write(o));
  2498. rocksdb_options_set_enable_write_thread_adaptive_yield(copy, 0);
  2499. CheckCondition(
  2500. 0 == rocksdb_options_get_enable_write_thread_adaptive_yield(copy));
  2501. CheckCondition(1 ==
  2502. rocksdb_options_get_enable_write_thread_adaptive_yield(o));
  2503. rocksdb_options_set_max_sequential_skip_in_iterations(copy, 122);
  2504. CheckCondition(122 ==
  2505. rocksdb_options_get_max_sequential_skip_in_iterations(copy));
  2506. CheckCondition(22 ==
  2507. rocksdb_options_get_max_sequential_skip_in_iterations(o));
  2508. rocksdb_options_set_disable_auto_compactions(copy, 0);
  2509. CheckCondition(0 == rocksdb_options_get_disable_auto_compactions(copy));
  2510. CheckCondition(1 == rocksdb_options_get_disable_auto_compactions(o));
  2511. rocksdb_options_set_optimize_filters_for_hits(copy, 0);
  2512. CheckCondition(0 == rocksdb_options_get_optimize_filters_for_hits(copy));
  2513. CheckCondition(1 == rocksdb_options_get_optimize_filters_for_hits(o));
  2514. rocksdb_options_set_delete_obsolete_files_period_micros(copy, 123);
  2515. CheckCondition(
  2516. 123 == rocksdb_options_get_delete_obsolete_files_period_micros(copy));
  2517. CheckCondition(23 ==
  2518. rocksdb_options_get_delete_obsolete_files_period_micros(o));
  2519. rocksdb_options_set_memtable_prefix_bloom_size_ratio(copy, 4.0);
  2520. CheckCondition(4.0 ==
  2521. rocksdb_options_get_memtable_prefix_bloom_size_ratio(copy));
  2522. CheckCondition(2.0 ==
  2523. rocksdb_options_get_memtable_prefix_bloom_size_ratio(o));
  2524. rocksdb_options_set_max_compaction_bytes(copy, 124);
  2525. CheckCondition(124 == rocksdb_options_get_max_compaction_bytes(copy));
  2526. CheckCondition(24 == rocksdb_options_get_max_compaction_bytes(o));
  2527. rocksdb_options_set_memtable_huge_page_size(copy, 125);
  2528. CheckCondition(125 == rocksdb_options_get_memtable_huge_page_size(copy));
  2529. CheckCondition(25 == rocksdb_options_get_memtable_huge_page_size(o));
  2530. rocksdb_options_set_max_successive_merges(copy, 126);
  2531. CheckCondition(126 == rocksdb_options_get_max_successive_merges(copy));
  2532. CheckCondition(26 == rocksdb_options_get_max_successive_merges(o));
  2533. rocksdb_options_set_bloom_locality(copy, 127);
  2534. CheckCondition(127 == rocksdb_options_get_bloom_locality(copy));
  2535. CheckCondition(27 == rocksdb_options_get_bloom_locality(o));
  2536. rocksdb_options_set_inplace_update_support(copy, 0);
  2537. CheckCondition(0 == rocksdb_options_get_inplace_update_support(copy));
  2538. CheckCondition(1 == rocksdb_options_get_inplace_update_support(o));
  2539. rocksdb_options_set_inplace_update_num_locks(copy, 128);
  2540. CheckCondition(128 == rocksdb_options_get_inplace_update_num_locks(copy));
  2541. CheckCondition(28 == rocksdb_options_get_inplace_update_num_locks(o));
  2542. rocksdb_options_set_report_bg_io_stats(copy, 0);
  2543. CheckCondition(0 == rocksdb_options_get_report_bg_io_stats(copy));
  2544. CheckCondition(1 == rocksdb_options_get_report_bg_io_stats(o));
  2545. rocksdb_options_set_wal_recovery_mode(copy, 1);
  2546. CheckCondition(1 == rocksdb_options_get_wal_recovery_mode(copy));
  2547. CheckCondition(2 == rocksdb_options_get_wal_recovery_mode(o));
  2548. rocksdb_options_set_compression(copy, 4);
  2549. CheckCondition(4 == rocksdb_options_get_compression(copy));
  2550. CheckCondition(5 == rocksdb_options_get_compression(o));
  2551. rocksdb_options_set_bottommost_compression(copy, 3);
  2552. CheckCondition(3 == rocksdb_options_get_bottommost_compression(copy));
  2553. CheckCondition(4 == rocksdb_options_get_bottommost_compression(o));
  2554. rocksdb_options_set_compaction_style(copy, 1);
  2555. CheckCondition(1 == rocksdb_options_get_compaction_style(copy));
  2556. CheckCondition(2 == rocksdb_options_get_compaction_style(o));
  2557. rocksdb_options_set_compaction_pri(copy, 1);
  2558. CheckCondition(1 == rocksdb_options_get_compaction_pri(copy));
  2559. CheckCondition(4 == rocksdb_options_get_compaction_pri(o));
  2560. rocksdb_options_set_atomic_flush(copy, 0);
  2561. CheckCondition(0 == rocksdb_options_get_atomic_flush(copy));
  2562. CheckCondition(1 == rocksdb_options_get_atomic_flush(o));
  2563. rocksdb_options_set_experimental_mempurge_threshold(copy, 229.0);
  2564. CheckCondition(229.0 ==
  2565. rocksdb_options_get_experimental_mempurge_threshold(copy));
  2566. CheckCondition(29.0 ==
  2567. rocksdb_options_get_experimental_mempurge_threshold(o));
  2568. rocksdb_options_destroy(copy);
  2569. rocksdb_options_destroy(o);
  2570. }
  2571. StartPhase("read_options");
  2572. {
  2573. rocksdb_readoptions_t* ro;
  2574. ro = rocksdb_readoptions_create();
  2575. rocksdb_readoptions_set_verify_checksums(ro, 1);
  2576. CheckCondition(1 == rocksdb_readoptions_get_verify_checksums(ro));
  2577. rocksdb_readoptions_set_fill_cache(ro, 1);
  2578. CheckCondition(1 == rocksdb_readoptions_get_fill_cache(ro));
  2579. rocksdb_readoptions_set_read_tier(ro, 2);
  2580. CheckCondition(2 == rocksdb_readoptions_get_read_tier(ro));
  2581. rocksdb_readoptions_set_tailing(ro, 1);
  2582. CheckCondition(1 == rocksdb_readoptions_get_tailing(ro));
  2583. rocksdb_readoptions_set_readahead_size(ro, 100);
  2584. CheckCondition(100 == rocksdb_readoptions_get_readahead_size(ro));
  2585. rocksdb_readoptions_set_prefix_same_as_start(ro, 1);
  2586. CheckCondition(1 == rocksdb_readoptions_get_prefix_same_as_start(ro));
  2587. rocksdb_readoptions_set_pin_data(ro, 1);
  2588. CheckCondition(1 == rocksdb_readoptions_get_pin_data(ro));
  2589. rocksdb_readoptions_set_total_order_seek(ro, 1);
  2590. CheckCondition(1 == rocksdb_readoptions_get_total_order_seek(ro));
  2591. rocksdb_readoptions_set_max_skippable_internal_keys(ro, 200);
  2592. CheckCondition(200 ==
  2593. rocksdb_readoptions_get_max_skippable_internal_keys(ro));
  2594. rocksdb_readoptions_set_background_purge_on_iterator_cleanup(ro, 1);
  2595. CheckCondition(
  2596. 1 == rocksdb_readoptions_get_background_purge_on_iterator_cleanup(ro));
  2597. rocksdb_readoptions_set_ignore_range_deletions(ro, 1);
  2598. CheckCondition(1 == rocksdb_readoptions_get_ignore_range_deletions(ro));
  2599. rocksdb_readoptions_set_deadline(ro, 300);
  2600. CheckCondition(300 == rocksdb_readoptions_get_deadline(ro));
  2601. rocksdb_readoptions_set_io_timeout(ro, 400);
  2602. CheckCondition(400 == rocksdb_readoptions_get_io_timeout(ro));
  2603. rocksdb_readoptions_set_async_io(ro, 1);
  2604. CheckCondition(1 == rocksdb_readoptions_get_async_io(ro));
  2605. rocksdb_readoptions_destroy(ro);
  2606. }
  2607. StartPhase("write_options");
  2608. {
  2609. rocksdb_writeoptions_t* wo;
  2610. wo = rocksdb_writeoptions_create();
  2611. rocksdb_writeoptions_set_sync(wo, 1);
  2612. CheckCondition(1 == rocksdb_writeoptions_get_sync(wo));
  2613. rocksdb_writeoptions_disable_WAL(wo, 1);
  2614. CheckCondition(1 == rocksdb_writeoptions_get_disable_WAL(wo));
  2615. rocksdb_writeoptions_set_ignore_missing_column_families(wo, 1);
  2616. CheckCondition(1 ==
  2617. rocksdb_writeoptions_get_ignore_missing_column_families(wo));
  2618. rocksdb_writeoptions_set_no_slowdown(wo, 1);
  2619. CheckCondition(1 == rocksdb_writeoptions_get_no_slowdown(wo));
  2620. rocksdb_writeoptions_set_low_pri(wo, 1);
  2621. CheckCondition(1 == rocksdb_writeoptions_get_low_pri(wo));
  2622. rocksdb_writeoptions_set_memtable_insert_hint_per_batch(wo, 1);
  2623. CheckCondition(1 ==
  2624. rocksdb_writeoptions_get_memtable_insert_hint_per_batch(wo));
  2625. rocksdb_writeoptions_destroy(wo);
  2626. }
  2627. StartPhase("compact_options");
  2628. {
  2629. rocksdb_compactoptions_t* co;
  2630. co = rocksdb_compactoptions_create();
  2631. rocksdb_compactoptions_set_exclusive_manual_compaction(co, 1);
  2632. CheckCondition(1 ==
  2633. rocksdb_compactoptions_get_exclusive_manual_compaction(co));
  2634. rocksdb_compactoptions_set_bottommost_level_compaction(co, 1);
  2635. CheckCondition(1 ==
  2636. rocksdb_compactoptions_get_bottommost_level_compaction(co));
  2637. rocksdb_compactoptions_set_change_level(co, 1);
  2638. CheckCondition(1 == rocksdb_compactoptions_get_change_level(co));
  2639. rocksdb_compactoptions_set_target_level(co, 1);
  2640. CheckCondition(1 == rocksdb_compactoptions_get_target_level(co));
  2641. rocksdb_compactoptions_set_target_path_id(co, 1);
  2642. CheckCondition(1 == rocksdb_compactoptions_get_target_path_id(co));
  2643. rocksdb_compactoptions_set_allow_write_stall(co, 1);
  2644. CheckCondition(1 == rocksdb_compactoptions_get_allow_write_stall(co));
  2645. rocksdb_compactoptions_set_max_subcompactions(co, 1);
  2646. CheckCondition(1 == rocksdb_compactoptions_get_max_subcompactions(co));
  2647. rocksdb_compactoptions_destroy(co);
  2648. }
  2649. StartPhase("flush_options");
  2650. {
  2651. rocksdb_flushoptions_t* fo;
  2652. fo = rocksdb_flushoptions_create();
  2653. rocksdb_flushoptions_set_wait(fo, 1);
  2654. CheckCondition(1 == rocksdb_flushoptions_get_wait(fo));
  2655. rocksdb_flushoptions_destroy(fo);
  2656. }
  2657. StartPhase("cache_options");
  2658. {
  2659. rocksdb_cache_t* co;
  2660. co = rocksdb_cache_create_lru(100);
  2661. CheckCondition(100 == rocksdb_cache_get_capacity(co));
  2662. rocksdb_cache_set_capacity(co, 200);
  2663. CheckCondition(200 == rocksdb_cache_get_capacity(co));
  2664. rocksdb_cache_destroy(co);
  2665. }
  2666. StartPhase("jemalloc_nodump_allocator");
  2667. {
  2668. rocksdb_memory_allocator_t* allocator;
  2669. allocator = rocksdb_jemalloc_nodump_allocator_create(&err);
  2670. if (err != NULL) {
  2671. // not supported on all platforms, allow unsupported error
  2672. const char* ni = "Not implemented: ";
  2673. size_t ni_len = strlen(ni);
  2674. size_t err_len = strlen(err);
  2675. CheckCondition(err_len >= ni_len);
  2676. CheckCondition(memcmp(ni, err, ni_len) == 0);
  2677. Free(&err);
  2678. } else {
  2679. rocksdb_cache_t* co;
  2680. rocksdb_lru_cache_options_t* copts;
  2681. copts = rocksdb_lru_cache_options_create();
  2682. rocksdb_lru_cache_options_set_capacity(copts, 100);
  2683. rocksdb_lru_cache_options_set_memory_allocator(copts, allocator);
  2684. co = rocksdb_cache_create_lru_opts(copts);
  2685. CheckCondition(100 == rocksdb_cache_get_capacity(co));
  2686. rocksdb_cache_destroy(co);
  2687. rocksdb_lru_cache_options_destroy(copts);
  2688. }
  2689. rocksdb_memory_allocator_destroy(allocator);
  2690. }
  2691. StartPhase("stderr_logger");
  2692. {
  2693. rocksdb_options_t* o_no_prefix = rocksdb_options_create();
  2694. rocksdb_logger_t* no_prefix_logger =
  2695. rocksdb_logger_create_stderr_logger(3, NULL);
  2696. rocksdb_options_set_info_log(o_no_prefix, no_prefix_logger);
  2697. rocksdb_logger_t* no_prefix_info_log =
  2698. rocksdb_options_get_info_log(o_no_prefix);
  2699. CheckCondition(no_prefix_info_log != NULL);
  2700. rocksdb_logger_destroy(no_prefix_logger);
  2701. rocksdb_logger_destroy(no_prefix_info_log);
  2702. rocksdb_options_destroy(o_no_prefix);
  2703. rocksdb_options_t* o_prefix = rocksdb_options_create();
  2704. rocksdb_logger_t* prefix_logger =
  2705. rocksdb_logger_create_stderr_logger(3, "some prefix");
  2706. rocksdb_options_set_info_log(o_prefix, prefix_logger);
  2707. rocksdb_logger_t* prefix_info_log = rocksdb_options_get_info_log(o_prefix);
  2708. CheckCondition(prefix_info_log != NULL);
  2709. rocksdb_logger_destroy(prefix_logger);
  2710. rocksdb_logger_destroy(prefix_info_log);
  2711. rocksdb_options_destroy(o_prefix);
  2712. }
  2713. StartPhase("env");
  2714. {
  2715. rocksdb_env_t* e;
  2716. e = rocksdb_create_default_env();
  2717. rocksdb_env_set_background_threads(e, 10);
  2718. CheckCondition(10 == rocksdb_env_get_background_threads(e));
  2719. rocksdb_env_set_high_priority_background_threads(e, 20);
  2720. CheckCondition(20 == rocksdb_env_get_high_priority_background_threads(e));
  2721. rocksdb_env_set_low_priority_background_threads(e, 30);
  2722. CheckCondition(30 == rocksdb_env_get_low_priority_background_threads(e));
  2723. rocksdb_env_set_bottom_priority_background_threads(e, 40);
  2724. CheckCondition(40 == rocksdb_env_get_bottom_priority_background_threads(e));
  2725. rocksdb_env_destroy(e);
  2726. }
  2727. StartPhase("universal_compaction_options");
  2728. {
  2729. rocksdb_universal_compaction_options_t* uco;
  2730. uco = rocksdb_universal_compaction_options_create();
  2731. rocksdb_universal_compaction_options_set_size_ratio(uco, 5);
  2732. CheckCondition(5 ==
  2733. rocksdb_universal_compaction_options_get_size_ratio(uco));
  2734. rocksdb_universal_compaction_options_set_min_merge_width(uco, 15);
  2735. CheckCondition(
  2736. 15 == rocksdb_universal_compaction_options_get_min_merge_width(uco));
  2737. rocksdb_universal_compaction_options_set_max_merge_width(uco, 25);
  2738. CheckCondition(
  2739. 25 == rocksdb_universal_compaction_options_get_max_merge_width(uco));
  2740. rocksdb_universal_compaction_options_set_max_size_amplification_percent(uco,
  2741. 35);
  2742. CheckCondition(
  2743. 35 ==
  2744. rocksdb_universal_compaction_options_get_max_size_amplification_percent(
  2745. uco));
  2746. rocksdb_universal_compaction_options_set_compression_size_percent(uco, 45);
  2747. CheckCondition(
  2748. 45 ==
  2749. rocksdb_universal_compaction_options_get_compression_size_percent(uco));
  2750. rocksdb_universal_compaction_options_set_stop_style(uco, 1);
  2751. CheckCondition(1 ==
  2752. rocksdb_universal_compaction_options_get_stop_style(uco));
  2753. rocksdb_universal_compaction_options_destroy(uco);
  2754. }
  2755. StartPhase("fifo_compaction_options");
  2756. {
  2757. rocksdb_fifo_compaction_options_t* fco;
  2758. fco = rocksdb_fifo_compaction_options_create();
  2759. rocksdb_fifo_compaction_options_set_max_table_files_size(fco, 100000);
  2760. CheckCondition(
  2761. 100000 ==
  2762. rocksdb_fifo_compaction_options_get_max_table_files_size(fco));
  2763. rocksdb_fifo_compaction_options_destroy(fco);
  2764. }
  2765. StartPhase("backup_engine_option");
  2766. {
  2767. rocksdb_backup_engine_options_t* bdo;
  2768. bdo = rocksdb_backup_engine_options_create("path");
  2769. rocksdb_backup_engine_options_set_share_table_files(bdo, 1);
  2770. CheckCondition(1 ==
  2771. rocksdb_backup_engine_options_get_share_table_files(bdo));
  2772. rocksdb_backup_engine_options_set_sync(bdo, 1);
  2773. CheckCondition(1 == rocksdb_backup_engine_options_get_sync(bdo));
  2774. rocksdb_backup_engine_options_set_destroy_old_data(bdo, 1);
  2775. CheckCondition(1 ==
  2776. rocksdb_backup_engine_options_get_destroy_old_data(bdo));
  2777. rocksdb_backup_engine_options_set_backup_log_files(bdo, 1);
  2778. CheckCondition(1 ==
  2779. rocksdb_backup_engine_options_get_backup_log_files(bdo));
  2780. rocksdb_backup_engine_options_set_backup_rate_limit(bdo, 123);
  2781. CheckCondition(123 ==
  2782. rocksdb_backup_engine_options_get_backup_rate_limit(bdo));
  2783. rocksdb_backup_engine_options_set_restore_rate_limit(bdo, 37);
  2784. CheckCondition(37 ==
  2785. rocksdb_backup_engine_options_get_restore_rate_limit(bdo));
  2786. rocksdb_backup_engine_options_set_max_background_operations(bdo, 20);
  2787. CheckCondition(
  2788. 20 == rocksdb_backup_engine_options_get_max_background_operations(bdo));
  2789. rocksdb_backup_engine_options_set_callback_trigger_interval_size(bdo, 9000);
  2790. CheckCondition(
  2791. 9000 ==
  2792. rocksdb_backup_engine_options_get_callback_trigger_interval_size(bdo));
  2793. rocksdb_backup_engine_options_set_max_valid_backups_to_open(bdo, 40);
  2794. CheckCondition(
  2795. 40 == rocksdb_backup_engine_options_get_max_valid_backups_to_open(bdo));
  2796. rocksdb_backup_engine_options_set_share_files_with_checksum_naming(bdo, 2);
  2797. CheckCondition(
  2798. 2 == rocksdb_backup_engine_options_get_share_files_with_checksum_naming(
  2799. bdo));
  2800. rocksdb_backup_engine_options_destroy(bdo);
  2801. }
  2802. StartPhase("compression_options");
  2803. {
  2804. rocksdb_options_t* co;
  2805. co = rocksdb_options_create();
  2806. rocksdb_options_set_compression_options_zstd_max_train_bytes(co, 100);
  2807. CheckCondition(
  2808. 100 ==
  2809. rocksdb_options_get_compression_options_zstd_max_train_bytes(co));
  2810. rocksdb_options_set_compression_options_parallel_threads(co, 2);
  2811. CheckCondition(
  2812. 2 == rocksdb_options_get_compression_options_parallel_threads(co));
  2813. rocksdb_options_set_compression_options_max_dict_buffer_bytes(co, 200);
  2814. CheckCondition(
  2815. 200 ==
  2816. rocksdb_options_get_compression_options_max_dict_buffer_bytes(co));
  2817. rocksdb_options_set_compression_options_use_zstd_dict_trainer(co, 0);
  2818. CheckCondition(
  2819. 0 == rocksdb_options_get_compression_options_use_zstd_dict_trainer(co));
  2820. rocksdb_options_destroy(co);
  2821. }
  2822. StartPhase("iterate_upper_bound");
  2823. {
  2824. // Create new empty database
  2825. rocksdb_close(db);
  2826. rocksdb_destroy_db(options, dbname, &err);
  2827. CheckNoError(err);
  2828. rocksdb_options_set_prefix_extractor(options, NULL);
  2829. db = rocksdb_open(options, dbname, &err);
  2830. CheckNoError(err);
  2831. rocksdb_put(db, woptions, "a", 1, "0", 1, &err);
  2832. CheckNoError(err);
  2833. rocksdb_put(db, woptions, "foo", 3, "bar", 3, &err);
  2834. CheckNoError(err);
  2835. rocksdb_put(db, woptions, "foo1", 4, "bar1", 4, &err);
  2836. CheckNoError(err);
  2837. rocksdb_put(db, woptions, "g1", 2, "0", 1, &err);
  2838. CheckNoError(err);
  2839. // testing basic case with no iterate_upper_bound and no prefix_extractor
  2840. {
  2841. rocksdb_readoptions_set_iterate_upper_bound(roptions, NULL, 0);
  2842. rocksdb_iterator_t* iter = rocksdb_create_iterator(db, roptions);
  2843. rocksdb_iter_seek(iter, "foo", 3);
  2844. CheckCondition(rocksdb_iter_valid(iter));
  2845. CheckIter(iter, "foo", "bar");
  2846. rocksdb_iter_next(iter);
  2847. CheckCondition(rocksdb_iter_valid(iter));
  2848. CheckIter(iter, "foo1", "bar1");
  2849. rocksdb_iter_next(iter);
  2850. CheckCondition(rocksdb_iter_valid(iter));
  2851. CheckIter(iter, "g1", "0");
  2852. rocksdb_iter_destroy(iter);
  2853. }
  2854. // testing iterate_upper_bound and forward iterator
  2855. // to make sure it stops at bound
  2856. {
  2857. // iterate_upper_bound points beyond the last expected entry
  2858. rocksdb_readoptions_set_iterate_upper_bound(roptions, "foo2", 4);
  2859. rocksdb_iterator_t* iter = rocksdb_create_iterator(db, roptions);
  2860. rocksdb_iter_seek(iter, "foo", 3);
  2861. CheckCondition(rocksdb_iter_valid(iter));
  2862. CheckIter(iter, "foo", "bar");
  2863. rocksdb_iter_next(iter);
  2864. CheckCondition(rocksdb_iter_valid(iter));
  2865. CheckIter(iter, "foo1", "bar1");
  2866. rocksdb_iter_next(iter);
  2867. // should stop here...
  2868. CheckCondition(!rocksdb_iter_valid(iter));
  2869. rocksdb_iter_destroy(iter);
  2870. rocksdb_readoptions_set_iterate_upper_bound(roptions, NULL, 0);
  2871. }
  2872. }
  2873. StartPhase("transactions");
  2874. {
  2875. rocksdb_close(db);
  2876. rocksdb_destroy_db(options, dbname, &err);
  2877. CheckNoError(err);
  2878. // open a TransactionDB
  2879. txn_db_options = rocksdb_transactiondb_options_create();
  2880. txn_options = rocksdb_transaction_options_create();
  2881. rocksdb_options_set_create_if_missing(options, 1);
  2882. txn_db = rocksdb_transactiondb_open(options, txn_db_options, dbname, &err);
  2883. CheckNoError(err);
  2884. // put outside a transaction
  2885. rocksdb_transactiondb_put(txn_db, woptions, "foo", 3, "hello", 5, &err);
  2886. CheckNoError(err);
  2887. CheckTxnDBGet(txn_db, roptions, "foo", "hello");
  2888. CheckTxnDBPinGet(txn_db, roptions, "foo", "hello");
  2889. // delete from outside transaction
  2890. rocksdb_transactiondb_delete(txn_db, woptions, "foo", 3, &err);
  2891. CheckNoError(err);
  2892. CheckTxnDBGet(txn_db, roptions, "foo", NULL);
  2893. CheckTxnDBPinGet(txn_db, roptions, "foo", NULL);
  2894. // write batch into TransactionDB
  2895. rocksdb_writebatch_t* wb = rocksdb_writebatch_create();
  2896. rocksdb_writebatch_put(wb, "foo", 3, "a", 1);
  2897. rocksdb_writebatch_clear(wb);
  2898. rocksdb_writebatch_put(wb, "bar", 3, "b", 1);
  2899. rocksdb_writebatch_put(wb, "box", 3, "c", 1);
  2900. rocksdb_writebatch_delete(wb, "bar", 3);
  2901. rocksdb_transactiondb_write(txn_db, woptions, wb, &err);
  2902. rocksdb_writebatch_destroy(wb);
  2903. CheckTxnDBGet(txn_db, roptions, "box", "c");
  2904. CheckTxnDBPinGet(txn_db, roptions, "box", "c");
  2905. CheckNoError(err);
  2906. // multi get
  2907. {
  2908. const char* keys[3] = {"box", "foo", "notfound"};
  2909. const size_t keys_sizes[3] = {3, 3, 8};
  2910. char* vals[3];
  2911. size_t vals_sizes[3];
  2912. char* errs[3];
  2913. const char* expected[3] = {"c", NULL, NULL};
  2914. rocksdb_transactiondb_multi_get(txn_db, roptions, 3, keys, keys_sizes,
  2915. vals, vals_sizes, errs);
  2916. CheckMultiGetValues(3, vals, vals_sizes, errs, expected);
  2917. }
  2918. // begin a transaction
  2919. txn = rocksdb_transaction_begin(txn_db, woptions, txn_options, NULL);
  2920. // put
  2921. rocksdb_transaction_put(txn, "foo", 3, "hello", 5, &err);
  2922. CheckNoError(err);
  2923. CheckTxnGet(txn, roptions, "foo", "hello");
  2924. CheckTxnPinGet(txn, roptions, "foo", "hello");
  2925. {
  2926. const char* keys[3] = {"box", "foo", "notfound"};
  2927. const size_t keys_sizes[3] = {3, 3, 8};
  2928. char* vals[3];
  2929. size_t vals_sizes[3];
  2930. char* errs[3];
  2931. const char* expected[3] = {"c", "hello", NULL};
  2932. rocksdb_transaction_multi_get(txn, roptions, 3, keys, keys_sizes, vals,
  2933. vals_sizes, errs);
  2934. CheckMultiGetValues(3, vals, vals_sizes, errs, expected);
  2935. }
  2936. // delete
  2937. rocksdb_transaction_delete(txn, "foo", 3, &err);
  2938. CheckNoError(err);
  2939. CheckTxnGet(txn, roptions, "foo", NULL);
  2940. CheckTxnPinGet(txn, roptions, "foo", NULL);
  2941. rocksdb_transaction_put(txn, "foo", 3, "hello", 5, &err);
  2942. CheckNoError(err);
  2943. // read from outside transaction, before commit
  2944. CheckTxnDBGet(txn_db, roptions, "foo", NULL);
  2945. CheckTxnDBPinGet(txn_db, roptions, "foo", NULL);
  2946. {
  2947. const char* keys[3] = {"box", "foo", "notfound"};
  2948. const size_t keys_sizes[3] = {3, 3, 8};
  2949. char* vals[3];
  2950. size_t vals_sizes[3];
  2951. char* errs[3];
  2952. const char* expected[3] = {"c", NULL, NULL};
  2953. rocksdb_transactiondb_multi_get(txn_db, roptions, 3, keys, keys_sizes,
  2954. vals, vals_sizes, errs);
  2955. CheckMultiGetValues(3, vals, vals_sizes, errs, expected);
  2956. }
  2957. // commit
  2958. rocksdb_transaction_commit(txn, &err);
  2959. CheckNoError(err);
  2960. // read from outside transaction, after commit
  2961. CheckTxnDBGet(txn_db, roptions, "foo", "hello");
  2962. CheckTxnDBPinGet(txn_db, roptions, "foo", "hello");
  2963. {
  2964. const char* keys[3] = {"box", "foo", "notfound"};
  2965. const size_t keys_sizes[3] = {3, 3, 8};
  2966. char* vals[3];
  2967. size_t vals_sizes[3];
  2968. char* errs[3];
  2969. const char* expected[3] = {"c", "hello", NULL};
  2970. rocksdb_transactiondb_multi_get(txn_db, roptions, 3, keys, keys_sizes,
  2971. vals, vals_sizes, errs);
  2972. CheckMultiGetValues(3, vals, vals_sizes, errs, expected);
  2973. }
  2974. // reuse old transaction
  2975. txn = rocksdb_transaction_begin(txn_db, woptions, txn_options, txn);
  2976. // snapshot
  2977. const rocksdb_snapshot_t* snapshot;
  2978. snapshot = rocksdb_transactiondb_create_snapshot(txn_db);
  2979. rocksdb_readoptions_set_snapshot(roptions, snapshot);
  2980. rocksdb_transactiondb_put(txn_db, woptions, "foo", 3, "hey", 3, &err);
  2981. CheckNoError(err);
  2982. CheckTxnDBGet(txn_db, roptions, "foo", "hello");
  2983. CheckTxnDBPinGet(txn_db, roptions, "foo", "hello");
  2984. rocksdb_readoptions_set_snapshot(roptions, NULL);
  2985. rocksdb_transactiondb_release_snapshot(txn_db, snapshot);
  2986. CheckTxnDBGet(txn_db, roptions, "foo", "hey");
  2987. CheckTxnDBPinGet(txn_db, roptions, "foo", "hey");
  2988. // iterate
  2989. rocksdb_transaction_put(txn, "bar", 3, "hi", 2, &err);
  2990. rocksdb_iterator_t* iter =
  2991. rocksdb_transaction_create_iterator(txn, roptions);
  2992. CheckCondition(!rocksdb_iter_valid(iter));
  2993. rocksdb_iter_seek_to_first(iter);
  2994. CheckCondition(rocksdb_iter_valid(iter));
  2995. CheckIter(iter, "bar", "hi");
  2996. rocksdb_iter_get_error(iter, &err);
  2997. CheckNoError(err);
  2998. rocksdb_iter_destroy(iter);
  2999. // rollback
  3000. rocksdb_transaction_rollback(txn, &err);
  3001. CheckNoError(err);
  3002. CheckTxnDBGet(txn_db, roptions, "bar", NULL);
  3003. CheckTxnDBPinGet(txn_db, roptions, "bar", NULL);
  3004. // save point
  3005. rocksdb_transaction_put(txn, "foo1", 4, "hi1", 3, &err);
  3006. rocksdb_transaction_set_savepoint(txn);
  3007. CheckTxnGet(txn, roptions, "foo1", "hi1");
  3008. CheckTxnPinGet(txn, roptions, "foo1", "hi1");
  3009. rocksdb_transaction_put(txn, "foo2", 4, "hi2", 3, &err);
  3010. CheckTxnGet(txn, roptions, "foo2", "hi2");
  3011. CheckTxnPinGet(txn, roptions, "foo2", "hi2");
  3012. // rollback to savepoint
  3013. rocksdb_transaction_rollback_to_savepoint(txn, &err);
  3014. CheckNoError(err);
  3015. CheckTxnGet(txn, roptions, "foo2", NULL);
  3016. CheckTxnGet(txn, roptions, "foo1", "hi1");
  3017. CheckTxnPinGet(txn, roptions, "foo2", NULL);
  3018. CheckTxnPinGet(txn, roptions, "foo1", "hi1");
  3019. CheckTxnDBGet(txn_db, roptions, "foo1", NULL);
  3020. CheckTxnDBGet(txn_db, roptions, "foo2", NULL);
  3021. CheckTxnDBPinGet(txn_db, roptions, "foo1", NULL);
  3022. CheckTxnDBPinGet(txn_db, roptions, "foo2", NULL);
  3023. rocksdb_transaction_commit(txn, &err);
  3024. CheckNoError(err);
  3025. CheckTxnDBGet(txn_db, roptions, "foo1", "hi1");
  3026. CheckTxnDBGet(txn_db, roptions, "foo2", NULL);
  3027. CheckTxnDBPinGet(txn_db, roptions, "foo1", "hi1");
  3028. CheckTxnDBPinGet(txn_db, roptions, "foo2", NULL);
  3029. // Column families.
  3030. rocksdb_column_family_handle_t* cfh;
  3031. cfh = rocksdb_transactiondb_create_column_family(txn_db, options,
  3032. "txn_db_cf", &err);
  3033. CheckNoError(err);
  3034. rocksdb_transactiondb_put_cf(txn_db, woptions, cfh, "cf_foo", 6, "cf_hello",
  3035. 8, &err);
  3036. CheckNoError(err);
  3037. CheckTxnDBGetCF(txn_db, roptions, cfh, "cf_foo", "cf_hello");
  3038. CheckTxnDBPinGetCF(txn_db, roptions, cfh, "cf_foo", "cf_hello");
  3039. {
  3040. const rocksdb_column_family_handle_t* get_handles[2] = {cfh, cfh};
  3041. const char* keys[2] = {"cf_foo", "notfound"};
  3042. const size_t keys_sizes[2] = {6, 8};
  3043. char* vals[2];
  3044. size_t vals_sizes[2];
  3045. char* errs[2];
  3046. const char* expected[2] = {"cf_hello", NULL};
  3047. rocksdb_transactiondb_multi_get_cf(txn_db, roptions, get_handles, 2, keys,
  3048. keys_sizes, vals, vals_sizes, errs);
  3049. CheckMultiGetValues(2, vals, vals_sizes, errs, expected);
  3050. }
  3051. rocksdb_transactiondb_delete_cf(txn_db, woptions, cfh, "cf_foo", 6, &err);
  3052. CheckNoError(err);
  3053. CheckTxnDBGetCF(txn_db, roptions, cfh, "cf_foo", NULL);
  3054. CheckTxnDBPinGetCF(txn_db, roptions, cfh, "cf_foo", NULL);
  3055. // memory usage
  3056. rocksdb_t* base_db = rocksdb_transactiondb_get_base_db(txn_db);
  3057. rocksdb_memory_consumers_t* consumers = rocksdb_memory_consumers_create();
  3058. rocksdb_memory_consumers_add_db(consumers, base_db);
  3059. rocksdb_memory_usage_t* usage =
  3060. rocksdb_approximate_memory_usage_create(consumers, &err);
  3061. CheckNoError(err);
  3062. rocksdb_approximate_memory_usage_destroy(usage);
  3063. rocksdb_memory_consumers_destroy(consumers);
  3064. rocksdb_transactiondb_close_base_db(base_db);
  3065. // flush
  3066. rocksdb_flushoptions_t* flush_options = rocksdb_flushoptions_create();
  3067. rocksdb_flushoptions_set_wait(flush_options, 1);
  3068. rocksdb_transactiondb_flush_wal(txn_db, 1, &err);
  3069. CheckNoError(err);
  3070. rocksdb_transactiondb_flush_cf(txn_db, flush_options, cfh, &err);
  3071. CheckNoError(err);
  3072. rocksdb_transactiondb_flush(txn_db, flush_options, &err);
  3073. CheckNoError(err);
  3074. rocksdb_flushoptions_destroy(flush_options);
  3075. // close and destroy
  3076. rocksdb_column_family_handle_destroy(cfh);
  3077. rocksdb_transaction_destroy(txn);
  3078. rocksdb_transactiondb_close(txn_db);
  3079. rocksdb_destroy_db(options, dbname, &err);
  3080. CheckNoError(err);
  3081. rocksdb_transaction_options_destroy(txn_options);
  3082. rocksdb_transactiondb_options_destroy(txn_db_options);
  3083. }
  3084. StartPhase("two-phase commit");
  3085. {
  3086. // open a TransactionDB
  3087. txn_db_options = rocksdb_transactiondb_options_create();
  3088. txn_options = rocksdb_transaction_options_create();
  3089. rocksdb_options_set_create_if_missing(options, 1);
  3090. txn_db = rocksdb_transactiondb_open(options, txn_db_options, dbname, &err);
  3091. CheckNoError(err);
  3092. rocksdb_transaction_options_set_skip_prepare(txn_options, 0);
  3093. txn = rocksdb_transaction_begin(txn_db, woptions, txn_options, NULL);
  3094. rocksdb_transaction_commit(txn, &err);
  3095. CheckCondition(err != NULL);
  3096. Free(&err);
  3097. err = NULL;
  3098. rocksdb_transaction_prepare(txn, &err);
  3099. CheckCondition(err != NULL);
  3100. Free(&err);
  3101. err = NULL;
  3102. rocksdb_transaction_set_name(txn, "txn1", 4, &err);
  3103. CheckNoError(err);
  3104. rocksdb_transaction_prepare(txn, &err);
  3105. CheckNoError(err);
  3106. rocksdb_transaction_commit(txn, &err);
  3107. CheckNoError(err);
  3108. rocksdb_transaction_destroy(txn);
  3109. // prepare 2 transactions and close db.
  3110. rocksdb_transaction_t* txn1 =
  3111. rocksdb_transaction_begin(txn_db, woptions, txn_options, NULL);
  3112. rocksdb_transaction_put(txn1, "bar1", 4, "1", 1, &err);
  3113. CheckNoError(err);
  3114. rocksdb_transaction_set_name(txn1, "txn1", 4, &err);
  3115. CheckNoError(err);
  3116. rocksdb_transaction_prepare(txn1, &err);
  3117. CheckNoError(err);
  3118. rocksdb_transaction_t* txn2 =
  3119. rocksdb_transaction_begin(txn_db, woptions, txn_options, NULL);
  3120. rocksdb_transaction_put(txn2, "bar2", 4, "2", 1, &err);
  3121. CheckNoError(err);
  3122. rocksdb_transaction_set_name(txn2, "txn2", 4, &err);
  3123. CheckNoError(err);
  3124. rocksdb_transaction_prepare(txn2, &err);
  3125. CheckNoError(err);
  3126. rocksdb_transaction_destroy(txn1);
  3127. rocksdb_transaction_destroy(txn2);
  3128. rocksdb_transactiondb_close(txn_db);
  3129. rocksdb_transaction_options_destroy(txn_options);
  3130. rocksdb_transactiondb_options_destroy(txn_db_options);
  3131. // reopen db and get all prepared.
  3132. txn_db_options = rocksdb_transactiondb_options_create();
  3133. txn_options = rocksdb_transaction_options_create();
  3134. rocksdb_options_set_error_if_exists(options, 0);
  3135. txn_db = rocksdb_transactiondb_open(options, txn_db_options, dbname, &err);
  3136. CheckNoError(err);
  3137. CheckTxnDBPinGet(txn_db, roptions, "bar1", NULL);
  3138. CheckTxnDBPinGet(txn_db, roptions, "bar2", NULL);
  3139. size_t cnt;
  3140. rocksdb_transaction_t** txns =
  3141. rocksdb_transactiondb_get_prepared_transactions(txn_db, &cnt);
  3142. CheckCondition(cnt == 2);
  3143. size_t i;
  3144. for (i = 0; i < cnt; i++) {
  3145. txn = txns[i];
  3146. size_t name_len = 0;
  3147. char* name = rocksdb_transaction_get_name(txn, &name_len);
  3148. CheckCondition(name_len == 4);
  3149. if (strncmp(name, "txn1", name_len) == 0) {
  3150. rocksdb_transaction_commit(txn, &err);
  3151. } else if (strncmp(name, "txn2", name_len) == 0) {
  3152. rocksdb_transaction_rollback(txn, &err);
  3153. }
  3154. rocksdb_free(name);
  3155. CheckNoError(err);
  3156. rocksdb_transaction_destroy(txn);
  3157. }
  3158. rocksdb_free(txns);
  3159. CheckTxnDBGet(txn_db, roptions, "bar1", "1");
  3160. CheckTxnDBGet(txn_db, roptions, "bar2", NULL);
  3161. rocksdb_transactiondb_put(txn_db, woptions, "bar2", 4, "2", 1, &err);
  3162. CheckNoError(err);
  3163. // close and destroy
  3164. rocksdb_transactiondb_close(txn_db);
  3165. rocksdb_destroy_db(options, dbname, &err);
  3166. CheckNoError(err);
  3167. rocksdb_transaction_options_destroy(txn_options);
  3168. rocksdb_transactiondb_options_destroy(txn_db_options);
  3169. }
  3170. StartPhase("transactions_multi_get_for_update");
  3171. {
  3172. // open a TransactionDB
  3173. txn_db_options = rocksdb_transactiondb_options_create();
  3174. rocksdb_transactiondb_options_set_transaction_lock_timeout(txn_db_options,
  3175. 0);
  3176. txn_options = rocksdb_transaction_options_create();
  3177. rocksdb_options_set_create_if_missing(options, 1);
  3178. txn_db = rocksdb_transactiondb_open(options, txn_db_options, dbname, &err);
  3179. CheckNoError(err);
  3180. rocksdb_transactiondb_put(txn_db, woptions, "foo", 3, "hey", 3, &err);
  3181. CheckNoError(err);
  3182. rocksdb_transactiondb_put(txn_db, woptions, "bar", 3, "hello", 5, &err);
  3183. CheckNoError(err);
  3184. // begin transactions
  3185. txn = rocksdb_transaction_begin(txn_db, woptions, txn_options, NULL);
  3186. rocksdb_transaction_t* txn2 =
  3187. rocksdb_transaction_begin(txn_db, woptions, txn_options, NULL);
  3188. // multi get
  3189. {
  3190. const char* keys[2] = {"foo", "bar"};
  3191. const size_t keys_sizes[2] = {3, 3};
  3192. char* vals[2];
  3193. size_t vals_sizes[2];
  3194. char* errs[2];
  3195. const char* expected[2] = {"hey", "hello"};
  3196. rocksdb_transaction_multi_get_for_update(
  3197. txn, roptions, 2, keys, keys_sizes, vals, vals_sizes, errs);
  3198. CheckMultiGetValues(2, vals, vals_sizes, errs, expected);
  3199. }
  3200. char* conflict_err = NULL;
  3201. size_t val_len;
  3202. rocksdb_transaction_get_for_update(txn2, roptions, "foo", 3, &val_len, true,
  3203. &conflict_err);
  3204. // get-for-update conflict
  3205. CheckCondition(conflict_err != NULL);
  3206. Free(&conflict_err);
  3207. // commit
  3208. rocksdb_transaction_commit(txn, &err);
  3209. CheckNoError(err);
  3210. // should work after first tx is commited
  3211. CheckTxnGetForUpdate(txn2, roptions, "foo", "hey");
  3212. // commit the second one
  3213. rocksdb_transaction_commit(txn2, &err);
  3214. CheckNoError(err);
  3215. // destroy txns
  3216. rocksdb_transaction_destroy(txn);
  3217. rocksdb_transaction_destroy(txn2);
  3218. // same for column families
  3219. rocksdb_column_family_handle_t* cfh;
  3220. cfh = rocksdb_transactiondb_create_column_family(txn_db, options,
  3221. "txn_db_cf", &err);
  3222. CheckNoError(err);
  3223. rocksdb_transactiondb_put_cf(txn_db, woptions, cfh, "cf_foo", 6, "cf_hello",
  3224. 8, &err);
  3225. CheckNoError(err);
  3226. rocksdb_transactiondb_put_cf(txn_db, woptions, cfh, "cf_bar", 6, "cf_hey",
  3227. 6, &err);
  3228. CheckNoError(err);
  3229. txn = rocksdb_transaction_begin(txn_db, woptions, txn_options, NULL);
  3230. txn2 = rocksdb_transaction_begin(txn_db, woptions, txn_options, NULL);
  3231. {
  3232. const rocksdb_column_family_handle_t* get_handles[2] = {cfh, cfh};
  3233. const char* keys[2] = {"cf_foo", "cf_bar"};
  3234. const size_t keys_sizes[2] = {6, 6};
  3235. char* vals[2];
  3236. size_t vals_sizes[2];
  3237. char* errs[2];
  3238. const char* expected[2] = {"cf_hello", "cf_hey"};
  3239. rocksdb_transaction_multi_get_for_update_cf(txn, roptions, get_handles, 2,
  3240. keys, keys_sizes, vals,
  3241. vals_sizes, errs);
  3242. CheckMultiGetValues(2, vals, vals_sizes, errs, expected);
  3243. }
  3244. char* conflict_err_cf = NULL;
  3245. size_t val_len_cf;
  3246. rocksdb_transaction_get_for_update_cf(txn2, roptions, cfh, "cf_foo", 6,
  3247. &val_len_cf, true, &conflict_err_cf);
  3248. CheckCondition(conflict_err_cf != NULL);
  3249. Free(&conflict_err_cf);
  3250. rocksdb_transaction_commit(txn, &err);
  3251. CheckNoError(err);
  3252. CheckTxnGetForUpdateCF(txn2, roptions, cfh, "cf_foo", "cf_hello");
  3253. rocksdb_transaction_commit(txn2, &err);
  3254. CheckNoError(err);
  3255. // close and destroy
  3256. rocksdb_column_family_handle_destroy(cfh);
  3257. rocksdb_transaction_destroy(txn);
  3258. rocksdb_transaction_destroy(txn2);
  3259. rocksdb_transactiondb_close(txn_db);
  3260. rocksdb_destroy_db(options, dbname, &err);
  3261. CheckNoError(err);
  3262. rocksdb_transaction_options_destroy(txn_options);
  3263. rocksdb_transactiondb_options_destroy(txn_db_options);
  3264. }
  3265. StartPhase("optimistic_transactions");
  3266. {
  3267. rocksdb_options_t* db_options = rocksdb_options_create();
  3268. rocksdb_options_set_create_if_missing(db_options, 1);
  3269. rocksdb_options_set_allow_concurrent_memtable_write(db_options, 1);
  3270. otxn_db = rocksdb_optimistictransactiondb_open(db_options, dbname, &err);
  3271. otxn_options = rocksdb_optimistictransaction_options_create();
  3272. rocksdb_transaction_t* txn1 = rocksdb_optimistictransaction_begin(
  3273. otxn_db, woptions, otxn_options, NULL);
  3274. rocksdb_transaction_t* txn2 = rocksdb_optimistictransaction_begin(
  3275. otxn_db, woptions, otxn_options, NULL);
  3276. rocksdb_transaction_put(txn1, "key", 3, "value", 5, &err);
  3277. CheckNoError(err);
  3278. rocksdb_transaction_put(txn2, "key1", 4, "value1", 6, &err);
  3279. CheckNoError(err);
  3280. CheckTxnGet(txn1, roptions, "key", "value");
  3281. CheckTxnPinGet(txn1, roptions, "key", "value");
  3282. rocksdb_transaction_commit(txn1, &err);
  3283. CheckNoError(err);
  3284. rocksdb_transaction_commit(txn2, &err);
  3285. CheckNoError(err);
  3286. rocksdb_transaction_destroy(txn1);
  3287. rocksdb_transaction_destroy(txn2);
  3288. // Check column family
  3289. db = rocksdb_optimistictransactiondb_get_base_db(otxn_db);
  3290. rocksdb_put(db, woptions, "key", 3, "value", 5, &err);
  3291. CheckNoError(err);
  3292. rocksdb_column_family_handle_t *cfh1, *cfh2;
  3293. char** list_const_cf_names = (char**)malloc(2 * sizeof(char*));
  3294. list_const_cf_names[0] = "txn_db_cf1";
  3295. list_const_cf_names[1] = "txn_db_cf2";
  3296. size_t cflen;
  3297. rocksdb_column_family_handle_t** list_cfh = rocksdb_create_column_families(
  3298. db, db_options, 2, (const char* const*)list_const_cf_names, &cflen,
  3299. &err);
  3300. free(list_const_cf_names);
  3301. CheckNoError(err);
  3302. assert(cflen == 2);
  3303. cfh1 = list_cfh[0];
  3304. cfh2 = list_cfh[1];
  3305. rocksdb_create_column_families_destroy(list_cfh);
  3306. txn = rocksdb_optimistictransaction_begin(otxn_db, woptions, otxn_options,
  3307. NULL);
  3308. rocksdb_transaction_put_cf(txn, cfh1, "key_cf1", 7, "val_cf1", 7, &err);
  3309. CheckNoError(err);
  3310. rocksdb_transaction_put_cf(txn, cfh2, "key_cf2", 7, "val_cf2", 7, &err);
  3311. CheckNoError(err);
  3312. rocksdb_transaction_commit(txn, &err);
  3313. CheckNoError(err);
  3314. txn = rocksdb_optimistictransaction_begin(otxn_db, woptions, otxn_options,
  3315. txn);
  3316. CheckGetCF(db, roptions, cfh1, "key_cf1", "val_cf1");
  3317. CheckTxnGetCF(txn, roptions, cfh1, "key_cf1", "val_cf1");
  3318. CheckTxnPinGetCF(txn, roptions, cfh1, "key_cf1", "val_cf1");
  3319. {
  3320. const rocksdb_column_family_handle_t* get_handles[3] = {cfh1, cfh2, cfh2};
  3321. const char* keys[3] = {"key_cf1", "key_cf2", "notfound"};
  3322. const size_t keys_sizes[3] = {7, 7, 8};
  3323. char* vals[3];
  3324. size_t vals_sizes[3];
  3325. char* errs[3];
  3326. const char* expected[3] = {"val_cf1", "val_cf2", NULL};
  3327. rocksdb_transaction_multi_get_cf(txn, roptions, get_handles, 3, keys,
  3328. keys_sizes, vals, vals_sizes, errs);
  3329. CheckMultiGetValues(3, vals, vals_sizes, errs, expected);
  3330. }
  3331. // Check iterator with column family
  3332. rocksdb_transaction_put_cf(txn, cfh1, "key1_cf", 7, "val1_cf", 7, &err);
  3333. CheckNoError(err);
  3334. rocksdb_iterator_t* iter =
  3335. rocksdb_transaction_create_iterator_cf(txn, roptions, cfh1);
  3336. CheckCondition(!rocksdb_iter_valid(iter));
  3337. rocksdb_iter_seek_to_first(iter);
  3338. CheckCondition(rocksdb_iter_valid(iter));
  3339. CheckIter(iter, "key1_cf", "val1_cf");
  3340. rocksdb_iter_get_error(iter, &err);
  3341. CheckNoError(err);
  3342. rocksdb_iter_destroy(iter);
  3343. rocksdb_transaction_destroy(txn);
  3344. rocksdb_column_family_handle_destroy(cfh1);
  3345. rocksdb_column_family_handle_destroy(cfh2);
  3346. rocksdb_optimistictransactiondb_close_base_db(db);
  3347. rocksdb_optimistictransactiondb_close(otxn_db);
  3348. // Check open optimistic transaction db with column families
  3349. size_t cf_len;
  3350. char** column_fams =
  3351. rocksdb_list_column_families(db_options, dbname, &cf_len, &err);
  3352. CheckNoError(err);
  3353. CheckEqual("default", column_fams[0], 7);
  3354. CheckEqual("txn_db_cf1", column_fams[1], 10);
  3355. CheckEqual("txn_db_cf2", column_fams[2], 10);
  3356. CheckCondition(cf_len == 3);
  3357. rocksdb_list_column_families_destroy(column_fams, cf_len);
  3358. const char* cf_names[3] = {"default", "txn_db_cf1", "txn_db_cf2"};
  3359. rocksdb_options_t* cf_options = rocksdb_options_create();
  3360. const rocksdb_options_t* cf_opts[3] = {cf_options, cf_options, cf_options};
  3361. rocksdb_options_set_error_if_exists(cf_options, 0);
  3362. rocksdb_column_family_handle_t* cf_handles[3];
  3363. otxn_db = rocksdb_optimistictransactiondb_open_column_families(
  3364. db_options, dbname, 3, cf_names, cf_opts, cf_handles, &err);
  3365. CheckNoError(err);
  3366. rocksdb_transaction_t* txn_cf = rocksdb_optimistictransaction_begin(
  3367. otxn_db, woptions, otxn_options, NULL);
  3368. CheckTxnGetCF(txn_cf, roptions, cf_handles[0], "key", "value");
  3369. CheckTxnGetCF(txn_cf, roptions, cf_handles[1], "key_cf1", "val_cf1");
  3370. CheckTxnGetCF(txn_cf, roptions, cf_handles[2], "key_cf2", "val_cf2");
  3371. CheckTxnPinGetCF(txn_cf, roptions, cf_handles[0], "key", "value");
  3372. CheckTxnPinGetCF(txn_cf, roptions, cf_handles[1], "key_cf1", "val_cf1");
  3373. CheckTxnPinGetCF(txn_cf, roptions, cf_handles[2], "key_cf2", "val_cf2");
  3374. rocksdb_transaction_destroy(txn_cf);
  3375. rocksdb_options_destroy(cf_options);
  3376. rocksdb_column_family_handle_destroy(cf_handles[0]);
  3377. rocksdb_column_family_handle_destroy(cf_handles[1]);
  3378. rocksdb_column_family_handle_destroy(cf_handles[2]);
  3379. rocksdb_optimistictransactiondb_close(otxn_db);
  3380. rocksdb_destroy_db(db_options, dbname, &err);
  3381. rocksdb_options_destroy(db_options);
  3382. rocksdb_optimistictransaction_options_destroy(otxn_options);
  3383. CheckNoError(err);
  3384. }
  3385. // Simple sanity check that setting memtable rep works.
  3386. StartPhase("memtable_reps");
  3387. {
  3388. // Create database with vector memtable.
  3389. rocksdb_options_set_memtable_vector_rep(options);
  3390. db = rocksdb_open(options, dbname, &err);
  3391. CheckNoError(err);
  3392. // Create database with hash skiplist memtable.
  3393. rocksdb_close(db);
  3394. rocksdb_destroy_db(options, dbname, &err);
  3395. CheckNoError(err);
  3396. rocksdb_options_set_hash_skip_list_rep(options, 5000, 4, 4);
  3397. db = rocksdb_open(options, dbname, &err);
  3398. CheckNoError(err);
  3399. }
  3400. // Check that secondary instance works.
  3401. StartPhase("open_as_secondary");
  3402. {
  3403. rocksdb_close(db);
  3404. rocksdb_destroy_db(options, dbname, &err);
  3405. rocksdb_options_t* db_options = rocksdb_options_create();
  3406. rocksdb_options_set_create_if_missing(db_options, 1);
  3407. db = rocksdb_open(db_options, dbname, &err);
  3408. CheckNoError(err);
  3409. rocksdb_t* db1;
  3410. rocksdb_options_t* opts = rocksdb_options_create();
  3411. rocksdb_options_set_max_open_files(opts, -1);
  3412. rocksdb_options_set_create_if_missing(opts, 1);
  3413. snprintf(secondary_path, sizeof(secondary_path),
  3414. "%s/rocksdb_c_test_secondary-%d", GetTempDir(), ((int)geteuid()));
  3415. db1 = rocksdb_open_as_secondary(opts, dbname, secondary_path, &err);
  3416. CheckNoError(err);
  3417. rocksdb_writeoptions_set_sync(woptions, 0);
  3418. rocksdb_writeoptions_disable_WAL(woptions, 1);
  3419. rocksdb_put(db, woptions, "key0", 4, "value0", 6, &err);
  3420. CheckNoError(err);
  3421. rocksdb_flushoptions_t* flush_opts = rocksdb_flushoptions_create();
  3422. rocksdb_flushoptions_set_wait(flush_opts, 1);
  3423. rocksdb_flush(db, flush_opts, &err);
  3424. CheckNoError(err);
  3425. rocksdb_try_catch_up_with_primary(db1, &err);
  3426. CheckNoError(err);
  3427. rocksdb_readoptions_t* ropts = rocksdb_readoptions_create();
  3428. rocksdb_readoptions_set_verify_checksums(ropts, 1);
  3429. rocksdb_readoptions_set_snapshot(ropts, NULL);
  3430. CheckGet(db, ropts, "key0", "value0");
  3431. CheckGet(db1, ropts, "key0", "value0");
  3432. rocksdb_writeoptions_disable_WAL(woptions, 0);
  3433. rocksdb_put(db, woptions, "key1", 4, "value1", 6, &err);
  3434. CheckNoError(err);
  3435. rocksdb_try_catch_up_with_primary(db1, &err);
  3436. CheckNoError(err);
  3437. CheckGet(db1, ropts, "key0", "value0");
  3438. CheckGet(db1, ropts, "key1", "value1");
  3439. rocksdb_close(db1);
  3440. rocksdb_destroy_db(opts, secondary_path, &err);
  3441. CheckNoError(err);
  3442. rocksdb_options_destroy(db_options);
  3443. rocksdb_options_destroy(opts);
  3444. rocksdb_readoptions_destroy(ropts);
  3445. rocksdb_flushoptions_destroy(flush_opts);
  3446. }
  3447. // Simple sanity check that options setting db_paths work.
  3448. StartPhase("open_db_paths");
  3449. {
  3450. rocksdb_close(db);
  3451. rocksdb_destroy_db(options, dbname, &err);
  3452. const rocksdb_dbpath_t* paths[1] = {dbpath};
  3453. rocksdb_options_set_db_paths(options, paths, 1);
  3454. db = rocksdb_open(options, dbname, &err);
  3455. CheckNoError(err);
  3456. }
  3457. StartPhase("filter_with_prefix_seek");
  3458. {
  3459. rocksdb_close(db);
  3460. rocksdb_destroy_db(options, dbname, &err);
  3461. CheckNoError(err);
  3462. rocksdb_options_set_prefix_extractor(
  3463. options, rocksdb_slicetransform_create_fixed_prefix(1));
  3464. rocksdb_filterpolicy_t* filter_policy =
  3465. rocksdb_filterpolicy_create_bloom_full(8.0);
  3466. rocksdb_block_based_options_set_filter_policy(table_options, filter_policy);
  3467. rocksdb_options_set_block_based_table_factory(options, table_options);
  3468. db = rocksdb_open(options, dbname, &err);
  3469. CheckNoError(err);
  3470. int i;
  3471. for (i = 0; i < 10; ++i) {
  3472. char key = '0' + (char)i;
  3473. rocksdb_put(db, woptions, &key, 1, "", 1, &err);
  3474. CheckNoError(err);
  3475. }
  3476. // Flush to generate an L0 so that filter will be used later.
  3477. rocksdb_flushoptions_t* flush_options = rocksdb_flushoptions_create();
  3478. rocksdb_flushoptions_set_wait(flush_options, 1);
  3479. rocksdb_flush(db, flush_options, &err);
  3480. rocksdb_flushoptions_destroy(flush_options);
  3481. CheckNoError(err);
  3482. rocksdb_readoptions_t* ropts = rocksdb_readoptions_create();
  3483. rocksdb_iterator_t* iter = rocksdb_create_iterator(db, ropts);
  3484. rocksdb_iter_seek(iter, "0", 1);
  3485. int cnt = 0;
  3486. while (rocksdb_iter_valid(iter)) {
  3487. ++cnt;
  3488. rocksdb_iter_next(iter);
  3489. }
  3490. CheckCondition(10 == cnt);
  3491. rocksdb_iter_destroy(iter);
  3492. rocksdb_readoptions_destroy(ropts);
  3493. }
  3494. StartPhase("statistics");
  3495. {
  3496. const uint32_t BYTES_WRITTEN_TICKER = 60;
  3497. const uint32_t DB_WRITE_HIST = 1;
  3498. rocksdb_statistics_histogram_data_t* hist =
  3499. rocksdb_statistics_histogram_data_create();
  3500. {
  3501. // zero by default
  3502. CheckCondition(0.0 == rocksdb_statistics_histogram_data_get_median(hist));
  3503. CheckCondition(0.0 == rocksdb_statistics_histogram_data_get_p95(hist));
  3504. CheckCondition(0.0 == rocksdb_statistics_histogram_data_get_p99(hist));
  3505. CheckCondition(0.0 ==
  3506. rocksdb_statistics_histogram_data_get_average(hist));
  3507. CheckCondition(0.0 ==
  3508. rocksdb_statistics_histogram_data_get_std_dev(hist));
  3509. CheckCondition(0.0 == rocksdb_statistics_histogram_data_get_max(hist));
  3510. CheckCondition(0 == rocksdb_statistics_histogram_data_get_count(hist));
  3511. CheckCondition(0 == rocksdb_statistics_histogram_data_get_sum(hist));
  3512. CheckCondition(0.0 == rocksdb_statistics_histogram_data_get_min(hist));
  3513. }
  3514. rocksdb_close(db);
  3515. rocksdb_destroy_db(options, dbname, &err);
  3516. CheckNoError(err);
  3517. rocksdb_options_enable_statistics(options);
  3518. rocksdb_options_set_statistics_level(options, rocksdb_statistics_level_all);
  3519. db = rocksdb_open(options, dbname, &err);
  3520. CheckNoError(err);
  3521. CheckCondition(0 == rocksdb_options_statistics_get_ticker_count(
  3522. options, BYTES_WRITTEN_TICKER));
  3523. rocksdb_options_statistics_get_histogram_data(options, DB_WRITE_HIST, hist);
  3524. CheckCondition(0.0 == rocksdb_statistics_histogram_data_get_median(hist));
  3525. CheckCondition(0.0 == rocksdb_statistics_histogram_data_get_p95(hist));
  3526. CheckCondition(0.0 == rocksdb_statistics_histogram_data_get_p99(hist));
  3527. CheckCondition(0.0 == rocksdb_statistics_histogram_data_get_average(hist));
  3528. CheckCondition(0.0 == rocksdb_statistics_histogram_data_get_std_dev(hist));
  3529. CheckCondition(0.0 == rocksdb_statistics_histogram_data_get_max(hist));
  3530. CheckCondition(0 == rocksdb_statistics_histogram_data_get_count(hist));
  3531. CheckCondition(0 == rocksdb_statistics_histogram_data_get_sum(hist));
  3532. int i;
  3533. for (i = 0; i < 10; ++i) {
  3534. char key = '0' + (char)i;
  3535. rocksdb_put(db, woptions, &key, 1, "", 1, &err);
  3536. CheckNoError(err);
  3537. }
  3538. CheckCondition(0 != rocksdb_options_statistics_get_ticker_count(
  3539. options, BYTES_WRITTEN_TICKER));
  3540. rocksdb_options_statistics_get_histogram_data(options, DB_WRITE_HIST, hist);
  3541. CheckCondition(0.0 != rocksdb_statistics_histogram_data_get_median(hist));
  3542. CheckCondition(0.0 != rocksdb_statistics_histogram_data_get_p95(hist));
  3543. CheckCondition(0.0 != rocksdb_statistics_histogram_data_get_p99(hist));
  3544. CheckCondition(0.0 != rocksdb_statistics_histogram_data_get_average(hist));
  3545. CheckCondition(0.0 != rocksdb_statistics_histogram_data_get_std_dev(hist));
  3546. CheckCondition(0.0 != rocksdb_statistics_histogram_data_get_max(hist));
  3547. CheckCondition(0 != rocksdb_statistics_histogram_data_get_count(hist));
  3548. CheckCondition(0 != rocksdb_statistics_histogram_data_get_sum(hist));
  3549. rocksdb_statistics_histogram_data_destroy(hist);
  3550. }
  3551. StartPhase("wait_for_compact_options");
  3552. {
  3553. rocksdb_wait_for_compact_options_t* wco;
  3554. wco = rocksdb_wait_for_compact_options_create();
  3555. rocksdb_wait_for_compact_options_set_abort_on_pause(wco, 1);
  3556. CheckCondition(1 ==
  3557. rocksdb_wait_for_compact_options_get_abort_on_pause(wco));
  3558. rocksdb_wait_for_compact_options_set_flush(wco, 1);
  3559. CheckCondition(1 == rocksdb_wait_for_compact_options_get_flush(wco));
  3560. rocksdb_wait_for_compact_options_set_close_db(wco, 1);
  3561. CheckCondition(1 == rocksdb_wait_for_compact_options_get_close_db(wco));
  3562. rocksdb_wait_for_compact_options_set_timeout(wco, 342);
  3563. CheckCondition(342 == rocksdb_wait_for_compact_options_get_timeout(wco));
  3564. rocksdb_wait_for_compact_options_destroy(wco);
  3565. }
  3566. StartPhase("wait_for_compact");
  3567. {
  3568. rocksdb_wait_for_compact_options_t* wco;
  3569. wco = rocksdb_wait_for_compact_options_create();
  3570. rocksdb_wait_for_compact_options_set_flush(wco, 1);
  3571. rocksdb_wait_for_compact(db, wco, &err);
  3572. CheckNoError(err);
  3573. rocksdb_wait_for_compact_options_destroy(wco);
  3574. }
  3575. StartPhase("write_buffer_manager");
  3576. {
  3577. rocksdb_cache_t* lru;
  3578. lru = rocksdb_cache_create_lru(100);
  3579. rocksdb_write_buffer_manager_t* write_buffer_manager;
  3580. write_buffer_manager =
  3581. rocksdb_write_buffer_manager_create_with_cache(200, lru, false);
  3582. CheckCondition(true ==
  3583. rocksdb_write_buffer_manager_enabled(write_buffer_manager));
  3584. CheckCondition(true == rocksdb_write_buffer_manager_cost_to_cache(
  3585. write_buffer_manager));
  3586. CheckCondition(
  3587. 200 == rocksdb_write_buffer_manager_buffer_size(write_buffer_manager));
  3588. rocksdb_write_buffer_manager_set_buffer_size(write_buffer_manager, 300);
  3589. CheckCondition(
  3590. 300 == rocksdb_write_buffer_manager_buffer_size(write_buffer_manager));
  3591. rocksdb_write_buffer_manager_destroy(write_buffer_manager);
  3592. rocksdb_cache_destroy(lru);
  3593. }
  3594. StartPhase("sst_file_manager");
  3595. {
  3596. rocksdb_sst_file_manager_t* sst_file_manager;
  3597. sst_file_manager = rocksdb_sst_file_manager_create(env);
  3598. rocksdb_sst_file_manager_set_delete_rate_bytes_per_second(sst_file_manager,
  3599. 1);
  3600. rocksdb_sst_file_manager_set_max_trash_db_ratio(sst_file_manager, 0.75);
  3601. CheckCondition(1 ==
  3602. rocksdb_sst_file_manager_get_delete_rate_bytes_per_second(
  3603. sst_file_manager));
  3604. CheckCondition(0.75 == rocksdb_sst_file_manager_get_max_trash_db_ratio(
  3605. sst_file_manager));
  3606. rocksdb_sst_file_manager_destroy(sst_file_manager);
  3607. }
  3608. StartPhase("cancel_all_background_work");
  3609. rocksdb_cancel_all_background_work(db, 1);
  3610. StartPhase("cleanup");
  3611. rocksdb_close(db);
  3612. rocksdb_options_destroy(options);
  3613. rocksdb_block_based_options_destroy(table_options);
  3614. rocksdb_readoptions_destroy(roptions);
  3615. rocksdb_writeoptions_destroy(woptions);
  3616. rocksdb_compactoptions_destroy(coptions);
  3617. rocksdb_cache_destroy(cache);
  3618. rocksdb_comparator_destroy(cmp);
  3619. rocksdb_dbpath_destroy(dbpath);
  3620. rocksdb_env_destroy(env);
  3621. fprintf(stderr, "PASS\n");
  3622. return 0;
  3623. }