nolo-cli 0.108.0-alpha.2 → 0.108.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (606) hide show
  1. package/README.md +1 -1
  2. package/{_executeModel-BY3P5LBB.js → _executeModel-RVAKYU4J.js} +128 -83
  3. package/action-RHUT4OHH.js +23 -0
  4. package/{addContentAction-MB2HHMDZ.js → addContentAction-BQ3LJLUW.js} +19 -13
  5. package/{addDialogAgentAction-MCEABSBA.js → addDialogAgentAction-B6X7BXR4.js} +24 -20
  6. package/{agentDeleteCommand-66KXCSRR.js → agentDeleteCommand-T5MDAOE7.js} +154 -68
  7. package/{agentEmailCommands-63UTONDK.js → agentEmailCommands-UWBQSKLI.js} +125 -105
  8. package/{agentGrantCommands-M3XFO6EN.js → agentGrantCommands-HOJ3JBBQ.js} +3 -3
  9. package/agentListCommands-2Q456VYS.js +800 -0
  10. package/{agentMachineCommands-Z6RGPZSG.js → agentMachineCommands-FPJJ4DCF.js} +54 -58
  11. package/{agentProviderCommands-X3UNW77C.js → agentProviderCommands-7PCGR77I.js} +97 -2
  12. package/{agentPullCommand-O5MPVJ5E.js → agentPullCommand-7GCDM4BK.js} +7 -7
  13. package/agentRecordCommands-3JGDR4NN.js +149 -0
  14. package/agentRunCommand-3NQOP3SD.js +179 -0
  15. package/{agentRunControl-AVJR4JW4.js → agentRunControl-2CDZNHXV.js} +10 -2
  16. package/{agentRuntimeLocal-E67CTV45.js → agentRuntimeLocal-SQUDRZWE.js} +41 -46
  17. package/{agentSlice-DG5TIQHE.js → agentSlice-R4W6MCEW.js} +22 -16
  18. package/{appDeleteCommands-Z36CLGUK.js → appDeleteCommands-CLLYGEBC.js} +55 -56
  19. package/{appDeployCommands-ECMUWG6S.js → appDeployCommands-HY2NBNDQ.js} +64 -60
  20. package/{appDeployStatusCommands-CL24TDMA.js → appDeployStatusCommands-SGO5GEXH.js} +53 -53
  21. package/{appGetCommands-ITHGOYGJ.js → appGetCommands-ZPYK2N5D.js} +53 -53
  22. package/{appListCommands-EEOSI6RC.js → appListCommands-O2BHIMKS.js} +54 -56
  23. package/{authCommand-HGP2XTKC.js → authCommand-GUIREPHK.js} +132 -83
  24. package/{authCommands-RGOGCPP6.js → authCommands-K3BDSTJ4.js} +10 -7
  25. package/{builtinSkillRegistry-FUAVTRVZ.js → builtinSkillRegistry-MUOUTRNJ.js} +13 -10
  26. package/{chromeCommands-FZYAU75D.js → chromeCommands-Z2WRJB7O.js} +290 -38
  27. package/{chromeOpsCommands-62P2Q2YB.js → chromeOpsCommands-YWYXZTIR.js} +157 -23
  28. package/{chunk-RVE4DCV3.js → chunk-26UZ2Y4Z.js} +26 -31
  29. package/{chunk-2F7RJC6L.js → chunk-2C47W7IJ.js} +1 -1
  30. package/{chunk-VLTIYV3X.js → chunk-2ECUZDEL.js} +37 -11
  31. package/{chunk-ALXHV7NK.js → chunk-2GGXHQIW.js} +43 -4
  32. package/{chunk-AHAHBQMU.js → chunk-2OMUAIKR.js} +2 -2
  33. package/{chunk-DHDMC6FO.js → chunk-3CZM6HGQ.js} +53 -23
  34. package/{chunk-BNGW5ASC.js → chunk-3LI5UCTU.js} +23 -3
  35. package/{chunk-FDTR4QJ6.js → chunk-3MZAGMYY.js} +48 -1
  36. package/chunk-3PVYUPXK.js +40 -0
  37. package/{chunk-FV3JEYR3.js → chunk-3SK3J3IF.js} +69 -10
  38. package/chunk-4LCOCOR5.js +50 -0
  39. package/{chunk-V7E4PXQD.js → chunk-4MSYSHZD.js} +15 -7
  40. package/{chunk-2GRGFCF6.js → chunk-4VJAC32I.js} +2 -1
  41. package/{chunk-MP64VFGD.js → chunk-4XEYAFLY.js} +60 -18
  42. package/chunk-4YRTZIVN.js +871 -0
  43. package/{chunk-MC4XLIJ7.js → chunk-523DITKR.js} +1 -1
  44. package/{chunk-N7J63Q6C.js → chunk-56GBUMO5.js} +10 -1
  45. package/chunk-5MMAK75Q.js +15 -0
  46. package/{chunk-KZJP33ZK.js → chunk-5WLADF62.js} +90 -36
  47. package/chunk-5XN3OSCT.js +164 -0
  48. package/chunk-6CCAXGFK.js +1712 -0
  49. package/{chunk-42V6BK2E.js → chunk-6MXDOUMH.js} +18 -36
  50. package/{chunk-QOKAKDPE.js → chunk-6Q7UTJKR.js} +6 -94
  51. package/{chunk-J4MOO56S.js → chunk-6VRWNU5J.js} +10 -2
  52. package/{chunk-IQPFGYO3.js → chunk-726TCFLQ.js} +5 -5
  53. package/chunk-7DPNBQSV.js +9 -0
  54. package/chunk-7YVPCIEN.js +1858 -0
  55. package/{chunk-LWKP7AWH.js → chunk-A337PRRR.js} +41 -17
  56. package/chunk-AGIM7IMJ.js +147 -0
  57. package/{chunk-ABQYVJBJ.js → chunk-AIZE5TDM.js} +3 -3
  58. package/{chunk-LJ5VW2UJ.js → chunk-ALKCVCA5.js} +4 -4
  59. package/{chunk-5UTFL4QJ.js → chunk-APO5TOXO.js} +1 -1
  60. package/{chunk-E4MARS3Q.js → chunk-AU7AXHUL.js} +1 -1
  61. package/{chunk-PBA4UJBK.js → chunk-BFYDNHYW.js} +12 -12
  62. package/{chunk-QTGQ2LTL.js → chunk-BIAETTOB.js} +5 -9
  63. package/{chunk-OIVSQH2O.js → chunk-CGEK73JN.js} +311 -12
  64. package/chunk-CHOZJMJS.js +78 -0
  65. package/{chunk-GBRG75BQ.js → chunk-D2MDMY2M.js} +1 -0
  66. package/chunk-DGDGNYI5.js +593 -0
  67. package/{chunk-TRV2MIDW.js → chunk-EXAJ6DCR.js} +1 -0
  68. package/{chunk-YTLRHRH3.js → chunk-EXR4XCFE.js} +17 -15
  69. package/chunk-EYLGAEB4.js +784 -0
  70. package/{chunk-3BMYXEUW.js → chunk-F2UJW3EK.js} +1 -1
  71. package/{chunk-P5EVSOPA.js → chunk-FWY6BHIJ.js} +363 -248
  72. package/{chunk-4MK3I7Y4.js → chunk-G23MQWLJ.js} +7 -128
  73. package/chunk-G6OOUQWJ.js +417 -0
  74. package/{chunk-WV42OMV7.js → chunk-GHZ2H2HJ.js} +11 -15
  75. package/chunk-I42VC5KR.js +15 -0
  76. package/{chunk-H4AHY5BU.js → chunk-IFALJPEX.js} +69 -20
  77. package/{chunk-O6OSWFZQ.js → chunk-IHPDK6UD.js} +6 -0
  78. package/{chunk-UKWGR5SS.js → chunk-IJERIUXS.js} +242 -1146
  79. package/chunk-IRG4OKY6.js +843 -0
  80. package/{chunk-PWBDVI4R.js → chunk-IUTHWIZQ.js} +269 -141
  81. package/{chunk-QDSINZM3.js → chunk-IXH3HKY2.js} +1 -22
  82. package/chunk-JJM3WS6W.js +132 -0
  83. package/{chunk-RZGLXO2B.js → chunk-KN6MKCS5.js} +1715 -451
  84. package/{chunk-SH43IESU.js → chunk-KQ7DAEZ7.js} +202 -32
  85. package/{chunk-6OZ36FXI.js → chunk-KY6GPQ7O.js} +36 -12
  86. package/{chunk-MRIHM22T.js → chunk-LAVSW2C2.js} +77 -144
  87. package/{chunk-HSSRGGXJ.js → chunk-LNEKN523.js} +10 -7
  88. package/chunk-LWLNLZC5.js +265 -0
  89. package/{chunk-I3TQJXQ7.js → chunk-MHD5JBSS.js} +131 -10
  90. package/{chunk-QU7KDSZX.js → chunk-MW533QT3.js} +190 -8
  91. package/{chunk-4NNTATRH.js → chunk-NLEJWKF5.js} +10394 -8549
  92. package/{chunk-BFU6C242.js → chunk-NMFV26UG.js} +1 -1
  93. package/{chunk-GQBOR3G6.js → chunk-NN4UUYGB.js} +18 -4
  94. package/{chunk-FZGV4FGK.js → chunk-NUHHBEJC.js} +378 -187
  95. package/chunk-OKARGYFT.js +15 -0
  96. package/{chunk-KQHGZWSV.js → chunk-OXME3PEE.js} +1 -1
  97. package/{chunk-Z5625XML.js → chunk-OYBAT7RT.js} +113 -17
  98. package/chunk-P3SFAHIL.js +134 -0
  99. package/{chunk-DOTZ5GTO.js → chunk-P6KLYCL3.js} +310 -95
  100. package/{chunk-XD2MJFUG.js → chunk-PBGO5AFD.js} +1 -1
  101. package/{chunk-EYAQT56M.js → chunk-PFEK4SA2.js} +13 -10
  102. package/{chunk-Z77CRGTW.js → chunk-PHHFVGOJ.js} +1 -1
  103. package/{chunk-3VNWWVKB.js → chunk-PJNFNEJE.js} +114 -28
  104. package/{chunk-G4VIHCGJ.js → chunk-PS6XSDHW.js} +35 -30
  105. package/{chunk-HVURBGF3.js → chunk-PWRS2SU2.js} +27 -9
  106. package/chunk-QFEW2ULV.js +42 -0
  107. package/chunk-QH2QSBGP.js +7546 -0
  108. package/{chunk-IIVGDG4I.js → chunk-QLQ573SU.js} +124 -77
  109. package/chunk-QQ56R7KS.js +88 -0
  110. package/chunk-QYPE3TS3.js +43 -0
  111. package/{chunk-VMFTFOWF.js → chunk-RLRYVSCD.js} +31 -14
  112. package/{chunk-VRTTFDBM.js → chunk-RNNWTMKT.js} +56 -63
  113. package/chunk-ROXFUKKL.js +13941 -0
  114. package/{chunk-SYXOBWOC.js → chunk-RRPT5CGT.js} +124 -703
  115. package/{chunk-JRQFUXY7.js → chunk-RRQQAG7W.js} +93 -24
  116. package/chunk-SJ3QFSQS.js +1147 -0
  117. package/chunk-SP4WCECG.js +95 -0
  118. package/{chunk-Q67DOFOO.js → chunk-SZC4REES.js} +212 -105
  119. package/{chunk-BYMV6QZG.js → chunk-TNIX77YM.js} +4 -0
  120. package/{chunk-GNCCNNZD.js → chunk-TSBCYK5F.js} +7 -7
  121. package/chunk-TY3TIUJK.js +89 -0
  122. package/chunk-U4STABYN.js +81 -0
  123. package/chunk-UEILX4EV.js +15 -0
  124. package/{chunk-YYLHWIW6.js → chunk-UKZX3NHN.js} +1 -1
  125. package/{chunk-AODJ7WSF.js → chunk-UPFOOGHU.js} +90 -79
  126. package/{chunk-7S4YWN7P.js → chunk-V2UPLOXT.js} +4 -4
  127. package/{chunk-2OASQKU2.js → chunk-V5DCOM6G.js} +185 -16
  128. package/{chunk-LS2ZANRJ.js → chunk-V6WXGTUJ.js} +1 -1
  129. package/{chunk-6YTOJY35.js → chunk-VBG7GWWR.js} +253 -8
  130. package/{chunk-DVINR3PL.js → chunk-VEA7H5FG.js} +3 -3
  131. package/chunk-VIWDGTDA.js +8 -0
  132. package/chunk-VJVNU77E.js +83 -0
  133. package/{chunk-EADNWBAZ.js → chunk-VP3BINY7.js} +13 -0
  134. package/{chunk-HKNXJGEC.js → chunk-VSPO4S33.js} +47 -192
  135. package/{chunk-PHXD6JTX.js → chunk-W2N3ZC4P.js} +7 -7
  136. package/{chunk-EOARMOVD.js → chunk-W4S6OTSC.js} +6 -3
  137. package/{chunk-6Z7MY3V7.js → chunk-WCQNEMXG.js} +3 -3
  138. package/chunk-WJZOQR2J.js +151 -0
  139. package/{chunk-T3GEOSRJ.js → chunk-WVES4PHL.js} +69 -57
  140. package/{chunk-BFDFRLLQ.js → chunk-WW2USJ3C.js} +3 -3
  141. package/{chunk-TR22GEUU.js → chunk-X2VPXJZC.js} +20 -11
  142. package/chunk-X5BIY654.js +29 -0
  143. package/{chunk-Q554LLSI.js → chunk-XETG4RIX.js} +5 -5
  144. package/{chunk-3L2WKC3W.js → chunk-XPWGOTBQ.js} +8 -1
  145. package/{chunk-JEDZAO7L.js → chunk-YBNHPX4S.js} +257 -37
  146. package/{chunk-JPGCXHNM.js → chunk-YLMMECCH.js} +1 -1
  147. package/{chunk-CW67PN7L.js → chunk-YSZQSZR2.js} +61 -11
  148. package/{chunk-6D6VBVEW.js → chunk-YVTZMLXZ.js} +96 -25
  149. package/{chunk-LPIYPEME.js → chunk-YZZLKXCQ.js} +1449 -1094
  150. package/chunk-ZRAU6T47.js +56 -0
  151. package/{chunk-ONXOABJR.js → chunk-ZWQUWF6W.js} +36 -1
  152. package/{cliExecutor-HG3S345O.js → cliExecutor-AWYR3T33.js} +1 -1
  153. package/commandRegistry-C25O2ARU.js +839 -0
  154. package/contentThunks-UWODFKX6.js +83 -0
  155. package/{cooldownCommands-REAWYVTY.js → cooldownCommands-JFKTYS2D.js} +2 -2
  156. package/{createAgentAutomationAction-7HX7KBES.js → createAgentAutomationAction-SA4IA4CR.js} +51 -43
  157. package/createDialogAction-EDK5IMRG.js +75 -0
  158. package/{createPageAction-QWNMGO3O.js → createPageAction-VYVF5EIZ.js} +60 -51
  159. package/{chunk-UDIIVXKA.js → cursorProvider-YGGNMVWX.js} +2822 -10269
  160. package/{dbSlice-A6C6H32X.js → dbSlice-JQFBMJ55.js} +18 -12
  161. package/{deleteFile-YG6QMJLU.js → deleteFile-6JWDDRVP.js} +9 -5
  162. package/dialogCommands-K734RXEQ.js +108 -0
  163. package/{dialogSlice-P2K47T3P.js → dialogSlice-EEDP6PJ3.js} +66 -41
  164. package/{dist-VODFSGNG.js → dist-NJC2W7I4.js} +61 -54
  165. package/{docCreateCommands-43JKQEIH.js → docCreateCommands-N3KPGP4A.js} +51 -54
  166. package/{docDeleteCommands-RL6D46XE.js → docDeleteCommands-4CR4TXZ7.js} +53 -55
  167. package/{docReadCommands-TOEUEQDG.js → docReadCommands-62XK57VS.js} +50 -53
  168. package/{docStore-3AHKTJRI.js → docStore-RB7YBD4Y.js} +24 -15
  169. package/{docUpdateCommands-FWU5G2XB.js → docUpdateCommands-DRAAWIDC.js} +51 -54
  170. package/{fetchMessages-EIU7UFFK.js → fetchMessages-LM6OMMQQ.js} +5 -4
  171. package/{getPricing-LUSEABA6.js → getPricing-XDF4OLTC.js} +6 -6
  172. package/handleSendMessageAction-TYDPIC6O.js +1849 -0
  173. package/index.js +91 -884
  174. package/{lib-FRRS27KN.js → lib-PU2G2MSO.js} +523 -191
  175. package/{localDialogRead-BTFJ4V2I.js → localDialogRead-BOETO2TD.js} +2 -2
  176. package/localRuntimeAdapter-VYB2QTU3.js +239 -0
  177. package/{localRuntimeAuthority-6IR6BBXE.js → localRuntimeAuthority-YSE6NH7B.js} +12 -9
  178. package/{localRuntimeDb-SYQGUF4U.js → localRuntimeDb-7FBKDEQY.js} +1 -1
  179. package/{machineCommands-TTKK4F7C.js → machineCommands-IQRRLSYP.js} +493 -152
  180. package/machineWsRunDispatch-LIMM5CYE.js +164 -0
  181. package/{memberThunks-P2ECUJ56.js → memberThunks-Y3Q7GZTG.js} +24 -17
  182. package/{models-T3SG6MJ5.js → models-6V4ZCHEE.js} +2 -2
  183. package/node_modules/abstract-level/CHANGELOG.md +150 -0
  184. package/node_modules/abstract-level/LICENSE +21 -0
  185. package/node_modules/abstract-level/README.md +1957 -0
  186. package/node_modules/abstract-level/UPGRADING.md +669 -0
  187. package/node_modules/abstract-level/abstract-chained-batch.js +397 -0
  188. package/node_modules/abstract-level/abstract-iterator.js +404 -0
  189. package/node_modules/abstract-level/abstract-level.js +1127 -0
  190. package/node_modules/abstract-level/abstract-snapshot.js +84 -0
  191. package/node_modules/abstract-level/index.d.ts +52 -0
  192. package/node_modules/abstract-level/index.js +9 -0
  193. package/node_modules/abstract-level/lib/abstract-sublevel-iterator.js +141 -0
  194. package/node_modules/abstract-level/lib/abstract-sublevel.js +290 -0
  195. package/node_modules/abstract-level/lib/common.js +33 -0
  196. package/node_modules/abstract-level/lib/default-chained-batch.js +29 -0
  197. package/node_modules/abstract-level/lib/default-kv-iterator.js +74 -0
  198. package/node_modules/abstract-level/lib/deferred-iterator.js +110 -0
  199. package/node_modules/abstract-level/lib/deferred-queue.js +84 -0
  200. package/node_modules/abstract-level/lib/errors.js +21 -0
  201. package/node_modules/abstract-level/lib/event-monitor.js +30 -0
  202. package/node_modules/abstract-level/lib/hooks.js +78 -0
  203. package/node_modules/abstract-level/lib/prefixes.js +21 -0
  204. package/node_modules/abstract-level/lib/prewrite-batch.js +96 -0
  205. package/node_modules/abstract-level/lib/range-options.js +26 -0
  206. package/node_modules/abstract-level/package.json +66 -0
  207. package/node_modules/abstract-level/test/async-iterator-test.js +132 -0
  208. package/node_modules/abstract-level/test/batch-test.js +214 -0
  209. package/node_modules/abstract-level/test/chained-batch-test.js +315 -0
  210. package/node_modules/abstract-level/test/clear-range-test.js +262 -0
  211. package/node_modules/abstract-level/test/clear-test.js +110 -0
  212. package/node_modules/abstract-level/test/common.js +90 -0
  213. package/node_modules/abstract-level/test/deferred-open-test.js +209 -0
  214. package/node_modules/abstract-level/test/del-test.js +65 -0
  215. package/node_modules/abstract-level/test/encoding-buffer-test.js +336 -0
  216. package/node_modules/abstract-level/test/encoding-custom-test.js +92 -0
  217. package/node_modules/abstract-level/test/encoding-decode-error-test.js +85 -0
  218. package/node_modules/abstract-level/test/encoding-json-test.js +75 -0
  219. package/node_modules/abstract-level/test/encoding-test.js +130 -0
  220. package/node_modules/abstract-level/test/events/write.js +132 -0
  221. package/node_modules/abstract-level/test/factory-test.js +36 -0
  222. package/node_modules/abstract-level/test/get-many-test.js +157 -0
  223. package/node_modules/abstract-level/test/get-sync-test.js +61 -0
  224. package/node_modules/abstract-level/test/get-test.js +83 -0
  225. package/node_modules/abstract-level/test/has-many-test.js +144 -0
  226. package/node_modules/abstract-level/test/has-test.js +81 -0
  227. package/node_modules/abstract-level/test/hooks/newsub.js +57 -0
  228. package/node_modules/abstract-level/test/hooks/postopen.js +229 -0
  229. package/node_modules/abstract-level/test/hooks/prewrite.js +816 -0
  230. package/node_modules/abstract-level/test/hooks/shared.js +38 -0
  231. package/node_modules/abstract-level/test/index.js +86 -0
  232. package/node_modules/abstract-level/test/iterator-explicit-snapshot-test.js +393 -0
  233. package/node_modules/abstract-level/test/iterator-no-snapshot-test.js +49 -0
  234. package/node_modules/abstract-level/test/iterator-range-test.js +277 -0
  235. package/node_modules/abstract-level/test/iterator-seek-test.js +335 -0
  236. package/node_modules/abstract-level/test/iterator-snapshot-test.js +56 -0
  237. package/node_modules/abstract-level/test/iterator-test.js +621 -0
  238. package/node_modules/abstract-level/test/manifest-test.js +21 -0
  239. package/node_modules/abstract-level/test/open-create-if-missing-test.js +39 -0
  240. package/node_modules/abstract-level/test/open-error-if-exists-test.js +25 -0
  241. package/node_modules/abstract-level/test/open-test.js +263 -0
  242. package/node_modules/abstract-level/test/put-get-del-test.js +97 -0
  243. package/node_modules/abstract-level/test/put-test.js +70 -0
  244. package/node_modules/abstract-level/test/self/abstract-iterator-test.js +182 -0
  245. package/node_modules/abstract-level/test/self/async-iterator-test.js +242 -0
  246. package/node_modules/abstract-level/test/self/attach-resource-test.js +74 -0
  247. package/node_modules/abstract-level/test/self/defer-test.js +140 -0
  248. package/node_modules/abstract-level/test/self/deferred-iterator-test.js +314 -0
  249. package/node_modules/abstract-level/test/self/deferred-operations-test.js +86 -0
  250. package/node_modules/abstract-level/test/self/deferred-queue-test.js +93 -0
  251. package/node_modules/abstract-level/test/self/encoding-test.js +391 -0
  252. package/node_modules/abstract-level/test/self/errors-test.js +11 -0
  253. package/node_modules/abstract-level/test/self/iterator-test.js +1050 -0
  254. package/node_modules/abstract-level/test/self/sublevel-test.js +1039 -0
  255. package/node_modules/abstract-level/test/self.js +905 -0
  256. package/node_modules/abstract-level/test/sublevel-test.js +209 -0
  257. package/node_modules/abstract-level/test/traits/closed.js +42 -0
  258. package/node_modules/abstract-level/test/traits/index.js +4 -0
  259. package/node_modules/abstract-level/test/traits/open.js +62 -0
  260. package/node_modules/abstract-level/test/util.js +275 -0
  261. package/node_modules/abstract-level/types/abstract-chained-batch.d.ts +124 -0
  262. package/node_modules/abstract-level/types/abstract-iterator.d.ts +241 -0
  263. package/node_modules/abstract-level/types/abstract-level.d.ts +636 -0
  264. package/node_modules/abstract-level/types/abstract-snapshot.d.ts +30 -0
  265. package/node_modules/abstract-level/types/abstract-sublevel.d.ts +76 -0
  266. package/node_modules/abstract-level/types/interfaces.d.ts +43 -0
  267. package/node_modules/base64-js/LICENSE +21 -0
  268. package/node_modules/base64-js/README.md +34 -0
  269. package/node_modules/base64-js/base64js.min.js +1 -0
  270. package/node_modules/base64-js/index.d.ts +3 -0
  271. package/node_modules/base64-js/index.js +150 -0
  272. package/node_modules/base64-js/package.json +47 -0
  273. package/node_modules/browser-level/CHANGELOG.md +44 -0
  274. package/node_modules/browser-level/LICENSE +21 -0
  275. package/node_modules/browser-level/README.md +124 -0
  276. package/node_modules/browser-level/UPGRADING.md +143 -0
  277. package/node_modules/browser-level/index.d.ts +108 -0
  278. package/node_modules/browser-level/index.js +323 -0
  279. package/node_modules/browser-level/iterator.js +239 -0
  280. package/node_modules/browser-level/package.json +48 -0
  281. package/node_modules/browser-level/util/clear.js +38 -0
  282. package/node_modules/browser-level/util/deserialize.js +17 -0
  283. package/node_modules/browser-level/util/key-range.js +20 -0
  284. package/node_modules/buffer/AUTHORS.md +73 -0
  285. package/node_modules/buffer/LICENSE +21 -0
  286. package/node_modules/buffer/README.md +410 -0
  287. package/node_modules/buffer/index.d.ts +194 -0
  288. package/node_modules/buffer/index.js +2106 -0
  289. package/node_modules/buffer/package.json +93 -0
  290. package/node_modules/classic-level/CHANGELOG.md +115 -0
  291. package/node_modules/classic-level/LICENSE +21 -0
  292. package/node_modules/classic-level/README.md +274 -0
  293. package/node_modules/classic-level/UPGRADING.md +131 -0
  294. package/node_modules/classic-level/binding.cc +2652 -0
  295. package/node_modules/classic-level/binding.gyp +71 -0
  296. package/node_modules/classic-level/binding.js +1 -0
  297. package/node_modules/classic-level/chained-batch.js +35 -0
  298. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/LICENSE +27 -0
  299. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/Makefile +424 -0
  300. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/build_detect_platform +256 -0
  301. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/db/autocompact_test.cc +118 -0
  302. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/db/builder.cc +88 -0
  303. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/db/builder.h +34 -0
  304. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/db/c.cc +595 -0
  305. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/db/c_test.c +390 -0
  306. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/db/corruption_test.cc +374 -0
  307. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/db/db_bench.cc +1020 -0
  308. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/db/db_impl.cc +1568 -0
  309. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/db/db_impl.h +212 -0
  310. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/db/db_iter.cc +317 -0
  311. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/db/db_iter.h +28 -0
  312. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/db/db_test.cc +2158 -0
  313. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/db/dbformat.cc +140 -0
  314. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/db/dbformat.h +230 -0
  315. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/db/dbformat_test.cc +112 -0
  316. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/db/dumpfile.cc +225 -0
  317. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/db/fault_injection_test.cc +554 -0
  318. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/db/filename.cc +144 -0
  319. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/db/filename.h +85 -0
  320. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/db/filename_test.cc +123 -0
  321. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/db/leveldbutil.cc +64 -0
  322. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/db/log_format.h +35 -0
  323. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/db/log_reader.cc +284 -0
  324. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/db/log_reader.h +113 -0
  325. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/db/log_test.cc +591 -0
  326. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/db/log_writer.cc +112 -0
  327. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/db/log_writer.h +54 -0
  328. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/db/memtable.cc +145 -0
  329. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/db/memtable.h +89 -0
  330. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/db/recovery_test.cc +324 -0
  331. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/db/repair.cc +461 -0
  332. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/db/skiplist.h +384 -0
  333. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/db/skiplist_test.cc +378 -0
  334. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/db/snapshot.h +67 -0
  335. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/db/table_cache.cc +127 -0
  336. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/db/table_cache.h +61 -0
  337. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/db/version_edit.cc +266 -0
  338. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/db/version_edit.h +107 -0
  339. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/db/version_edit_test.cc +46 -0
  340. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/db/version_set.cc +1535 -0
  341. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/db/version_set.h +399 -0
  342. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/db/version_set_test.cc +179 -0
  343. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/db/write_batch.cc +147 -0
  344. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/db/write_batch_internal.h +50 -0
  345. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/db/write_batch_test.cc +120 -0
  346. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/helpers/memenv/memenv.cc +398 -0
  347. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/helpers/memenv/memenv.h +20 -0
  348. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/helpers/memenv/memenv_test.cc +241 -0
  349. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/include/leveldb/c.h +290 -0
  350. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/include/leveldb/cache.h +110 -0
  351. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/include/leveldb/comparator.h +63 -0
  352. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/include/leveldb/db.h +164 -0
  353. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/include/leveldb/dumpfile.h +25 -0
  354. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/include/leveldb/env.h +351 -0
  355. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/include/leveldb/filter_policy.h +70 -0
  356. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/include/leveldb/iterator.h +100 -0
  357. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/include/leveldb/options.h +213 -0
  358. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/include/leveldb/slice.h +109 -0
  359. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/include/leveldb/status.h +112 -0
  360. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/include/leveldb/table.h +85 -0
  361. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/include/leveldb/table_builder.h +92 -0
  362. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/include/leveldb/value_sink.h +26 -0
  363. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/include/leveldb/write_batch.h +64 -0
  364. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/issues/issue178_test.cc +92 -0
  365. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/issues/issue200_test.cc +59 -0
  366. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/port/atomic_pointer.h +242 -0
  367. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/port/port.h +21 -0
  368. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/port/port_example.h +141 -0
  369. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/port/port_posix.cc +53 -0
  370. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/port/port_posix.h +156 -0
  371. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/port/port_posix_sse.cc +129 -0
  372. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/port/thread_annotations.h +60 -0
  373. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/port/win/stdint.h +24 -0
  374. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/table/block.cc +268 -0
  375. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/table/block.h +44 -0
  376. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/table/block_builder.cc +109 -0
  377. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/table/block_builder.h +57 -0
  378. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/table/filter_block.cc +111 -0
  379. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/table/filter_block.h +68 -0
  380. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/table/filter_block_test.cc +128 -0
  381. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/table/format.cc +144 -0
  382. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/table/format.h +108 -0
  383. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/table/iterator.cc +67 -0
  384. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/table/iterator_wrapper.h +66 -0
  385. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/table/merger.cc +197 -0
  386. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/table/merger.h +26 -0
  387. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/table/table.cc +285 -0
  388. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/table/table_builder.cc +270 -0
  389. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/table/table_test.cc +876 -0
  390. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/table/two_level_iterator.cc +182 -0
  391. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/table/two_level_iterator.h +34 -0
  392. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/util/arena.cc +68 -0
  393. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/util/arena.h +68 -0
  394. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/util/arena_test.cc +68 -0
  395. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/util/bloom.cc +95 -0
  396. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/util/bloom_test.cc +162 -0
  397. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/util/cache.cc +405 -0
  398. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/util/cache_test.cc +226 -0
  399. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/util/coding.cc +194 -0
  400. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/util/coding.h +104 -0
  401. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/util/coding_test.cc +196 -0
  402. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/util/comparator.cc +81 -0
  403. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/util/crc32c.cc +350 -0
  404. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/util/crc32c.h +45 -0
  405. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/util/crc32c_test.cc +72 -0
  406. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/util/env.cc +100 -0
  407. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/util/env_posix.cc +695 -0
  408. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/util/env_posix_test.cc +66 -0
  409. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/util/env_posix_test_helper.h +28 -0
  410. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/util/env_test.cc +106 -0
  411. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/util/filter_policy.cc +11 -0
  412. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/util/hash.cc +52 -0
  413. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/util/hash.h +19 -0
  414. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/util/hash_test.cc +54 -0
  415. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/util/histogram.cc +139 -0
  416. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/util/histogram.h +42 -0
  417. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/util/logging.cc +72 -0
  418. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/util/logging.h +43 -0
  419. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/util/mutexlock.h +41 -0
  420. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/util/options.cc +30 -0
  421. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/util/posix_logger.h +98 -0
  422. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/util/random.h +64 -0
  423. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/util/status.cc +75 -0
  424. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/util/testharness.cc +77 -0
  425. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/util/testharness.h +138 -0
  426. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/util/testutil.cc +51 -0
  427. package/node_modules/classic-level/deps/leveldb/leveldb-1.20/util/testutil.h +63 -0
  428. package/node_modules/classic-level/deps/leveldb/leveldb.gyp +282 -0
  429. package/node_modules/classic-level/deps/leveldb/patches/001-value-sink.patch +164 -0
  430. package/node_modules/classic-level/deps/leveldb/port-libuv/atomic_pointer_win.h +48 -0
  431. package/node_modules/classic-level/deps/leveldb/port-libuv/env_win.cc +692 -0
  432. package/node_modules/classic-level/deps/leveldb/port-libuv/port_uv.cc +36 -0
  433. package/node_modules/classic-level/deps/leveldb/port-libuv/port_uv.h +157 -0
  434. package/node_modules/classic-level/deps/leveldb/port-libuv/port_uv.h.bak +153 -0
  435. package/node_modules/classic-level/deps/leveldb/port-libuv/stdint-msvc2008.h +247 -0
  436. package/node_modules/classic-level/deps/leveldb/port-libuv/uv_condvar.h +45 -0
  437. package/node_modules/classic-level/deps/leveldb/port-libuv/uv_condvar_posix.cc +139 -0
  438. package/node_modules/classic-level/deps/leveldb/port-libuv/win_logger.cc +79 -0
  439. package/node_modules/classic-level/deps/leveldb/port-libuv/win_logger.h +28 -0
  440. package/node_modules/classic-level/deps/snappy/freebsd/config.h +135 -0
  441. package/node_modules/classic-level/deps/snappy/freebsd/snappy-stubs-public.h +100 -0
  442. package/node_modules/classic-level/deps/snappy/linux/config.h +135 -0
  443. package/node_modules/classic-level/deps/snappy/linux/snappy-stubs-public.h +100 -0
  444. package/node_modules/classic-level/deps/snappy/mac/config.h +137 -0
  445. package/node_modules/classic-level/deps/snappy/mac/snappy-stubs-public.h +100 -0
  446. package/node_modules/classic-level/deps/snappy/openbsd/config.h +135 -0
  447. package/node_modules/classic-level/deps/snappy/openbsd/snappy-stubs-public.h +100 -0
  448. package/node_modules/classic-level/deps/snappy/snappy/COPYING +54 -0
  449. package/node_modules/classic-level/deps/snappy/snappy/cmake/SnappyConfig.cmake +1 -0
  450. package/node_modules/classic-level/deps/snappy/snappy/cmake/config.h.in +62 -0
  451. package/node_modules/classic-level/deps/snappy/snappy/snappy-c.cc +90 -0
  452. package/node_modules/classic-level/deps/snappy/snappy/snappy-c.h +138 -0
  453. package/node_modules/classic-level/deps/snappy/snappy/snappy-internal.h +224 -0
  454. package/node_modules/classic-level/deps/snappy/snappy/snappy-sinksource.cc +104 -0
  455. package/node_modules/classic-level/deps/snappy/snappy/snappy-sinksource.h +182 -0
  456. package/node_modules/classic-level/deps/snappy/snappy/snappy-stubs-internal.cc +42 -0
  457. package/node_modules/classic-level/deps/snappy/snappy/snappy-stubs-internal.h +561 -0
  458. package/node_modules/classic-level/deps/snappy/snappy/snappy-stubs-public.h.in +94 -0
  459. package/node_modules/classic-level/deps/snappy/snappy/snappy-test.cc +612 -0
  460. package/node_modules/classic-level/deps/snappy/snappy/snappy-test.h +573 -0
  461. package/node_modules/classic-level/deps/snappy/snappy/snappy.cc +1515 -0
  462. package/node_modules/classic-level/deps/snappy/snappy/snappy.h +203 -0
  463. package/node_modules/classic-level/deps/snappy/snappy/snappy_unittest.cc +1410 -0
  464. package/node_modules/classic-level/deps/snappy/snappy.gyp +119 -0
  465. package/node_modules/classic-level/deps/snappy/solaris/config.h +135 -0
  466. package/node_modules/classic-level/deps/snappy/solaris/snappy-stubs-public.h +100 -0
  467. package/node_modules/classic-level/deps/snappy/win32/config.h +29 -0
  468. package/node_modules/classic-level/deps/snappy/win32/snappy-stubs-public.h +100 -0
  469. package/node_modules/classic-level/index.d.ts +343 -0
  470. package/node_modules/classic-level/index.js +311 -0
  471. package/node_modules/classic-level/iterator.js +122 -0
  472. package/node_modules/classic-level/package.json +70 -0
  473. package/node_modules/classic-level/prebuilds/android-arm/classic-level.armv7.node +0 -0
  474. package/node_modules/classic-level/prebuilds/android-arm64/classic-level.armv8.node +0 -0
  475. package/node_modules/classic-level/prebuilds/darwin-x64+arm64/classic-level.node +0 -0
  476. package/node_modules/classic-level/prebuilds/linux-arm/classic-level.armv6.node +0 -0
  477. package/node_modules/classic-level/prebuilds/linux-arm/classic-level.armv7.node +0 -0
  478. package/node_modules/classic-level/prebuilds/linux-arm64/classic-level.armv8.node +0 -0
  479. package/node_modules/classic-level/prebuilds/linux-x64/classic-level.musl.node +0 -0
  480. package/node_modules/classic-level/prebuilds/linux-x64/classic-level.node +0 -0
  481. package/node_modules/classic-level/prebuilds/win32-ia32/classic-level.node +0 -0
  482. package/node_modules/classic-level/prebuilds/win32-x64/classic-level.node +0 -0
  483. package/node_modules/ieee754/LICENSE +11 -0
  484. package/node_modules/ieee754/README.md +51 -0
  485. package/node_modules/ieee754/index.d.ts +10 -0
  486. package/node_modules/ieee754/index.js +85 -0
  487. package/node_modules/ieee754/package.json +52 -0
  488. package/node_modules/is-buffer/LICENSE +21 -0
  489. package/node_modules/is-buffer/README.md +54 -0
  490. package/node_modules/is-buffer/index.d.ts +2 -0
  491. package/node_modules/is-buffer/index.js +11 -0
  492. package/node_modules/is-buffer/package.json +65 -0
  493. package/node_modules/level/CHANGELOG.md +532 -0
  494. package/node_modules/level/LICENSE +21 -0
  495. package/node_modules/level/README.md +107 -0
  496. package/node_modules/level/UPGRADING.md +413 -0
  497. package/node_modules/level/browser.js +1 -0
  498. package/node_modules/level/index.d.ts +75 -0
  499. package/node_modules/level/index.js +1 -0
  500. package/node_modules/level/package.json +62 -0
  501. package/node_modules/level-supports/CHANGELOG.md +140 -0
  502. package/node_modules/level-supports/LICENSE +21 -0
  503. package/node_modules/level-supports/README.md +276 -0
  504. package/node_modules/level-supports/index.d.ts +137 -0
  505. package/node_modules/level-supports/index.js +26 -0
  506. package/node_modules/level-supports/package.json +46 -0
  507. package/node_modules/level-supports/test/cloneable.js +26 -0
  508. package/node_modules/level-supports/test/index.js +24 -0
  509. package/node_modules/level-supports/test/self.js +86 -0
  510. package/node_modules/level-supports/test/shape.js +23 -0
  511. package/node_modules/level-transcoder/CHANGELOG.md +15 -0
  512. package/node_modules/level-transcoder/LICENSE +21 -0
  513. package/node_modules/level-transcoder/README.md +214 -0
  514. package/node_modules/level-transcoder/UPGRADING.md +13 -0
  515. package/node_modules/level-transcoder/index.d.ts +27 -0
  516. package/node_modules/level-transcoder/index.js +158 -0
  517. package/node_modules/level-transcoder/lib/encoding.d.ts +158 -0
  518. package/node_modules/level-transcoder/lib/encoding.js +105 -0
  519. package/node_modules/level-transcoder/lib/encodings.d.ts +9 -0
  520. package/node_modules/level-transcoder/lib/encodings.js +135 -0
  521. package/node_modules/level-transcoder/lib/formats.d.ts +13 -0
  522. package/node_modules/level-transcoder/lib/formats.js +111 -0
  523. package/node_modules/level-transcoder/lib/text-endec.d.ts +6 -0
  524. package/node_modules/level-transcoder/lib/text-endec.js +19 -0
  525. package/node_modules/level-transcoder/package.json +46 -0
  526. package/node_modules/maybe-combine-errors/LICENSE.md +21 -0
  527. package/node_modules/maybe-combine-errors/README.md +94 -0
  528. package/node_modules/maybe-combine-errors/index.js +60 -0
  529. package/node_modules/maybe-combine-errors/package.json +33 -0
  530. package/node_modules/module-error/CHANGELOG.md +23 -0
  531. package/node_modules/module-error/LICENSE +21 -0
  532. package/node_modules/module-error/README.md +89 -0
  533. package/node_modules/module-error/index.d.ts +18 -0
  534. package/node_modules/module-error/index.js +22 -0
  535. package/node_modules/module-error/package.json +36 -0
  536. package/node_modules/napi-macros/LICENSE +21 -0
  537. package/node_modules/napi-macros/README.md +277 -0
  538. package/node_modules/napi-macros/index.js +1 -0
  539. package/node_modules/napi-macros/napi-macros.h +255 -0
  540. package/node_modules/napi-macros/package.json +22 -0
  541. package/node_modules/node-gyp-build/LICENSE +21 -0
  542. package/node_modules/node-gyp-build/README.md +58 -0
  543. package/node_modules/node-gyp-build/SECURITY.md +5 -0
  544. package/node_modules/node-gyp-build/bin.js +84 -0
  545. package/node_modules/node-gyp-build/build-test.js +19 -0
  546. package/node_modules/node-gyp-build/index.js +6 -0
  547. package/node_modules/node-gyp-build/node-gyp-build.js +207 -0
  548. package/node_modules/node-gyp-build/optional.js +7 -0
  549. package/node_modules/node-gyp-build/package.json +43 -0
  550. package/oauthTokenStore-PADKLNOC.js +23 -0
  551. package/package.json +6 -3
  552. package/processSpawn-SOAV3FEV.js +11 -0
  553. package/profileConfig-ZGOFORWV.js +43 -0
  554. package/{providerPresetApply-XI3WUPTI.js → providerPresetApply-HIPK67DU.js} +9 -9
  555. package/{providerRegistry-KEPWWGXD.js → providerRegistry-AI4U2FNM.js} +13 -9
  556. package/{read-COE3ZYR6.js → read-RNUQ7F34.js} +11 -7
  557. package/{readDocTool-5USN4A6V.js → readDocTool-6WIZHE6O.js} +5 -3
  558. package/{readlineWorkspace-KIMUDPPV.js → readlineWorkspace-P3I7ZJUP.js} +6947 -3879
  559. package/{removeDialogAgentAction-J6X5QMTA.js → removeDialogAgentAction-EFQ4O2IQ.js} +27 -26
  560. package/{runAgentClientLoop-AN4WIRPQ.js → runAgentClientLoop-AYNL3KMJ.js} +150 -90
  561. package/{runtimeDoctorCommands-X6WDBEQX.js → runtimeDoctorCommands-5CIWJEZ3.js} +36 -8
  562. package/runtimeModeArgs-2Y7BALTO.js +31 -0
  563. package/setDialogExtraReferencesAction-MXAH2KPV.js +37 -0
  564. package/{setPrimaryDialogAgentAction-FN22THHT.js → setPrimaryDialogAgentAction-7OPVNK4M.js} +28 -27
  565. package/{chunk-GP5LKBUZ.js → settingThunks-GHVLHABJ.js} +240 -945
  566. package/{skillDiscovery-CYUCJMAG.js → skillDiscovery-QC35EQY4.js} +3 -3
  567. package/{slateUtils-RIZES3PV.js → slateUtils-NGV2NMKM.js} +1 -1
  568. package/{spaceCommands-NA4JMIGT.js → spaceCommands-WZCLRGBO.js} +56 -56
  569. package/{streamAgentChatTurn-3TYTHZPJ.js → streamAgentChatTurn-O5T3B4B3.js} +325 -1557
  570. package/{switchDialogAgentAction-LVTEV3FR.js → switchDialogAgentAction-4PANDG3L.js} +24 -20
  571. package/{tableCommands-O6NWHFKV.js → tableCommands-U3QDY4L6.js} +19 -17
  572. package/{toolApiClient-QVJ6HDNN.js → toolApiClient-54CXTU7C.js} +5 -4
  573. package/tools-UMU2DYQX.js +122 -0
  574. package/{tuiSummaryLlmCaller-UFGFOIIW.js → tuiSummaryLlmCaller-ISODIW2O.js} +14 -29
  575. package/{updateCommands-2M74UL7P.js → updateCommands-NQXAGFM7.js} +3 -3
  576. package/{updateDialogTitleAction-RDHNT265.js → updateDialogTitleAction-TIS2SETN.js} +101 -57
  577. package/action-P4TNFGAD.js +0 -31
  578. package/agentListCommands-NXCOTTZL.js +0 -411
  579. package/agentRecordCommands-JP54ZWND.js +0 -129
  580. package/agentRunCommand-RMQWWSHF.js +0 -157
  581. package/browser-image-compression-MFDTD7K6.js +0 -1763
  582. package/chatQueueReduxAdapter-DKLWTT3G.js +0 -186
  583. package/chunk-ACTMNVHM.js +0 -93
  584. package/chunk-CQ3WA2NE.js +0 -299
  585. package/chunk-M76ECQRD.js +0 -13658
  586. package/chunk-MEYIRKDN.js +0 -8967
  587. package/chunk-N4G4PKQ6.js +0 -23
  588. package/chunk-P3GYTNDF.js +0 -34
  589. package/chunk-PUOC4YRO.js +0 -394
  590. package/chunk-S7Z2HMCN.js +0 -25
  591. package/chunk-Y5GCAMGP.js +0 -9
  592. package/chunk-YPREESF4.js +0 -225
  593. package/chunk-YWIEQS6H.js +0 -21409
  594. package/contentThunks-JHK6X2KU.js +0 -73
  595. package/createDialogAction-VUUUZL54.js +0 -65
  596. package/dialogCommands-EN7TYD3I.js +0 -100
  597. package/handleSendMessageAction-ID5IKXUE.js +0 -633
  598. package/machineWsRunDispatch-RX64L3ET.js +0 -145
  599. package/setDialogExtraReferencesAction-WX5VTY6O.js +0 -30
  600. package/settingSlice-P4ZW7K5X.js +0 -204
  601. package/syncMapping-N6RGXGBW.js +0 -437
  602. package/tools-34SEJSLQ.js +0 -110
  603. package/{chunk-SV5IJK6K.js → chunk-NBTY7YJF.js} +3 -3
  604. package/{chunk-X7HHHIOZ.js → chunk-Y6ROFCZO.js} +0 -0
  605. package/{db-WK5MDZVN.js → db-VQSAOWAO.js} +1 -1
  606. package/{offlineMarxistsAgentCommand-HGXZV4XJ.js → offlineMarxistsAgentCommand-2QTHJCHV.js} +4 -4
@@ -0,0 +1,2158 @@
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
+
5
+ #include "leveldb/db.h"
6
+ #include "leveldb/filter_policy.h"
7
+ #include "db/db_impl.h"
8
+ #include "db/filename.h"
9
+ #include "db/version_set.h"
10
+ #include "db/write_batch_internal.h"
11
+ #include "leveldb/cache.h"
12
+ #include "leveldb/env.h"
13
+ #include "leveldb/table.h"
14
+ #include "util/hash.h"
15
+ #include "util/logging.h"
16
+ #include "util/mutexlock.h"
17
+ #include "util/testharness.h"
18
+ #include "util/testutil.h"
19
+
20
+ namespace leveldb {
21
+
22
+ static std::string RandomString(Random* rnd, int len) {
23
+ std::string r;
24
+ test::RandomString(rnd, len, &r);
25
+ return r;
26
+ }
27
+
28
+ namespace {
29
+ class AtomicCounter {
30
+ private:
31
+ port::Mutex mu_;
32
+ int count_;
33
+ public:
34
+ AtomicCounter() : count_(0) { }
35
+ void Increment() {
36
+ IncrementBy(1);
37
+ }
38
+ void IncrementBy(int count) {
39
+ MutexLock l(&mu_);
40
+ count_ += count;
41
+ }
42
+ int Read() {
43
+ MutexLock l(&mu_);
44
+ return count_;
45
+ }
46
+ void Reset() {
47
+ MutexLock l(&mu_);
48
+ count_ = 0;
49
+ }
50
+ };
51
+
52
+ void DelayMilliseconds(int millis) {
53
+ Env::Default()->SleepForMicroseconds(millis * 1000);
54
+ }
55
+ }
56
+
57
+ // Special Env used to delay background operations
58
+ class SpecialEnv : public EnvWrapper {
59
+ public:
60
+ // sstable/log Sync() calls are blocked while this pointer is non-NULL.
61
+ port::AtomicPointer delay_data_sync_;
62
+
63
+ // sstable/log Sync() calls return an error.
64
+ port::AtomicPointer data_sync_error_;
65
+
66
+ // Simulate no-space errors while this pointer is non-NULL.
67
+ port::AtomicPointer no_space_;
68
+
69
+ // Simulate non-writable file system while this pointer is non-NULL
70
+ port::AtomicPointer non_writable_;
71
+
72
+ // Force sync of manifest files to fail while this pointer is non-NULL
73
+ port::AtomicPointer manifest_sync_error_;
74
+
75
+ // Force write to manifest files to fail while this pointer is non-NULL
76
+ port::AtomicPointer manifest_write_error_;
77
+
78
+ bool count_random_reads_;
79
+ AtomicCounter random_read_counter_;
80
+
81
+ explicit SpecialEnv(Env* base) : EnvWrapper(base) {
82
+ delay_data_sync_.Release_Store(NULL);
83
+ data_sync_error_.Release_Store(NULL);
84
+ no_space_.Release_Store(NULL);
85
+ non_writable_.Release_Store(NULL);
86
+ count_random_reads_ = false;
87
+ manifest_sync_error_.Release_Store(NULL);
88
+ manifest_write_error_.Release_Store(NULL);
89
+ }
90
+
91
+ Status NewWritableFile(const std::string& f, WritableFile** r) {
92
+ class DataFile : public WritableFile {
93
+ private:
94
+ SpecialEnv* env_;
95
+ WritableFile* base_;
96
+
97
+ public:
98
+ DataFile(SpecialEnv* env, WritableFile* base)
99
+ : env_(env),
100
+ base_(base) {
101
+ }
102
+ ~DataFile() { delete base_; }
103
+ Status Append(const Slice& data) {
104
+ if (env_->no_space_.Acquire_Load() != NULL) {
105
+ // Drop writes on the floor
106
+ return Status::OK();
107
+ } else {
108
+ return base_->Append(data);
109
+ }
110
+ }
111
+ Status Close() { return base_->Close(); }
112
+ Status Flush() { return base_->Flush(); }
113
+ Status Sync() {
114
+ if (env_->data_sync_error_.Acquire_Load() != NULL) {
115
+ return Status::IOError("simulated data sync error");
116
+ }
117
+ while (env_->delay_data_sync_.Acquire_Load() != NULL) {
118
+ DelayMilliseconds(100);
119
+ }
120
+ return base_->Sync();
121
+ }
122
+ };
123
+ class ManifestFile : public WritableFile {
124
+ private:
125
+ SpecialEnv* env_;
126
+ WritableFile* base_;
127
+ public:
128
+ ManifestFile(SpecialEnv* env, WritableFile* b) : env_(env), base_(b) { }
129
+ ~ManifestFile() { delete base_; }
130
+ Status Append(const Slice& data) {
131
+ if (env_->manifest_write_error_.Acquire_Load() != NULL) {
132
+ return Status::IOError("simulated writer error");
133
+ } else {
134
+ return base_->Append(data);
135
+ }
136
+ }
137
+ Status Close() { return base_->Close(); }
138
+ Status Flush() { return base_->Flush(); }
139
+ Status Sync() {
140
+ if (env_->manifest_sync_error_.Acquire_Load() != NULL) {
141
+ return Status::IOError("simulated sync error");
142
+ } else {
143
+ return base_->Sync();
144
+ }
145
+ }
146
+ };
147
+
148
+ if (non_writable_.Acquire_Load() != NULL) {
149
+ return Status::IOError("simulated write error");
150
+ }
151
+
152
+ Status s = target()->NewWritableFile(f, r);
153
+ if (s.ok()) {
154
+ if (strstr(f.c_str(), ".ldb") != NULL ||
155
+ strstr(f.c_str(), ".log") != NULL) {
156
+ *r = new DataFile(this, *r);
157
+ } else if (strstr(f.c_str(), "MANIFEST") != NULL) {
158
+ *r = new ManifestFile(this, *r);
159
+ }
160
+ }
161
+ return s;
162
+ }
163
+
164
+ Status NewRandomAccessFile(const std::string& f, RandomAccessFile** r) {
165
+ class CountingFile : public RandomAccessFile {
166
+ private:
167
+ RandomAccessFile* target_;
168
+ AtomicCounter* counter_;
169
+ public:
170
+ CountingFile(RandomAccessFile* target, AtomicCounter* counter)
171
+ : target_(target), counter_(counter) {
172
+ }
173
+ virtual ~CountingFile() { delete target_; }
174
+ virtual Status Read(uint64_t offset, size_t n, Slice* result,
175
+ char* scratch) const {
176
+ counter_->Increment();
177
+ return target_->Read(offset, n, result, scratch);
178
+ }
179
+ };
180
+
181
+ Status s = target()->NewRandomAccessFile(f, r);
182
+ if (s.ok() && count_random_reads_) {
183
+ *r = new CountingFile(*r, &random_read_counter_);
184
+ }
185
+ return s;
186
+ }
187
+ };
188
+
189
+ class DBTest {
190
+ private:
191
+ const FilterPolicy* filter_policy_;
192
+
193
+ // Sequence of option configurations to try
194
+ enum OptionConfig {
195
+ kDefault,
196
+ kReuse,
197
+ kFilter,
198
+ kUncompressed,
199
+ kEnd
200
+ };
201
+ int option_config_;
202
+
203
+ public:
204
+ std::string dbname_;
205
+ SpecialEnv* env_;
206
+ DB* db_;
207
+
208
+ Options last_options_;
209
+
210
+ DBTest() : option_config_(kDefault),
211
+ env_(new SpecialEnv(Env::Default())) {
212
+ filter_policy_ = NewBloomFilterPolicy(10);
213
+ dbname_ = test::TmpDir() + "/db_test";
214
+ DestroyDB(dbname_, Options());
215
+ db_ = NULL;
216
+ Reopen();
217
+ }
218
+
219
+ ~DBTest() {
220
+ delete db_;
221
+ DestroyDB(dbname_, Options());
222
+ delete env_;
223
+ delete filter_policy_;
224
+ }
225
+
226
+ // Switch to a fresh database with the next option configuration to
227
+ // test. Return false if there are no more configurations to test.
228
+ bool ChangeOptions() {
229
+ option_config_++;
230
+ if (option_config_ >= kEnd) {
231
+ return false;
232
+ } else {
233
+ DestroyAndReopen();
234
+ return true;
235
+ }
236
+ }
237
+
238
+ // Return the current option configuration.
239
+ Options CurrentOptions() {
240
+ Options options;
241
+ options.reuse_logs = false;
242
+ switch (option_config_) {
243
+ case kReuse:
244
+ options.reuse_logs = true;
245
+ break;
246
+ case kFilter:
247
+ options.filter_policy = filter_policy_;
248
+ break;
249
+ case kUncompressed:
250
+ options.compression = kNoCompression;
251
+ break;
252
+ default:
253
+ break;
254
+ }
255
+ return options;
256
+ }
257
+
258
+ DBImpl* dbfull() {
259
+ return reinterpret_cast<DBImpl*>(db_);
260
+ }
261
+
262
+ void Reopen(Options* options = NULL) {
263
+ ASSERT_OK(TryReopen(options));
264
+ }
265
+
266
+ void Close() {
267
+ delete db_;
268
+ db_ = NULL;
269
+ }
270
+
271
+ void DestroyAndReopen(Options* options = NULL) {
272
+ delete db_;
273
+ db_ = NULL;
274
+ DestroyDB(dbname_, Options());
275
+ ASSERT_OK(TryReopen(options));
276
+ }
277
+
278
+ Status TryReopen(Options* options) {
279
+ delete db_;
280
+ db_ = NULL;
281
+ Options opts;
282
+ if (options != NULL) {
283
+ opts = *options;
284
+ } else {
285
+ opts = CurrentOptions();
286
+ opts.create_if_missing = true;
287
+ }
288
+ last_options_ = opts;
289
+
290
+ return DB::Open(opts, dbname_, &db_);
291
+ }
292
+
293
+ Status Put(const std::string& k, const std::string& v) {
294
+ return db_->Put(WriteOptions(), k, v);
295
+ }
296
+
297
+ Status Delete(const std::string& k) {
298
+ return db_->Delete(WriteOptions(), k);
299
+ }
300
+
301
+ std::string Get(const std::string& k, const Snapshot* snapshot = NULL) {
302
+ ReadOptions options;
303
+ options.snapshot = snapshot;
304
+ std::string result;
305
+ Status s = db_->Get(options, k, &result);
306
+ if (s.IsNotFound()) {
307
+ result = "NOT_FOUND";
308
+ } else if (!s.ok()) {
309
+ result = s.ToString();
310
+ }
311
+ return result;
312
+ }
313
+
314
+ // Return a string that contains all key,value pairs in order,
315
+ // formatted like "(k1->v1)(k2->v2)".
316
+ std::string Contents() {
317
+ std::vector<std::string> forward;
318
+ std::string result;
319
+ Iterator* iter = db_->NewIterator(ReadOptions());
320
+ for (iter->SeekToFirst(); iter->Valid(); iter->Next()) {
321
+ std::string s = IterStatus(iter);
322
+ result.push_back('(');
323
+ result.append(s);
324
+ result.push_back(')');
325
+ forward.push_back(s);
326
+ }
327
+
328
+ // Check reverse iteration results are the reverse of forward results
329
+ size_t matched = 0;
330
+ for (iter->SeekToLast(); iter->Valid(); iter->Prev()) {
331
+ ASSERT_LT(matched, forward.size());
332
+ ASSERT_EQ(IterStatus(iter), forward[forward.size() - matched - 1]);
333
+ matched++;
334
+ }
335
+ ASSERT_EQ(matched, forward.size());
336
+
337
+ delete iter;
338
+ return result;
339
+ }
340
+
341
+ std::string AllEntriesFor(const Slice& user_key) {
342
+ Iterator* iter = dbfull()->TEST_NewInternalIterator();
343
+ InternalKey target(user_key, kMaxSequenceNumber, kTypeValue);
344
+ iter->Seek(target.Encode());
345
+ std::string result;
346
+ if (!iter->status().ok()) {
347
+ result = iter->status().ToString();
348
+ } else {
349
+ result = "[ ";
350
+ bool first = true;
351
+ while (iter->Valid()) {
352
+ ParsedInternalKey ikey;
353
+ if (!ParseInternalKey(iter->key(), &ikey)) {
354
+ result += "CORRUPTED";
355
+ } else {
356
+ if (last_options_.comparator->Compare(ikey.user_key, user_key) != 0) {
357
+ break;
358
+ }
359
+ if (!first) {
360
+ result += ", ";
361
+ }
362
+ first = false;
363
+ switch (ikey.type) {
364
+ case kTypeValue:
365
+ result += iter->value().ToString();
366
+ break;
367
+ case kTypeDeletion:
368
+ result += "DEL";
369
+ break;
370
+ }
371
+ }
372
+ iter->Next();
373
+ }
374
+ if (!first) {
375
+ result += " ";
376
+ }
377
+ result += "]";
378
+ }
379
+ delete iter;
380
+ return result;
381
+ }
382
+
383
+ int NumTableFilesAtLevel(int level) {
384
+ std::string property;
385
+ ASSERT_TRUE(
386
+ db_->GetProperty("leveldb.num-files-at-level" + NumberToString(level),
387
+ &property));
388
+ return atoi(property.c_str());
389
+ }
390
+
391
+ int TotalTableFiles() {
392
+ int result = 0;
393
+ for (int level = 0; level < config::kNumLevels; level++) {
394
+ result += NumTableFilesAtLevel(level);
395
+ }
396
+ return result;
397
+ }
398
+
399
+ // Return spread of files per level
400
+ std::string FilesPerLevel() {
401
+ std::string result;
402
+ int last_non_zero_offset = 0;
403
+ for (int level = 0; level < config::kNumLevels; level++) {
404
+ int f = NumTableFilesAtLevel(level);
405
+ char buf[100];
406
+ snprintf(buf, sizeof(buf), "%s%d", (level ? "," : ""), f);
407
+ result += buf;
408
+ if (f > 0) {
409
+ last_non_zero_offset = result.size();
410
+ }
411
+ }
412
+ result.resize(last_non_zero_offset);
413
+ return result;
414
+ }
415
+
416
+ int CountFiles() {
417
+ std::vector<std::string> files;
418
+ env_->GetChildren(dbname_, &files);
419
+ return static_cast<int>(files.size());
420
+ }
421
+
422
+ uint64_t Size(const Slice& start, const Slice& limit) {
423
+ Range r(start, limit);
424
+ uint64_t size;
425
+ db_->GetApproximateSizes(&r, 1, &size);
426
+ return size;
427
+ }
428
+
429
+ void Compact(const Slice& start, const Slice& limit) {
430
+ db_->CompactRange(&start, &limit);
431
+ }
432
+
433
+ // Do n memtable compactions, each of which produces an sstable
434
+ // covering the range [small,large].
435
+ void MakeTables(int n, const std::string& small, const std::string& large) {
436
+ for (int i = 0; i < n; i++) {
437
+ Put(small, "begin");
438
+ Put(large, "end");
439
+ dbfull()->TEST_CompactMemTable();
440
+ }
441
+ }
442
+
443
+ // Prevent pushing of new sstables into deeper levels by adding
444
+ // tables that cover a specified range to all levels.
445
+ void FillLevels(const std::string& smallest, const std::string& largest) {
446
+ MakeTables(config::kNumLevels, smallest, largest);
447
+ }
448
+
449
+ void DumpFileCounts(const char* label) {
450
+ fprintf(stderr, "---\n%s:\n", label);
451
+ fprintf(stderr, "maxoverlap: %lld\n",
452
+ static_cast<long long>(
453
+ dbfull()->TEST_MaxNextLevelOverlappingBytes()));
454
+ for (int level = 0; level < config::kNumLevels; level++) {
455
+ int num = NumTableFilesAtLevel(level);
456
+ if (num > 0) {
457
+ fprintf(stderr, " level %3d : %d files\n", level, num);
458
+ }
459
+ }
460
+ }
461
+
462
+ std::string DumpSSTableList() {
463
+ std::string property;
464
+ db_->GetProperty("leveldb.sstables", &property);
465
+ return property;
466
+ }
467
+
468
+ std::string IterStatus(Iterator* iter) {
469
+ std::string result;
470
+ if (iter->Valid()) {
471
+ result = iter->key().ToString() + "->" + iter->value().ToString();
472
+ } else {
473
+ result = "(invalid)";
474
+ }
475
+ return result;
476
+ }
477
+
478
+ bool DeleteAnSSTFile() {
479
+ std::vector<std::string> filenames;
480
+ ASSERT_OK(env_->GetChildren(dbname_, &filenames));
481
+ uint64_t number;
482
+ FileType type;
483
+ for (size_t i = 0; i < filenames.size(); i++) {
484
+ if (ParseFileName(filenames[i], &number, &type) && type == kTableFile) {
485
+ ASSERT_OK(env_->DeleteFile(TableFileName(dbname_, number)));
486
+ return true;
487
+ }
488
+ }
489
+ return false;
490
+ }
491
+
492
+ // Returns number of files renamed.
493
+ int RenameLDBToSST() {
494
+ std::vector<std::string> filenames;
495
+ ASSERT_OK(env_->GetChildren(dbname_, &filenames));
496
+ uint64_t number;
497
+ FileType type;
498
+ int files_renamed = 0;
499
+ for (size_t i = 0; i < filenames.size(); i++) {
500
+ if (ParseFileName(filenames[i], &number, &type) && type == kTableFile) {
501
+ const std::string from = TableFileName(dbname_, number);
502
+ const std::string to = SSTTableFileName(dbname_, number);
503
+ ASSERT_OK(env_->RenameFile(from, to));
504
+ files_renamed++;
505
+ }
506
+ }
507
+ return files_renamed;
508
+ }
509
+ };
510
+
511
+ TEST(DBTest, Empty) {
512
+ do {
513
+ ASSERT_TRUE(db_ != NULL);
514
+ ASSERT_EQ("NOT_FOUND", Get("foo"));
515
+ } while (ChangeOptions());
516
+ }
517
+
518
+ TEST(DBTest, ReadWrite) {
519
+ do {
520
+ ASSERT_OK(Put("foo", "v1"));
521
+ ASSERT_EQ("v1", Get("foo"));
522
+ ASSERT_OK(Put("bar", "v2"));
523
+ ASSERT_OK(Put("foo", "v3"));
524
+ ASSERT_EQ("v3", Get("foo"));
525
+ ASSERT_EQ("v2", Get("bar"));
526
+ } while (ChangeOptions());
527
+ }
528
+
529
+ TEST(DBTest, PutDeleteGet) {
530
+ do {
531
+ ASSERT_OK(db_->Put(WriteOptions(), "foo", "v1"));
532
+ ASSERT_EQ("v1", Get("foo"));
533
+ ASSERT_OK(db_->Put(WriteOptions(), "foo", "v2"));
534
+ ASSERT_EQ("v2", Get("foo"));
535
+ ASSERT_OK(db_->Delete(WriteOptions(), "foo"));
536
+ ASSERT_EQ("NOT_FOUND", Get("foo"));
537
+ } while (ChangeOptions());
538
+ }
539
+
540
+ TEST(DBTest, GetFromImmutableLayer) {
541
+ do {
542
+ Options options = CurrentOptions();
543
+ options.env = env_;
544
+ options.write_buffer_size = 100000; // Small write buffer
545
+ Reopen(&options);
546
+
547
+ ASSERT_OK(Put("foo", "v1"));
548
+ ASSERT_EQ("v1", Get("foo"));
549
+
550
+ env_->delay_data_sync_.Release_Store(env_); // Block sync calls
551
+ Put("k1", std::string(100000, 'x')); // Fill memtable
552
+ Put("k2", std::string(100000, 'y')); // Trigger compaction
553
+ ASSERT_EQ("v1", Get("foo"));
554
+ env_->delay_data_sync_.Release_Store(NULL); // Release sync calls
555
+ } while (ChangeOptions());
556
+ }
557
+
558
+ TEST(DBTest, GetFromVersions) {
559
+ do {
560
+ ASSERT_OK(Put("foo", "v1"));
561
+ dbfull()->TEST_CompactMemTable();
562
+ ASSERT_EQ("v1", Get("foo"));
563
+ } while (ChangeOptions());
564
+ }
565
+
566
+ TEST(DBTest, GetMemUsage) {
567
+ do {
568
+ ASSERT_OK(Put("foo", "v1"));
569
+ std::string val;
570
+ ASSERT_TRUE(db_->GetProperty("leveldb.approximate-memory-usage", &val));
571
+ int mem_usage = atoi(val.c_str());
572
+ ASSERT_GT(mem_usage, 0);
573
+ ASSERT_LT(mem_usage, 5*1024*1024);
574
+ } while (ChangeOptions());
575
+ }
576
+
577
+ TEST(DBTest, GetSnapshot) {
578
+ do {
579
+ // Try with both a short key and a long key
580
+ for (int i = 0; i < 2; i++) {
581
+ std::string key = (i == 0) ? std::string("foo") : std::string(200, 'x');
582
+ ASSERT_OK(Put(key, "v1"));
583
+ const Snapshot* s1 = db_->GetSnapshot();
584
+ ASSERT_OK(Put(key, "v2"));
585
+ ASSERT_EQ("v2", Get(key));
586
+ ASSERT_EQ("v1", Get(key, s1));
587
+ dbfull()->TEST_CompactMemTable();
588
+ ASSERT_EQ("v2", Get(key));
589
+ ASSERT_EQ("v1", Get(key, s1));
590
+ db_->ReleaseSnapshot(s1);
591
+ }
592
+ } while (ChangeOptions());
593
+ }
594
+
595
+ TEST(DBTest, GetLevel0Ordering) {
596
+ do {
597
+ // Check that we process level-0 files in correct order. The code
598
+ // below generates two level-0 files where the earlier one comes
599
+ // before the later one in the level-0 file list since the earlier
600
+ // one has a smaller "smallest" key.
601
+ ASSERT_OK(Put("bar", "b"));
602
+ ASSERT_OK(Put("foo", "v1"));
603
+ dbfull()->TEST_CompactMemTable();
604
+ ASSERT_OK(Put("foo", "v2"));
605
+ dbfull()->TEST_CompactMemTable();
606
+ ASSERT_EQ("v2", Get("foo"));
607
+ } while (ChangeOptions());
608
+ }
609
+
610
+ TEST(DBTest, GetOrderedByLevels) {
611
+ do {
612
+ ASSERT_OK(Put("foo", "v1"));
613
+ Compact("a", "z");
614
+ ASSERT_EQ("v1", Get("foo"));
615
+ ASSERT_OK(Put("foo", "v2"));
616
+ ASSERT_EQ("v2", Get("foo"));
617
+ dbfull()->TEST_CompactMemTable();
618
+ ASSERT_EQ("v2", Get("foo"));
619
+ } while (ChangeOptions());
620
+ }
621
+
622
+ TEST(DBTest, GetPicksCorrectFile) {
623
+ do {
624
+ // Arrange to have multiple files in a non-level-0 level.
625
+ ASSERT_OK(Put("a", "va"));
626
+ Compact("a", "b");
627
+ ASSERT_OK(Put("x", "vx"));
628
+ Compact("x", "y");
629
+ ASSERT_OK(Put("f", "vf"));
630
+ Compact("f", "g");
631
+ ASSERT_EQ("va", Get("a"));
632
+ ASSERT_EQ("vf", Get("f"));
633
+ ASSERT_EQ("vx", Get("x"));
634
+ } while (ChangeOptions());
635
+ }
636
+
637
+ TEST(DBTest, GetEncountersEmptyLevel) {
638
+ do {
639
+ // Arrange for the following to happen:
640
+ // * sstable A in level 0
641
+ // * nothing in level 1
642
+ // * sstable B in level 2
643
+ // Then do enough Get() calls to arrange for an automatic compaction
644
+ // of sstable A. A bug would cause the compaction to be marked as
645
+ // occurring at level 1 (instead of the correct level 0).
646
+
647
+ // Step 1: First place sstables in levels 0 and 2
648
+ int compaction_count = 0;
649
+ while (NumTableFilesAtLevel(0) == 0 ||
650
+ NumTableFilesAtLevel(2) == 0) {
651
+ ASSERT_LE(compaction_count, 100) << "could not fill levels 0 and 2";
652
+ compaction_count++;
653
+ Put("a", "begin");
654
+ Put("z", "end");
655
+ dbfull()->TEST_CompactMemTable();
656
+ }
657
+
658
+ // Step 2: clear level 1 if necessary.
659
+ dbfull()->TEST_CompactRange(1, NULL, NULL);
660
+ ASSERT_EQ(NumTableFilesAtLevel(0), 1);
661
+ ASSERT_EQ(NumTableFilesAtLevel(1), 0);
662
+ ASSERT_EQ(NumTableFilesAtLevel(2), 1);
663
+
664
+ // Step 3: read a bunch of times
665
+ for (int i = 0; i < 1000; i++) {
666
+ ASSERT_EQ("NOT_FOUND", Get("missing"));
667
+ }
668
+
669
+ // Step 4: Wait for compaction to finish
670
+ DelayMilliseconds(1000);
671
+
672
+ ASSERT_EQ(NumTableFilesAtLevel(0), 0);
673
+ } while (ChangeOptions());
674
+ }
675
+
676
+ TEST(DBTest, IterEmpty) {
677
+ Iterator* iter = db_->NewIterator(ReadOptions());
678
+
679
+ iter->SeekToFirst();
680
+ ASSERT_EQ(IterStatus(iter), "(invalid)");
681
+
682
+ iter->SeekToLast();
683
+ ASSERT_EQ(IterStatus(iter), "(invalid)");
684
+
685
+ iter->Seek("foo");
686
+ ASSERT_EQ(IterStatus(iter), "(invalid)");
687
+
688
+ delete iter;
689
+ }
690
+
691
+ TEST(DBTest, IterSingle) {
692
+ ASSERT_OK(Put("a", "va"));
693
+ Iterator* iter = db_->NewIterator(ReadOptions());
694
+
695
+ iter->SeekToFirst();
696
+ ASSERT_EQ(IterStatus(iter), "a->va");
697
+ iter->Next();
698
+ ASSERT_EQ(IterStatus(iter), "(invalid)");
699
+ iter->SeekToFirst();
700
+ ASSERT_EQ(IterStatus(iter), "a->va");
701
+ iter->Prev();
702
+ ASSERT_EQ(IterStatus(iter), "(invalid)");
703
+
704
+ iter->SeekToLast();
705
+ ASSERT_EQ(IterStatus(iter), "a->va");
706
+ iter->Next();
707
+ ASSERT_EQ(IterStatus(iter), "(invalid)");
708
+ iter->SeekToLast();
709
+ ASSERT_EQ(IterStatus(iter), "a->va");
710
+ iter->Prev();
711
+ ASSERT_EQ(IterStatus(iter), "(invalid)");
712
+
713
+ iter->Seek("");
714
+ ASSERT_EQ(IterStatus(iter), "a->va");
715
+ iter->Next();
716
+ ASSERT_EQ(IterStatus(iter), "(invalid)");
717
+
718
+ iter->Seek("a");
719
+ ASSERT_EQ(IterStatus(iter), "a->va");
720
+ iter->Next();
721
+ ASSERT_EQ(IterStatus(iter), "(invalid)");
722
+
723
+ iter->Seek("b");
724
+ ASSERT_EQ(IterStatus(iter), "(invalid)");
725
+
726
+ delete iter;
727
+ }
728
+
729
+ TEST(DBTest, IterMulti) {
730
+ ASSERT_OK(Put("a", "va"));
731
+ ASSERT_OK(Put("b", "vb"));
732
+ ASSERT_OK(Put("c", "vc"));
733
+ Iterator* iter = db_->NewIterator(ReadOptions());
734
+
735
+ iter->SeekToFirst();
736
+ ASSERT_EQ(IterStatus(iter), "a->va");
737
+ iter->Next();
738
+ ASSERT_EQ(IterStatus(iter), "b->vb");
739
+ iter->Next();
740
+ ASSERT_EQ(IterStatus(iter), "c->vc");
741
+ iter->Next();
742
+ ASSERT_EQ(IterStatus(iter), "(invalid)");
743
+ iter->SeekToFirst();
744
+ ASSERT_EQ(IterStatus(iter), "a->va");
745
+ iter->Prev();
746
+ ASSERT_EQ(IterStatus(iter), "(invalid)");
747
+
748
+ iter->SeekToLast();
749
+ ASSERT_EQ(IterStatus(iter), "c->vc");
750
+ iter->Prev();
751
+ ASSERT_EQ(IterStatus(iter), "b->vb");
752
+ iter->Prev();
753
+ ASSERT_EQ(IterStatus(iter), "a->va");
754
+ iter->Prev();
755
+ ASSERT_EQ(IterStatus(iter), "(invalid)");
756
+ iter->SeekToLast();
757
+ ASSERT_EQ(IterStatus(iter), "c->vc");
758
+ iter->Next();
759
+ ASSERT_EQ(IterStatus(iter), "(invalid)");
760
+
761
+ iter->Seek("");
762
+ ASSERT_EQ(IterStatus(iter), "a->va");
763
+ iter->Seek("a");
764
+ ASSERT_EQ(IterStatus(iter), "a->va");
765
+ iter->Seek("ax");
766
+ ASSERT_EQ(IterStatus(iter), "b->vb");
767
+ iter->Seek("b");
768
+ ASSERT_EQ(IterStatus(iter), "b->vb");
769
+ iter->Seek("z");
770
+ ASSERT_EQ(IterStatus(iter), "(invalid)");
771
+
772
+ // Switch from reverse to forward
773
+ iter->SeekToLast();
774
+ iter->Prev();
775
+ iter->Prev();
776
+ iter->Next();
777
+ ASSERT_EQ(IterStatus(iter), "b->vb");
778
+
779
+ // Switch from forward to reverse
780
+ iter->SeekToFirst();
781
+ iter->Next();
782
+ iter->Next();
783
+ iter->Prev();
784
+ ASSERT_EQ(IterStatus(iter), "b->vb");
785
+
786
+ // Make sure iter stays at snapshot
787
+ ASSERT_OK(Put("a", "va2"));
788
+ ASSERT_OK(Put("a2", "va3"));
789
+ ASSERT_OK(Put("b", "vb2"));
790
+ ASSERT_OK(Put("c", "vc2"));
791
+ ASSERT_OK(Delete("b"));
792
+ iter->SeekToFirst();
793
+ ASSERT_EQ(IterStatus(iter), "a->va");
794
+ iter->Next();
795
+ ASSERT_EQ(IterStatus(iter), "b->vb");
796
+ iter->Next();
797
+ ASSERT_EQ(IterStatus(iter), "c->vc");
798
+ iter->Next();
799
+ ASSERT_EQ(IterStatus(iter), "(invalid)");
800
+ iter->SeekToLast();
801
+ ASSERT_EQ(IterStatus(iter), "c->vc");
802
+ iter->Prev();
803
+ ASSERT_EQ(IterStatus(iter), "b->vb");
804
+ iter->Prev();
805
+ ASSERT_EQ(IterStatus(iter), "a->va");
806
+ iter->Prev();
807
+ ASSERT_EQ(IterStatus(iter), "(invalid)");
808
+
809
+ delete iter;
810
+ }
811
+
812
+ TEST(DBTest, IterSmallAndLargeMix) {
813
+ ASSERT_OK(Put("a", "va"));
814
+ ASSERT_OK(Put("b", std::string(100000, 'b')));
815
+ ASSERT_OK(Put("c", "vc"));
816
+ ASSERT_OK(Put("d", std::string(100000, 'd')));
817
+ ASSERT_OK(Put("e", std::string(100000, 'e')));
818
+
819
+ Iterator* iter = db_->NewIterator(ReadOptions());
820
+
821
+ iter->SeekToFirst();
822
+ ASSERT_EQ(IterStatus(iter), "a->va");
823
+ iter->Next();
824
+ ASSERT_EQ(IterStatus(iter), "b->" + std::string(100000, 'b'));
825
+ iter->Next();
826
+ ASSERT_EQ(IterStatus(iter), "c->vc");
827
+ iter->Next();
828
+ ASSERT_EQ(IterStatus(iter), "d->" + std::string(100000, 'd'));
829
+ iter->Next();
830
+ ASSERT_EQ(IterStatus(iter), "e->" + std::string(100000, 'e'));
831
+ iter->Next();
832
+ ASSERT_EQ(IterStatus(iter), "(invalid)");
833
+
834
+ iter->SeekToLast();
835
+ ASSERT_EQ(IterStatus(iter), "e->" + std::string(100000, 'e'));
836
+ iter->Prev();
837
+ ASSERT_EQ(IterStatus(iter), "d->" + std::string(100000, 'd'));
838
+ iter->Prev();
839
+ ASSERT_EQ(IterStatus(iter), "c->vc");
840
+ iter->Prev();
841
+ ASSERT_EQ(IterStatus(iter), "b->" + std::string(100000, 'b'));
842
+ iter->Prev();
843
+ ASSERT_EQ(IterStatus(iter), "a->va");
844
+ iter->Prev();
845
+ ASSERT_EQ(IterStatus(iter), "(invalid)");
846
+
847
+ delete iter;
848
+ }
849
+
850
+ TEST(DBTest, IterMultiWithDelete) {
851
+ do {
852
+ ASSERT_OK(Put("a", "va"));
853
+ ASSERT_OK(Put("b", "vb"));
854
+ ASSERT_OK(Put("c", "vc"));
855
+ ASSERT_OK(Delete("b"));
856
+ ASSERT_EQ("NOT_FOUND", Get("b"));
857
+
858
+ Iterator* iter = db_->NewIterator(ReadOptions());
859
+ iter->Seek("c");
860
+ ASSERT_EQ(IterStatus(iter), "c->vc");
861
+ iter->Prev();
862
+ ASSERT_EQ(IterStatus(iter), "a->va");
863
+ delete iter;
864
+ } while (ChangeOptions());
865
+ }
866
+
867
+ TEST(DBTest, Recover) {
868
+ do {
869
+ ASSERT_OK(Put("foo", "v1"));
870
+ ASSERT_OK(Put("baz", "v5"));
871
+
872
+ Reopen();
873
+ ASSERT_EQ("v1", Get("foo"));
874
+
875
+ ASSERT_EQ("v1", Get("foo"));
876
+ ASSERT_EQ("v5", Get("baz"));
877
+ ASSERT_OK(Put("bar", "v2"));
878
+ ASSERT_OK(Put("foo", "v3"));
879
+
880
+ Reopen();
881
+ ASSERT_EQ("v3", Get("foo"));
882
+ ASSERT_OK(Put("foo", "v4"));
883
+ ASSERT_EQ("v4", Get("foo"));
884
+ ASSERT_EQ("v2", Get("bar"));
885
+ ASSERT_EQ("v5", Get("baz"));
886
+ } while (ChangeOptions());
887
+ }
888
+
889
+ TEST(DBTest, RecoveryWithEmptyLog) {
890
+ do {
891
+ ASSERT_OK(Put("foo", "v1"));
892
+ ASSERT_OK(Put("foo", "v2"));
893
+ Reopen();
894
+ Reopen();
895
+ ASSERT_OK(Put("foo", "v3"));
896
+ Reopen();
897
+ ASSERT_EQ("v3", Get("foo"));
898
+ } while (ChangeOptions());
899
+ }
900
+
901
+ // Check that writes done during a memtable compaction are recovered
902
+ // if the database is shutdown during the memtable compaction.
903
+ TEST(DBTest, RecoverDuringMemtableCompaction) {
904
+ do {
905
+ Options options = CurrentOptions();
906
+ options.env = env_;
907
+ options.write_buffer_size = 1000000;
908
+ Reopen(&options);
909
+
910
+ // Trigger a long memtable compaction and reopen the database during it
911
+ ASSERT_OK(Put("foo", "v1")); // Goes to 1st log file
912
+ ASSERT_OK(Put("big1", std::string(10000000, 'x'))); // Fills memtable
913
+ ASSERT_OK(Put("big2", std::string(1000, 'y'))); // Triggers compaction
914
+ ASSERT_OK(Put("bar", "v2")); // Goes to new log file
915
+
916
+ Reopen(&options);
917
+ ASSERT_EQ("v1", Get("foo"));
918
+ ASSERT_EQ("v2", Get("bar"));
919
+ ASSERT_EQ(std::string(10000000, 'x'), Get("big1"));
920
+ ASSERT_EQ(std::string(1000, 'y'), Get("big2"));
921
+ } while (ChangeOptions());
922
+ }
923
+
924
+ static std::string Key(int i) {
925
+ char buf[100];
926
+ snprintf(buf, sizeof(buf), "key%06d", i);
927
+ return std::string(buf);
928
+ }
929
+
930
+ TEST(DBTest, MinorCompactionsHappen) {
931
+ Options options = CurrentOptions();
932
+ options.write_buffer_size = 10000;
933
+ Reopen(&options);
934
+
935
+ const int N = 500;
936
+
937
+ int starting_num_tables = TotalTableFiles();
938
+ for (int i = 0; i < N; i++) {
939
+ ASSERT_OK(Put(Key(i), Key(i) + std::string(1000, 'v')));
940
+ }
941
+ int ending_num_tables = TotalTableFiles();
942
+ ASSERT_GT(ending_num_tables, starting_num_tables);
943
+
944
+ for (int i = 0; i < N; i++) {
945
+ ASSERT_EQ(Key(i) + std::string(1000, 'v'), Get(Key(i)));
946
+ }
947
+
948
+ Reopen();
949
+
950
+ for (int i = 0; i < N; i++) {
951
+ ASSERT_EQ(Key(i) + std::string(1000, 'v'), Get(Key(i)));
952
+ }
953
+ }
954
+
955
+ TEST(DBTest, RecoverWithLargeLog) {
956
+ {
957
+ Options options = CurrentOptions();
958
+ Reopen(&options);
959
+ ASSERT_OK(Put("big1", std::string(200000, '1')));
960
+ ASSERT_OK(Put("big2", std::string(200000, '2')));
961
+ ASSERT_OK(Put("small3", std::string(10, '3')));
962
+ ASSERT_OK(Put("small4", std::string(10, '4')));
963
+ ASSERT_EQ(NumTableFilesAtLevel(0), 0);
964
+ }
965
+
966
+ // Make sure that if we re-open with a small write buffer size that
967
+ // we flush table files in the middle of a large log file.
968
+ Options options = CurrentOptions();
969
+ options.write_buffer_size = 100000;
970
+ Reopen(&options);
971
+ ASSERT_EQ(NumTableFilesAtLevel(0), 3);
972
+ ASSERT_EQ(std::string(200000, '1'), Get("big1"));
973
+ ASSERT_EQ(std::string(200000, '2'), Get("big2"));
974
+ ASSERT_EQ(std::string(10, '3'), Get("small3"));
975
+ ASSERT_EQ(std::string(10, '4'), Get("small4"));
976
+ ASSERT_GT(NumTableFilesAtLevel(0), 1);
977
+ }
978
+
979
+ TEST(DBTest, CompactionsGenerateMultipleFiles) {
980
+ Options options = CurrentOptions();
981
+ options.write_buffer_size = 100000000; // Large write buffer
982
+ Reopen(&options);
983
+
984
+ Random rnd(301);
985
+
986
+ // Write 8MB (80 values, each 100K)
987
+ ASSERT_EQ(NumTableFilesAtLevel(0), 0);
988
+ std::vector<std::string> values;
989
+ for (int i = 0; i < 80; i++) {
990
+ values.push_back(RandomString(&rnd, 100000));
991
+ ASSERT_OK(Put(Key(i), values[i]));
992
+ }
993
+
994
+ // Reopening moves updates to level-0
995
+ Reopen(&options);
996
+ dbfull()->TEST_CompactRange(0, NULL, NULL);
997
+
998
+ ASSERT_EQ(NumTableFilesAtLevel(0), 0);
999
+ ASSERT_GT(NumTableFilesAtLevel(1), 1);
1000
+ for (int i = 0; i < 80; i++) {
1001
+ ASSERT_EQ(Get(Key(i)), values[i]);
1002
+ }
1003
+ }
1004
+
1005
+ TEST(DBTest, RepeatedWritesToSameKey) {
1006
+ Options options = CurrentOptions();
1007
+ options.env = env_;
1008
+ options.write_buffer_size = 100000; // Small write buffer
1009
+ Reopen(&options);
1010
+
1011
+ // We must have at most one file per level except for level-0,
1012
+ // which may have up to kL0_StopWritesTrigger files.
1013
+ const int kMaxFiles = config::kNumLevels + config::kL0_StopWritesTrigger;
1014
+
1015
+ Random rnd(301);
1016
+ std::string value = RandomString(&rnd, 2 * options.write_buffer_size);
1017
+ for (int i = 0; i < 5 * kMaxFiles; i++) {
1018
+ Put("key", value);
1019
+ ASSERT_LE(TotalTableFiles(), kMaxFiles);
1020
+ fprintf(stderr, "after %d: %d files\n", int(i+1), TotalTableFiles());
1021
+ }
1022
+ }
1023
+
1024
+ TEST(DBTest, SparseMerge) {
1025
+ Options options = CurrentOptions();
1026
+ options.compression = kNoCompression;
1027
+ Reopen(&options);
1028
+
1029
+ FillLevels("A", "Z");
1030
+
1031
+ // Suppose there is:
1032
+ // small amount of data with prefix A
1033
+ // large amount of data with prefix B
1034
+ // small amount of data with prefix C
1035
+ // and that recent updates have made small changes to all three prefixes.
1036
+ // Check that we do not do a compaction that merges all of B in one shot.
1037
+ const std::string value(1000, 'x');
1038
+ Put("A", "va");
1039
+ // Write approximately 100MB of "B" values
1040
+ for (int i = 0; i < 100000; i++) {
1041
+ char key[100];
1042
+ snprintf(key, sizeof(key), "B%010d", i);
1043
+ Put(key, value);
1044
+ }
1045
+ Put("C", "vc");
1046
+ dbfull()->TEST_CompactMemTable();
1047
+ dbfull()->TEST_CompactRange(0, NULL, NULL);
1048
+
1049
+ // Make sparse update
1050
+ Put("A", "va2");
1051
+ Put("B100", "bvalue2");
1052
+ Put("C", "vc2");
1053
+ dbfull()->TEST_CompactMemTable();
1054
+
1055
+ // Compactions should not cause us to create a situation where
1056
+ // a file overlaps too much data at the next level.
1057
+ ASSERT_LE(dbfull()->TEST_MaxNextLevelOverlappingBytes(), 20*1048576);
1058
+ dbfull()->TEST_CompactRange(0, NULL, NULL);
1059
+ ASSERT_LE(dbfull()->TEST_MaxNextLevelOverlappingBytes(), 20*1048576);
1060
+ dbfull()->TEST_CompactRange(1, NULL, NULL);
1061
+ ASSERT_LE(dbfull()->TEST_MaxNextLevelOverlappingBytes(), 20*1048576);
1062
+ }
1063
+
1064
+ static bool Between(uint64_t val, uint64_t low, uint64_t high) {
1065
+ bool result = (val >= low) && (val <= high);
1066
+ if (!result) {
1067
+ fprintf(stderr, "Value %llu is not in range [%llu, %llu]\n",
1068
+ (unsigned long long)(val),
1069
+ (unsigned long long)(low),
1070
+ (unsigned long long)(high));
1071
+ }
1072
+ return result;
1073
+ }
1074
+
1075
+ TEST(DBTest, ApproximateSizes) {
1076
+ do {
1077
+ Options options = CurrentOptions();
1078
+ options.write_buffer_size = 100000000; // Large write buffer
1079
+ options.compression = kNoCompression;
1080
+ DestroyAndReopen();
1081
+
1082
+ ASSERT_TRUE(Between(Size("", "xyz"), 0, 0));
1083
+ Reopen(&options);
1084
+ ASSERT_TRUE(Between(Size("", "xyz"), 0, 0));
1085
+
1086
+ // Write 8MB (80 values, each 100K)
1087
+ ASSERT_EQ(NumTableFilesAtLevel(0), 0);
1088
+ const int N = 80;
1089
+ static const int S1 = 100000;
1090
+ static const int S2 = 105000; // Allow some expansion from metadata
1091
+ Random rnd(301);
1092
+ for (int i = 0; i < N; i++) {
1093
+ ASSERT_OK(Put(Key(i), RandomString(&rnd, S1)));
1094
+ }
1095
+
1096
+ // 0 because GetApproximateSizes() does not account for memtable space
1097
+ ASSERT_TRUE(Between(Size("", Key(50)), 0, 0));
1098
+
1099
+ if (options.reuse_logs) {
1100
+ // Recovery will reuse memtable, and GetApproximateSizes() does not
1101
+ // account for memtable usage;
1102
+ Reopen(&options);
1103
+ ASSERT_TRUE(Between(Size("", Key(50)), 0, 0));
1104
+ continue;
1105
+ }
1106
+
1107
+ // Check sizes across recovery by reopening a few times
1108
+ for (int run = 0; run < 3; run++) {
1109
+ Reopen(&options);
1110
+
1111
+ for (int compact_start = 0; compact_start < N; compact_start += 10) {
1112
+ for (int i = 0; i < N; i += 10) {
1113
+ ASSERT_TRUE(Between(Size("", Key(i)), S1*i, S2*i));
1114
+ ASSERT_TRUE(Between(Size("", Key(i)+".suffix"), S1*(i+1), S2*(i+1)));
1115
+ ASSERT_TRUE(Between(Size(Key(i), Key(i+10)), S1*10, S2*10));
1116
+ }
1117
+ ASSERT_TRUE(Between(Size("", Key(50)), S1*50, S2*50));
1118
+ ASSERT_TRUE(Between(Size("", Key(50)+".suffix"), S1*50, S2*50));
1119
+
1120
+ std::string cstart_str = Key(compact_start);
1121
+ std::string cend_str = Key(compact_start + 9);
1122
+ Slice cstart = cstart_str;
1123
+ Slice cend = cend_str;
1124
+ dbfull()->TEST_CompactRange(0, &cstart, &cend);
1125
+ }
1126
+
1127
+ ASSERT_EQ(NumTableFilesAtLevel(0), 0);
1128
+ ASSERT_GT(NumTableFilesAtLevel(1), 0);
1129
+ }
1130
+ } while (ChangeOptions());
1131
+ }
1132
+
1133
+ TEST(DBTest, ApproximateSizes_MixOfSmallAndLarge) {
1134
+ do {
1135
+ Options options = CurrentOptions();
1136
+ options.compression = kNoCompression;
1137
+ Reopen();
1138
+
1139
+ Random rnd(301);
1140
+ std::string big1 = RandomString(&rnd, 100000);
1141
+ ASSERT_OK(Put(Key(0), RandomString(&rnd, 10000)));
1142
+ ASSERT_OK(Put(Key(1), RandomString(&rnd, 10000)));
1143
+ ASSERT_OK(Put(Key(2), big1));
1144
+ ASSERT_OK(Put(Key(3), RandomString(&rnd, 10000)));
1145
+ ASSERT_OK(Put(Key(4), big1));
1146
+ ASSERT_OK(Put(Key(5), RandomString(&rnd, 10000)));
1147
+ ASSERT_OK(Put(Key(6), RandomString(&rnd, 300000)));
1148
+ ASSERT_OK(Put(Key(7), RandomString(&rnd, 10000)));
1149
+
1150
+ if (options.reuse_logs) {
1151
+ // Need to force a memtable compaction since recovery does not do so.
1152
+ ASSERT_OK(dbfull()->TEST_CompactMemTable());
1153
+ }
1154
+
1155
+ // Check sizes across recovery by reopening a few times
1156
+ for (int run = 0; run < 3; run++) {
1157
+ Reopen(&options);
1158
+
1159
+ ASSERT_TRUE(Between(Size("", Key(0)), 0, 0));
1160
+ ASSERT_TRUE(Between(Size("", Key(1)), 10000, 11000));
1161
+ ASSERT_TRUE(Between(Size("", Key(2)), 20000, 21000));
1162
+ ASSERT_TRUE(Between(Size("", Key(3)), 120000, 121000));
1163
+ ASSERT_TRUE(Between(Size("", Key(4)), 130000, 131000));
1164
+ ASSERT_TRUE(Between(Size("", Key(5)), 230000, 231000));
1165
+ ASSERT_TRUE(Between(Size("", Key(6)), 240000, 241000));
1166
+ ASSERT_TRUE(Between(Size("", Key(7)), 540000, 541000));
1167
+ ASSERT_TRUE(Between(Size("", Key(8)), 550000, 560000));
1168
+
1169
+ ASSERT_TRUE(Between(Size(Key(3), Key(5)), 110000, 111000));
1170
+
1171
+ dbfull()->TEST_CompactRange(0, NULL, NULL);
1172
+ }
1173
+ } while (ChangeOptions());
1174
+ }
1175
+
1176
+ TEST(DBTest, IteratorPinsRef) {
1177
+ Put("foo", "hello");
1178
+
1179
+ // Get iterator that will yield the current contents of the DB.
1180
+ Iterator* iter = db_->NewIterator(ReadOptions());
1181
+
1182
+ // Write to force compactions
1183
+ Put("foo", "newvalue1");
1184
+ for (int i = 0; i < 100; i++) {
1185
+ ASSERT_OK(Put(Key(i), Key(i) + std::string(100000, 'v'))); // 100K values
1186
+ }
1187
+ Put("foo", "newvalue2");
1188
+
1189
+ iter->SeekToFirst();
1190
+ ASSERT_TRUE(iter->Valid());
1191
+ ASSERT_EQ("foo", iter->key().ToString());
1192
+ ASSERT_EQ("hello", iter->value().ToString());
1193
+ iter->Next();
1194
+ ASSERT_TRUE(!iter->Valid());
1195
+ delete iter;
1196
+ }
1197
+
1198
+ TEST(DBTest, Snapshot) {
1199
+ do {
1200
+ Put("foo", "v1");
1201
+ const Snapshot* s1 = db_->GetSnapshot();
1202
+ Put("foo", "v2");
1203
+ const Snapshot* s2 = db_->GetSnapshot();
1204
+ Put("foo", "v3");
1205
+ const Snapshot* s3 = db_->GetSnapshot();
1206
+
1207
+ Put("foo", "v4");
1208
+ ASSERT_EQ("v1", Get("foo", s1));
1209
+ ASSERT_EQ("v2", Get("foo", s2));
1210
+ ASSERT_EQ("v3", Get("foo", s3));
1211
+ ASSERT_EQ("v4", Get("foo"));
1212
+
1213
+ db_->ReleaseSnapshot(s3);
1214
+ ASSERT_EQ("v1", Get("foo", s1));
1215
+ ASSERT_EQ("v2", Get("foo", s2));
1216
+ ASSERT_EQ("v4", Get("foo"));
1217
+
1218
+ db_->ReleaseSnapshot(s1);
1219
+ ASSERT_EQ("v2", Get("foo", s2));
1220
+ ASSERT_EQ("v4", Get("foo"));
1221
+
1222
+ db_->ReleaseSnapshot(s2);
1223
+ ASSERT_EQ("v4", Get("foo"));
1224
+ } while (ChangeOptions());
1225
+ }
1226
+
1227
+ TEST(DBTest, HiddenValuesAreRemoved) {
1228
+ do {
1229
+ Random rnd(301);
1230
+ FillLevels("a", "z");
1231
+
1232
+ std::string big = RandomString(&rnd, 50000);
1233
+ Put("foo", big);
1234
+ Put("pastfoo", "v");
1235
+ const Snapshot* snapshot = db_->GetSnapshot();
1236
+ Put("foo", "tiny");
1237
+ Put("pastfoo2", "v2"); // Advance sequence number one more
1238
+
1239
+ ASSERT_OK(dbfull()->TEST_CompactMemTable());
1240
+ ASSERT_GT(NumTableFilesAtLevel(0), 0);
1241
+
1242
+ ASSERT_EQ(big, Get("foo", snapshot));
1243
+ ASSERT_TRUE(Between(Size("", "pastfoo"), 50000, 60000));
1244
+ db_->ReleaseSnapshot(snapshot);
1245
+ ASSERT_EQ(AllEntriesFor("foo"), "[ tiny, " + big + " ]");
1246
+ Slice x("x");
1247
+ dbfull()->TEST_CompactRange(0, NULL, &x);
1248
+ ASSERT_EQ(AllEntriesFor("foo"), "[ tiny ]");
1249
+ ASSERT_EQ(NumTableFilesAtLevel(0), 0);
1250
+ ASSERT_GE(NumTableFilesAtLevel(1), 1);
1251
+ dbfull()->TEST_CompactRange(1, NULL, &x);
1252
+ ASSERT_EQ(AllEntriesFor("foo"), "[ tiny ]");
1253
+
1254
+ ASSERT_TRUE(Between(Size("", "pastfoo"), 0, 1000));
1255
+ } while (ChangeOptions());
1256
+ }
1257
+
1258
+ TEST(DBTest, DeletionMarkers1) {
1259
+ Put("foo", "v1");
1260
+ ASSERT_OK(dbfull()->TEST_CompactMemTable());
1261
+ const int last = config::kMaxMemCompactLevel;
1262
+ ASSERT_EQ(NumTableFilesAtLevel(last), 1); // foo => v1 is now in last level
1263
+
1264
+ // Place a table at level last-1 to prevent merging with preceding mutation
1265
+ Put("a", "begin");
1266
+ Put("z", "end");
1267
+ dbfull()->TEST_CompactMemTable();
1268
+ ASSERT_EQ(NumTableFilesAtLevel(last), 1);
1269
+ ASSERT_EQ(NumTableFilesAtLevel(last-1), 1);
1270
+
1271
+ Delete("foo");
1272
+ Put("foo", "v2");
1273
+ ASSERT_EQ(AllEntriesFor("foo"), "[ v2, DEL, v1 ]");
1274
+ ASSERT_OK(dbfull()->TEST_CompactMemTable()); // Moves to level last-2
1275
+ ASSERT_EQ(AllEntriesFor("foo"), "[ v2, DEL, v1 ]");
1276
+ Slice z("z");
1277
+ dbfull()->TEST_CompactRange(last-2, NULL, &z);
1278
+ // DEL eliminated, but v1 remains because we aren't compacting that level
1279
+ // (DEL can be eliminated because v2 hides v1).
1280
+ ASSERT_EQ(AllEntriesFor("foo"), "[ v2, v1 ]");
1281
+ dbfull()->TEST_CompactRange(last-1, NULL, NULL);
1282
+ // Merging last-1 w/ last, so we are the base level for "foo", so
1283
+ // DEL is removed. (as is v1).
1284
+ ASSERT_EQ(AllEntriesFor("foo"), "[ v2 ]");
1285
+ }
1286
+
1287
+ TEST(DBTest, DeletionMarkers2) {
1288
+ Put("foo", "v1");
1289
+ ASSERT_OK(dbfull()->TEST_CompactMemTable());
1290
+ const int last = config::kMaxMemCompactLevel;
1291
+ ASSERT_EQ(NumTableFilesAtLevel(last), 1); // foo => v1 is now in last level
1292
+
1293
+ // Place a table at level last-1 to prevent merging with preceding mutation
1294
+ Put("a", "begin");
1295
+ Put("z", "end");
1296
+ dbfull()->TEST_CompactMemTable();
1297
+ ASSERT_EQ(NumTableFilesAtLevel(last), 1);
1298
+ ASSERT_EQ(NumTableFilesAtLevel(last-1), 1);
1299
+
1300
+ Delete("foo");
1301
+ ASSERT_EQ(AllEntriesFor("foo"), "[ DEL, v1 ]");
1302
+ ASSERT_OK(dbfull()->TEST_CompactMemTable()); // Moves to level last-2
1303
+ ASSERT_EQ(AllEntriesFor("foo"), "[ DEL, v1 ]");
1304
+ dbfull()->TEST_CompactRange(last-2, NULL, NULL);
1305
+ // DEL kept: "last" file overlaps
1306
+ ASSERT_EQ(AllEntriesFor("foo"), "[ DEL, v1 ]");
1307
+ dbfull()->TEST_CompactRange(last-1, NULL, NULL);
1308
+ // Merging last-1 w/ last, so we are the base level for "foo", so
1309
+ // DEL is removed. (as is v1).
1310
+ ASSERT_EQ(AllEntriesFor("foo"), "[ ]");
1311
+ }
1312
+
1313
+ TEST(DBTest, OverlapInLevel0) {
1314
+ do {
1315
+ ASSERT_EQ(config::kMaxMemCompactLevel, 2) << "Fix test to match config";
1316
+
1317
+ // Fill levels 1 and 2 to disable the pushing of new memtables to levels > 0.
1318
+ ASSERT_OK(Put("100", "v100"));
1319
+ ASSERT_OK(Put("999", "v999"));
1320
+ dbfull()->TEST_CompactMemTable();
1321
+ ASSERT_OK(Delete("100"));
1322
+ ASSERT_OK(Delete("999"));
1323
+ dbfull()->TEST_CompactMemTable();
1324
+ ASSERT_EQ("0,1,1", FilesPerLevel());
1325
+
1326
+ // Make files spanning the following ranges in level-0:
1327
+ // files[0] 200 .. 900
1328
+ // files[1] 300 .. 500
1329
+ // Note that files are sorted by smallest key.
1330
+ ASSERT_OK(Put("300", "v300"));
1331
+ ASSERT_OK(Put("500", "v500"));
1332
+ dbfull()->TEST_CompactMemTable();
1333
+ ASSERT_OK(Put("200", "v200"));
1334
+ ASSERT_OK(Put("600", "v600"));
1335
+ ASSERT_OK(Put("900", "v900"));
1336
+ dbfull()->TEST_CompactMemTable();
1337
+ ASSERT_EQ("2,1,1", FilesPerLevel());
1338
+
1339
+ // Compact away the placeholder files we created initially
1340
+ dbfull()->TEST_CompactRange(1, NULL, NULL);
1341
+ dbfull()->TEST_CompactRange(2, NULL, NULL);
1342
+ ASSERT_EQ("2", FilesPerLevel());
1343
+
1344
+ // Do a memtable compaction. Before bug-fix, the compaction would
1345
+ // not detect the overlap with level-0 files and would incorrectly place
1346
+ // the deletion in a deeper level.
1347
+ ASSERT_OK(Delete("600"));
1348
+ dbfull()->TEST_CompactMemTable();
1349
+ ASSERT_EQ("3", FilesPerLevel());
1350
+ ASSERT_EQ("NOT_FOUND", Get("600"));
1351
+ } while (ChangeOptions());
1352
+ }
1353
+
1354
+ TEST(DBTest, L0_CompactionBug_Issue44_a) {
1355
+ Reopen();
1356
+ ASSERT_OK(Put("b", "v"));
1357
+ Reopen();
1358
+ ASSERT_OK(Delete("b"));
1359
+ ASSERT_OK(Delete("a"));
1360
+ Reopen();
1361
+ ASSERT_OK(Delete("a"));
1362
+ Reopen();
1363
+ ASSERT_OK(Put("a", "v"));
1364
+ Reopen();
1365
+ Reopen();
1366
+ ASSERT_EQ("(a->v)", Contents());
1367
+ DelayMilliseconds(1000); // Wait for compaction to finish
1368
+ ASSERT_EQ("(a->v)", Contents());
1369
+ }
1370
+
1371
+ TEST(DBTest, L0_CompactionBug_Issue44_b) {
1372
+ Reopen();
1373
+ Put("","");
1374
+ Reopen();
1375
+ Delete("e");
1376
+ Put("","");
1377
+ Reopen();
1378
+ Put("c", "cv");
1379
+ Reopen();
1380
+ Put("","");
1381
+ Reopen();
1382
+ Put("","");
1383
+ DelayMilliseconds(1000); // Wait for compaction to finish
1384
+ Reopen();
1385
+ Put("d","dv");
1386
+ Reopen();
1387
+ Put("","");
1388
+ Reopen();
1389
+ Delete("d");
1390
+ Delete("b");
1391
+ Reopen();
1392
+ ASSERT_EQ("(->)(c->cv)", Contents());
1393
+ DelayMilliseconds(1000); // Wait for compaction to finish
1394
+ ASSERT_EQ("(->)(c->cv)", Contents());
1395
+ }
1396
+
1397
+ TEST(DBTest, ComparatorCheck) {
1398
+ class NewComparator : public Comparator {
1399
+ public:
1400
+ virtual const char* Name() const { return "leveldb.NewComparator"; }
1401
+ virtual int Compare(const Slice& a, const Slice& b) const {
1402
+ return BytewiseComparator()->Compare(a, b);
1403
+ }
1404
+ virtual void FindShortestSeparator(std::string* s, const Slice& l) const {
1405
+ BytewiseComparator()->FindShortestSeparator(s, l);
1406
+ }
1407
+ virtual void FindShortSuccessor(std::string* key) const {
1408
+ BytewiseComparator()->FindShortSuccessor(key);
1409
+ }
1410
+ };
1411
+ NewComparator cmp;
1412
+ Options new_options = CurrentOptions();
1413
+ new_options.comparator = &cmp;
1414
+ Status s = TryReopen(&new_options);
1415
+ ASSERT_TRUE(!s.ok());
1416
+ ASSERT_TRUE(s.ToString().find("comparator") != std::string::npos)
1417
+ << s.ToString();
1418
+ }
1419
+
1420
+ TEST(DBTest, CustomComparator) {
1421
+ class NumberComparator : public Comparator {
1422
+ public:
1423
+ virtual const char* Name() const { return "test.NumberComparator"; }
1424
+ virtual int Compare(const Slice& a, const Slice& b) const {
1425
+ return ToNumber(a) - ToNumber(b);
1426
+ }
1427
+ virtual void FindShortestSeparator(std::string* s, const Slice& l) const {
1428
+ ToNumber(*s); // Check format
1429
+ ToNumber(l); // Check format
1430
+ }
1431
+ virtual void FindShortSuccessor(std::string* key) const {
1432
+ ToNumber(*key); // Check format
1433
+ }
1434
+ private:
1435
+ static int ToNumber(const Slice& x) {
1436
+ // Check that there are no extra characters.
1437
+ ASSERT_TRUE(x.size() >= 2 && x[0] == '[' && x[x.size()-1] == ']')
1438
+ << EscapeString(x);
1439
+ int val;
1440
+ char ignored;
1441
+ ASSERT_TRUE(sscanf(x.ToString().c_str(), "[%i]%c", &val, &ignored) == 1)
1442
+ << EscapeString(x);
1443
+ return val;
1444
+ }
1445
+ };
1446
+ NumberComparator cmp;
1447
+ Options new_options = CurrentOptions();
1448
+ new_options.create_if_missing = true;
1449
+ new_options.comparator = &cmp;
1450
+ new_options.filter_policy = NULL; // Cannot use bloom filters
1451
+ new_options.write_buffer_size = 1000; // Compact more often
1452
+ DestroyAndReopen(&new_options);
1453
+ ASSERT_OK(Put("[10]", "ten"));
1454
+ ASSERT_OK(Put("[0x14]", "twenty"));
1455
+ for (int i = 0; i < 2; i++) {
1456
+ ASSERT_EQ("ten", Get("[10]"));
1457
+ ASSERT_EQ("ten", Get("[0xa]"));
1458
+ ASSERT_EQ("twenty", Get("[20]"));
1459
+ ASSERT_EQ("twenty", Get("[0x14]"));
1460
+ ASSERT_EQ("NOT_FOUND", Get("[15]"));
1461
+ ASSERT_EQ("NOT_FOUND", Get("[0xf]"));
1462
+ Compact("[0]", "[9999]");
1463
+ }
1464
+
1465
+ for (int run = 0; run < 2; run++) {
1466
+ for (int i = 0; i < 1000; i++) {
1467
+ char buf[100];
1468
+ snprintf(buf, sizeof(buf), "[%d]", i*10);
1469
+ ASSERT_OK(Put(buf, buf));
1470
+ }
1471
+ Compact("[0]", "[1000000]");
1472
+ }
1473
+ }
1474
+
1475
+ TEST(DBTest, ManualCompaction) {
1476
+ ASSERT_EQ(config::kMaxMemCompactLevel, 2)
1477
+ << "Need to update this test to match kMaxMemCompactLevel";
1478
+
1479
+ MakeTables(3, "p", "q");
1480
+ ASSERT_EQ("1,1,1", FilesPerLevel());
1481
+
1482
+ // Compaction range falls before files
1483
+ Compact("", "c");
1484
+ ASSERT_EQ("1,1,1", FilesPerLevel());
1485
+
1486
+ // Compaction range falls after files
1487
+ Compact("r", "z");
1488
+ ASSERT_EQ("1,1,1", FilesPerLevel());
1489
+
1490
+ // Compaction range overlaps files
1491
+ Compact("p1", "p9");
1492
+ ASSERT_EQ("0,0,1", FilesPerLevel());
1493
+
1494
+ // Populate a different range
1495
+ MakeTables(3, "c", "e");
1496
+ ASSERT_EQ("1,1,2", FilesPerLevel());
1497
+
1498
+ // Compact just the new range
1499
+ Compact("b", "f");
1500
+ ASSERT_EQ("0,0,2", FilesPerLevel());
1501
+
1502
+ // Compact all
1503
+ MakeTables(1, "a", "z");
1504
+ ASSERT_EQ("0,1,2", FilesPerLevel());
1505
+ db_->CompactRange(NULL, NULL);
1506
+ ASSERT_EQ("0,0,1", FilesPerLevel());
1507
+ }
1508
+
1509
+ TEST(DBTest, DBOpen_Options) {
1510
+ std::string dbname = test::TmpDir() + "/db_options_test";
1511
+ DestroyDB(dbname, Options());
1512
+
1513
+ // Does not exist, and create_if_missing == false: error
1514
+ DB* db = NULL;
1515
+ Options opts;
1516
+ opts.create_if_missing = false;
1517
+ Status s = DB::Open(opts, dbname, &db);
1518
+ ASSERT_TRUE(strstr(s.ToString().c_str(), "does not exist") != NULL);
1519
+ ASSERT_TRUE(db == NULL);
1520
+
1521
+ // Does not exist, and create_if_missing == true: OK
1522
+ opts.create_if_missing = true;
1523
+ s = DB::Open(opts, dbname, &db);
1524
+ ASSERT_OK(s);
1525
+ ASSERT_TRUE(db != NULL);
1526
+
1527
+ delete db;
1528
+ db = NULL;
1529
+
1530
+ // Does exist, and error_if_exists == true: error
1531
+ opts.create_if_missing = false;
1532
+ opts.error_if_exists = true;
1533
+ s = DB::Open(opts, dbname, &db);
1534
+ ASSERT_TRUE(strstr(s.ToString().c_str(), "exists") != NULL);
1535
+ ASSERT_TRUE(db == NULL);
1536
+
1537
+ // Does exist, and error_if_exists == false: OK
1538
+ opts.create_if_missing = true;
1539
+ opts.error_if_exists = false;
1540
+ s = DB::Open(opts, dbname, &db);
1541
+ ASSERT_OK(s);
1542
+ ASSERT_TRUE(db != NULL);
1543
+
1544
+ delete db;
1545
+ db = NULL;
1546
+ }
1547
+
1548
+ TEST(DBTest, Locking) {
1549
+ DB* db2 = NULL;
1550
+ Status s = DB::Open(CurrentOptions(), dbname_, &db2);
1551
+ ASSERT_TRUE(!s.ok()) << "Locking did not prevent re-opening db";
1552
+ }
1553
+
1554
+ // Check that number of files does not grow when we are out of space
1555
+ TEST(DBTest, NoSpace) {
1556
+ Options options = CurrentOptions();
1557
+ options.env = env_;
1558
+ Reopen(&options);
1559
+
1560
+ ASSERT_OK(Put("foo", "v1"));
1561
+ ASSERT_EQ("v1", Get("foo"));
1562
+ Compact("a", "z");
1563
+ const int num_files = CountFiles();
1564
+ env_->no_space_.Release_Store(env_); // Force out-of-space errors
1565
+ for (int i = 0; i < 10; i++) {
1566
+ for (int level = 0; level < config::kNumLevels-1; level++) {
1567
+ dbfull()->TEST_CompactRange(level, NULL, NULL);
1568
+ }
1569
+ }
1570
+ env_->no_space_.Release_Store(NULL);
1571
+ ASSERT_LT(CountFiles(), num_files + 3);
1572
+ }
1573
+
1574
+ TEST(DBTest, NonWritableFileSystem) {
1575
+ Options options = CurrentOptions();
1576
+ options.write_buffer_size = 1000;
1577
+ options.env = env_;
1578
+ Reopen(&options);
1579
+ ASSERT_OK(Put("foo", "v1"));
1580
+ env_->non_writable_.Release_Store(env_); // Force errors for new files
1581
+ std::string big(100000, 'x');
1582
+ int errors = 0;
1583
+ for (int i = 0; i < 20; i++) {
1584
+ fprintf(stderr, "iter %d; errors %d\n", i, errors);
1585
+ if (!Put("foo", big).ok()) {
1586
+ errors++;
1587
+ DelayMilliseconds(100);
1588
+ }
1589
+ }
1590
+ ASSERT_GT(errors, 0);
1591
+ env_->non_writable_.Release_Store(NULL);
1592
+ }
1593
+
1594
+ TEST(DBTest, WriteSyncError) {
1595
+ // Check that log sync errors cause the DB to disallow future writes.
1596
+
1597
+ // (a) Cause log sync calls to fail
1598
+ Options options = CurrentOptions();
1599
+ options.env = env_;
1600
+ Reopen(&options);
1601
+ env_->data_sync_error_.Release_Store(env_);
1602
+
1603
+ // (b) Normal write should succeed
1604
+ WriteOptions w;
1605
+ ASSERT_OK(db_->Put(w, "k1", "v1"));
1606
+ ASSERT_EQ("v1", Get("k1"));
1607
+
1608
+ // (c) Do a sync write; should fail
1609
+ w.sync = true;
1610
+ ASSERT_TRUE(!db_->Put(w, "k2", "v2").ok());
1611
+ ASSERT_EQ("v1", Get("k1"));
1612
+ ASSERT_EQ("NOT_FOUND", Get("k2"));
1613
+
1614
+ // (d) make sync behave normally
1615
+ env_->data_sync_error_.Release_Store(NULL);
1616
+
1617
+ // (e) Do a non-sync write; should fail
1618
+ w.sync = false;
1619
+ ASSERT_TRUE(!db_->Put(w, "k3", "v3").ok());
1620
+ ASSERT_EQ("v1", Get("k1"));
1621
+ ASSERT_EQ("NOT_FOUND", Get("k2"));
1622
+ ASSERT_EQ("NOT_FOUND", Get("k3"));
1623
+ }
1624
+
1625
+ TEST(DBTest, ManifestWriteError) {
1626
+ // Test for the following problem:
1627
+ // (a) Compaction produces file F
1628
+ // (b) Log record containing F is written to MANIFEST file, but Sync() fails
1629
+ // (c) GC deletes F
1630
+ // (d) After reopening DB, reads fail since deleted F is named in log record
1631
+
1632
+ // We iterate twice. In the second iteration, everything is the
1633
+ // same except the log record never makes it to the MANIFEST file.
1634
+ for (int iter = 0; iter < 2; iter++) {
1635
+ port::AtomicPointer* error_type = (iter == 0)
1636
+ ? &env_->manifest_sync_error_
1637
+ : &env_->manifest_write_error_;
1638
+
1639
+ // Insert foo=>bar mapping
1640
+ Options options = CurrentOptions();
1641
+ options.env = env_;
1642
+ options.create_if_missing = true;
1643
+ options.error_if_exists = false;
1644
+ DestroyAndReopen(&options);
1645
+ ASSERT_OK(Put("foo", "bar"));
1646
+ ASSERT_EQ("bar", Get("foo"));
1647
+
1648
+ // Memtable compaction (will succeed)
1649
+ dbfull()->TEST_CompactMemTable();
1650
+ ASSERT_EQ("bar", Get("foo"));
1651
+ const int last = config::kMaxMemCompactLevel;
1652
+ ASSERT_EQ(NumTableFilesAtLevel(last), 1); // foo=>bar is now in last level
1653
+
1654
+ // Merging compaction (will fail)
1655
+ error_type->Release_Store(env_);
1656
+ dbfull()->TEST_CompactRange(last, NULL, NULL); // Should fail
1657
+ ASSERT_EQ("bar", Get("foo"));
1658
+
1659
+ // Recovery: should not lose data
1660
+ error_type->Release_Store(NULL);
1661
+ Reopen(&options);
1662
+ ASSERT_EQ("bar", Get("foo"));
1663
+ }
1664
+ }
1665
+
1666
+ TEST(DBTest, MissingSSTFile) {
1667
+ ASSERT_OK(Put("foo", "bar"));
1668
+ ASSERT_EQ("bar", Get("foo"));
1669
+
1670
+ // Dump the memtable to disk.
1671
+ dbfull()->TEST_CompactMemTable();
1672
+ ASSERT_EQ("bar", Get("foo"));
1673
+
1674
+ Close();
1675
+ ASSERT_TRUE(DeleteAnSSTFile());
1676
+ Options options = CurrentOptions();
1677
+ options.paranoid_checks = true;
1678
+ Status s = TryReopen(&options);
1679
+ ASSERT_TRUE(!s.ok());
1680
+ ASSERT_TRUE(s.ToString().find("issing") != std::string::npos)
1681
+ << s.ToString();
1682
+ }
1683
+
1684
+ TEST(DBTest, StillReadSST) {
1685
+ ASSERT_OK(Put("foo", "bar"));
1686
+ ASSERT_EQ("bar", Get("foo"));
1687
+
1688
+ // Dump the memtable to disk.
1689
+ dbfull()->TEST_CompactMemTable();
1690
+ ASSERT_EQ("bar", Get("foo"));
1691
+ Close();
1692
+ ASSERT_GT(RenameLDBToSST(), 0);
1693
+ Options options = CurrentOptions();
1694
+ options.paranoid_checks = true;
1695
+ Status s = TryReopen(&options);
1696
+ ASSERT_TRUE(s.ok());
1697
+ ASSERT_EQ("bar", Get("foo"));
1698
+ }
1699
+
1700
+ TEST(DBTest, FilesDeletedAfterCompaction) {
1701
+ ASSERT_OK(Put("foo", "v2"));
1702
+ Compact("a", "z");
1703
+ const int num_files = CountFiles();
1704
+ for (int i = 0; i < 10; i++) {
1705
+ ASSERT_OK(Put("foo", "v2"));
1706
+ Compact("a", "z");
1707
+ }
1708
+ ASSERT_EQ(CountFiles(), num_files);
1709
+ }
1710
+
1711
+ TEST(DBTest, BloomFilter) {
1712
+ env_->count_random_reads_ = true;
1713
+ Options options = CurrentOptions();
1714
+ options.env = env_;
1715
+ options.block_cache = NewLRUCache(0); // Prevent cache hits
1716
+ options.filter_policy = NewBloomFilterPolicy(10);
1717
+ Reopen(&options);
1718
+
1719
+ // Populate multiple layers
1720
+ const int N = 10000;
1721
+ for (int i = 0; i < N; i++) {
1722
+ ASSERT_OK(Put(Key(i), Key(i)));
1723
+ }
1724
+ Compact("a", "z");
1725
+ for (int i = 0; i < N; i += 100) {
1726
+ ASSERT_OK(Put(Key(i), Key(i)));
1727
+ }
1728
+ dbfull()->TEST_CompactMemTable();
1729
+
1730
+ // Prevent auto compactions triggered by seeks
1731
+ env_->delay_data_sync_.Release_Store(env_);
1732
+
1733
+ // Lookup present keys. Should rarely read from small sstable.
1734
+ env_->random_read_counter_.Reset();
1735
+ for (int i = 0; i < N; i++) {
1736
+ ASSERT_EQ(Key(i), Get(Key(i)));
1737
+ }
1738
+ int reads = env_->random_read_counter_.Read();
1739
+ fprintf(stderr, "%d present => %d reads\n", N, reads);
1740
+ ASSERT_GE(reads, N);
1741
+ ASSERT_LE(reads, N + 2*N/100);
1742
+
1743
+ // Lookup present keys. Should rarely read from either sstable.
1744
+ env_->random_read_counter_.Reset();
1745
+ for (int i = 0; i < N; i++) {
1746
+ ASSERT_EQ("NOT_FOUND", Get(Key(i) + ".missing"));
1747
+ }
1748
+ reads = env_->random_read_counter_.Read();
1749
+ fprintf(stderr, "%d missing => %d reads\n", N, reads);
1750
+ ASSERT_LE(reads, 3*N/100);
1751
+
1752
+ env_->delay_data_sync_.Release_Store(NULL);
1753
+ Close();
1754
+ delete options.block_cache;
1755
+ delete options.filter_policy;
1756
+ }
1757
+
1758
+ // Multi-threaded test:
1759
+ namespace {
1760
+
1761
+ static const int kNumThreads = 4;
1762
+ static const int kTestSeconds = 10;
1763
+ static const int kNumKeys = 1000;
1764
+
1765
+ struct MTState {
1766
+ DBTest* test;
1767
+ port::AtomicPointer stop;
1768
+ port::AtomicPointer counter[kNumThreads];
1769
+ port::AtomicPointer thread_done[kNumThreads];
1770
+ };
1771
+
1772
+ struct MTThread {
1773
+ MTState* state;
1774
+ int id;
1775
+ };
1776
+
1777
+ static void MTThreadBody(void* arg) {
1778
+ MTThread* t = reinterpret_cast<MTThread*>(arg);
1779
+ int id = t->id;
1780
+ DB* db = t->state->test->db_;
1781
+ uintptr_t counter = 0;
1782
+ fprintf(stderr, "... starting thread %d\n", id);
1783
+ Random rnd(1000 + id);
1784
+ std::string value;
1785
+ char valbuf[1500];
1786
+ while (t->state->stop.Acquire_Load() == NULL) {
1787
+ t->state->counter[id].Release_Store(reinterpret_cast<void*>(counter));
1788
+
1789
+ int key = rnd.Uniform(kNumKeys);
1790
+ char keybuf[20];
1791
+ snprintf(keybuf, sizeof(keybuf), "%016d", key);
1792
+
1793
+ if (rnd.OneIn(2)) {
1794
+ // Write values of the form <key, my id, counter>.
1795
+ // We add some padding for force compactions.
1796
+ snprintf(valbuf, sizeof(valbuf), "%d.%d.%-1000d",
1797
+ key, id, static_cast<int>(counter));
1798
+ ASSERT_OK(db->Put(WriteOptions(), Slice(keybuf), Slice(valbuf)));
1799
+ } else {
1800
+ // Read a value and verify that it matches the pattern written above.
1801
+ Status s = db->Get(ReadOptions(), Slice(keybuf), &value);
1802
+ if (s.IsNotFound()) {
1803
+ // Key has not yet been written
1804
+ } else {
1805
+ // Check that the writer thread counter is >= the counter in the value
1806
+ ASSERT_OK(s);
1807
+ int k, w, c;
1808
+ ASSERT_EQ(3, sscanf(value.c_str(), "%d.%d.%d", &k, &w, &c)) << value;
1809
+ ASSERT_EQ(k, key);
1810
+ ASSERT_GE(w, 0);
1811
+ ASSERT_LT(w, kNumThreads);
1812
+ ASSERT_LE(static_cast<uintptr_t>(c), reinterpret_cast<uintptr_t>(
1813
+ t->state->counter[w].Acquire_Load()));
1814
+ }
1815
+ }
1816
+ counter++;
1817
+ }
1818
+ t->state->thread_done[id].Release_Store(t);
1819
+ fprintf(stderr, "... stopping thread %d after %d ops\n", id, int(counter));
1820
+ }
1821
+
1822
+ } // namespace
1823
+
1824
+ TEST(DBTest, MultiThreaded) {
1825
+ do {
1826
+ // Initialize state
1827
+ MTState mt;
1828
+ mt.test = this;
1829
+ mt.stop.Release_Store(0);
1830
+ for (int id = 0; id < kNumThreads; id++) {
1831
+ mt.counter[id].Release_Store(0);
1832
+ mt.thread_done[id].Release_Store(0);
1833
+ }
1834
+
1835
+ // Start threads
1836
+ MTThread thread[kNumThreads];
1837
+ for (int id = 0; id < kNumThreads; id++) {
1838
+ thread[id].state = &mt;
1839
+ thread[id].id = id;
1840
+ env_->StartThread(MTThreadBody, &thread[id]);
1841
+ }
1842
+
1843
+ // Let them run for a while
1844
+ DelayMilliseconds(kTestSeconds * 1000);
1845
+
1846
+ // Stop the threads and wait for them to finish
1847
+ mt.stop.Release_Store(&mt);
1848
+ for (int id = 0; id < kNumThreads; id++) {
1849
+ while (mt.thread_done[id].Acquire_Load() == NULL) {
1850
+ DelayMilliseconds(100);
1851
+ }
1852
+ }
1853
+ } while (ChangeOptions());
1854
+ }
1855
+
1856
+ namespace {
1857
+ typedef std::map<std::string, std::string> KVMap;
1858
+ }
1859
+
1860
+ class ModelDB: public DB {
1861
+ public:
1862
+ class ModelSnapshot : public Snapshot {
1863
+ public:
1864
+ KVMap map_;
1865
+ };
1866
+
1867
+ explicit ModelDB(const Options& options): options_(options) { }
1868
+ ~ModelDB() { }
1869
+ virtual Status Put(const WriteOptions& o, const Slice& k, const Slice& v) {
1870
+ return DB::Put(o, k, v);
1871
+ }
1872
+ virtual Status Delete(const WriteOptions& o, const Slice& key) {
1873
+ return DB::Delete(o, key);
1874
+ }
1875
+ virtual Status Get(const ReadOptions& options,
1876
+ const Slice& key, std::string* value) {
1877
+ assert(false); // Not implemented
1878
+ return Status::NotFound(key);
1879
+ }
1880
+ virtual Iterator* NewIterator(const ReadOptions& options) {
1881
+ if (options.snapshot == NULL) {
1882
+ KVMap* saved = new KVMap;
1883
+ *saved = map_;
1884
+ return new ModelIter(saved, true);
1885
+ } else {
1886
+ const KVMap* snapshot_state =
1887
+ &(reinterpret_cast<const ModelSnapshot*>(options.snapshot)->map_);
1888
+ return new ModelIter(snapshot_state, false);
1889
+ }
1890
+ }
1891
+ virtual const Snapshot* GetSnapshot() {
1892
+ ModelSnapshot* snapshot = new ModelSnapshot;
1893
+ snapshot->map_ = map_;
1894
+ return snapshot;
1895
+ }
1896
+
1897
+ virtual void ReleaseSnapshot(const Snapshot* snapshot) {
1898
+ delete reinterpret_cast<const ModelSnapshot*>(snapshot);
1899
+ }
1900
+ virtual Status Write(const WriteOptions& options, WriteBatch* batch) {
1901
+ class Handler : public WriteBatch::Handler {
1902
+ public:
1903
+ KVMap* map_;
1904
+ virtual void Put(const Slice& key, const Slice& value) {
1905
+ (*map_)[key.ToString()] = value.ToString();
1906
+ }
1907
+ virtual void Delete(const Slice& key) {
1908
+ map_->erase(key.ToString());
1909
+ }
1910
+ };
1911
+ Handler handler;
1912
+ handler.map_ = &map_;
1913
+ return batch->Iterate(&handler);
1914
+ }
1915
+
1916
+ virtual bool GetProperty(const Slice& property, std::string* value) {
1917
+ return false;
1918
+ }
1919
+ virtual void GetApproximateSizes(const Range* r, int n, uint64_t* sizes) {
1920
+ for (int i = 0; i < n; i++) {
1921
+ sizes[i] = 0;
1922
+ }
1923
+ }
1924
+ virtual void CompactRange(const Slice* start, const Slice* end) {
1925
+ }
1926
+
1927
+ private:
1928
+ class ModelIter: public Iterator {
1929
+ public:
1930
+ ModelIter(const KVMap* map, bool owned)
1931
+ : map_(map), owned_(owned), iter_(map_->end()) {
1932
+ }
1933
+ ~ModelIter() {
1934
+ if (owned_) delete map_;
1935
+ }
1936
+ virtual bool Valid() const { return iter_ != map_->end(); }
1937
+ virtual void SeekToFirst() { iter_ = map_->begin(); }
1938
+ virtual void SeekToLast() {
1939
+ if (map_->empty()) {
1940
+ iter_ = map_->end();
1941
+ } else {
1942
+ iter_ = map_->find(map_->rbegin()->first);
1943
+ }
1944
+ }
1945
+ virtual void Seek(const Slice& k) {
1946
+ iter_ = map_->lower_bound(k.ToString());
1947
+ }
1948
+ virtual void Next() { ++iter_; }
1949
+ virtual void Prev() { --iter_; }
1950
+ virtual Slice key() const { return iter_->first; }
1951
+ virtual Slice value() const { return iter_->second; }
1952
+ virtual Status status() const { return Status::OK(); }
1953
+ private:
1954
+ const KVMap* const map_;
1955
+ const bool owned_; // Do we own map_
1956
+ KVMap::const_iterator iter_;
1957
+ };
1958
+ const Options options_;
1959
+ KVMap map_;
1960
+ };
1961
+
1962
+ static std::string RandomKey(Random* rnd) {
1963
+ int len = (rnd->OneIn(3)
1964
+ ? 1 // Short sometimes to encourage collisions
1965
+ : (rnd->OneIn(100) ? rnd->Skewed(10) : rnd->Uniform(10)));
1966
+ return test::RandomKey(rnd, len);
1967
+ }
1968
+
1969
+ static bool CompareIterators(int step,
1970
+ DB* model,
1971
+ DB* db,
1972
+ const Snapshot* model_snap,
1973
+ const Snapshot* db_snap) {
1974
+ ReadOptions options;
1975
+ options.snapshot = model_snap;
1976
+ Iterator* miter = model->NewIterator(options);
1977
+ options.snapshot = db_snap;
1978
+ Iterator* dbiter = db->NewIterator(options);
1979
+ bool ok = true;
1980
+ int count = 0;
1981
+ for (miter->SeekToFirst(), dbiter->SeekToFirst();
1982
+ ok && miter->Valid() && dbiter->Valid();
1983
+ miter->Next(), dbiter->Next()) {
1984
+ count++;
1985
+ if (miter->key().compare(dbiter->key()) != 0) {
1986
+ fprintf(stderr, "step %d: Key mismatch: '%s' vs. '%s'\n",
1987
+ step,
1988
+ EscapeString(miter->key()).c_str(),
1989
+ EscapeString(dbiter->key()).c_str());
1990
+ ok = false;
1991
+ break;
1992
+ }
1993
+
1994
+ if (miter->value().compare(dbiter->value()) != 0) {
1995
+ fprintf(stderr, "step %d: Value mismatch for key '%s': '%s' vs. '%s'\n",
1996
+ step,
1997
+ EscapeString(miter->key()).c_str(),
1998
+ EscapeString(miter->value()).c_str(),
1999
+ EscapeString(miter->value()).c_str());
2000
+ ok = false;
2001
+ }
2002
+ }
2003
+
2004
+ if (ok) {
2005
+ if (miter->Valid() != dbiter->Valid()) {
2006
+ fprintf(stderr, "step %d: Mismatch at end of iterators: %d vs. %d\n",
2007
+ step, miter->Valid(), dbiter->Valid());
2008
+ ok = false;
2009
+ }
2010
+ }
2011
+ fprintf(stderr, "%d entries compared: ok=%d\n", count, ok);
2012
+ delete miter;
2013
+ delete dbiter;
2014
+ return ok;
2015
+ }
2016
+
2017
+ TEST(DBTest, Randomized) {
2018
+ Random rnd(test::RandomSeed());
2019
+ do {
2020
+ ModelDB model(CurrentOptions());
2021
+ const int N = 10000;
2022
+ const Snapshot* model_snap = NULL;
2023
+ const Snapshot* db_snap = NULL;
2024
+ std::string k, v;
2025
+ for (int step = 0; step < N; step++) {
2026
+ if (step % 100 == 0) {
2027
+ fprintf(stderr, "Step %d of %d\n", step, N);
2028
+ }
2029
+ // TODO(sanjay): Test Get() works
2030
+ int p = rnd.Uniform(100);
2031
+ if (p < 45) { // Put
2032
+ k = RandomKey(&rnd);
2033
+ v = RandomString(&rnd,
2034
+ rnd.OneIn(20)
2035
+ ? 100 + rnd.Uniform(100)
2036
+ : rnd.Uniform(8));
2037
+ ASSERT_OK(model.Put(WriteOptions(), k, v));
2038
+ ASSERT_OK(db_->Put(WriteOptions(), k, v));
2039
+
2040
+ } else if (p < 90) { // Delete
2041
+ k = RandomKey(&rnd);
2042
+ ASSERT_OK(model.Delete(WriteOptions(), k));
2043
+ ASSERT_OK(db_->Delete(WriteOptions(), k));
2044
+
2045
+
2046
+ } else { // Multi-element batch
2047
+ WriteBatch b;
2048
+ const int num = rnd.Uniform(8);
2049
+ for (int i = 0; i < num; i++) {
2050
+ if (i == 0 || !rnd.OneIn(10)) {
2051
+ k = RandomKey(&rnd);
2052
+ } else {
2053
+ // Periodically re-use the same key from the previous iter, so
2054
+ // we have multiple entries in the write batch for the same key
2055
+ }
2056
+ if (rnd.OneIn(2)) {
2057
+ v = RandomString(&rnd, rnd.Uniform(10));
2058
+ b.Put(k, v);
2059
+ } else {
2060
+ b.Delete(k);
2061
+ }
2062
+ }
2063
+ ASSERT_OK(model.Write(WriteOptions(), &b));
2064
+ ASSERT_OK(db_->Write(WriteOptions(), &b));
2065
+ }
2066
+
2067
+ if ((step % 100) == 0) {
2068
+ ASSERT_TRUE(CompareIterators(step, &model, db_, NULL, NULL));
2069
+ ASSERT_TRUE(CompareIterators(step, &model, db_, model_snap, db_snap));
2070
+ // Save a snapshot from each DB this time that we'll use next
2071
+ // time we compare things, to make sure the current state is
2072
+ // preserved with the snapshot
2073
+ if (model_snap != NULL) model.ReleaseSnapshot(model_snap);
2074
+ if (db_snap != NULL) db_->ReleaseSnapshot(db_snap);
2075
+
2076
+ Reopen();
2077
+ ASSERT_TRUE(CompareIterators(step, &model, db_, NULL, NULL));
2078
+
2079
+ model_snap = model.GetSnapshot();
2080
+ db_snap = db_->GetSnapshot();
2081
+ }
2082
+ }
2083
+ if (model_snap != NULL) model.ReleaseSnapshot(model_snap);
2084
+ if (db_snap != NULL) db_->ReleaseSnapshot(db_snap);
2085
+ } while (ChangeOptions());
2086
+ }
2087
+
2088
+ std::string MakeKey(unsigned int num) {
2089
+ char buf[30];
2090
+ snprintf(buf, sizeof(buf), "%016u", num);
2091
+ return std::string(buf);
2092
+ }
2093
+
2094
+ void BM_LogAndApply(int iters, int num_base_files) {
2095
+ std::string dbname = test::TmpDir() + "/leveldb_test_benchmark";
2096
+ DestroyDB(dbname, Options());
2097
+
2098
+ DB* db = NULL;
2099
+ Options opts;
2100
+ opts.create_if_missing = true;
2101
+ Status s = DB::Open(opts, dbname, &db);
2102
+ ASSERT_OK(s);
2103
+ ASSERT_TRUE(db != NULL);
2104
+
2105
+ delete db;
2106
+ db = NULL;
2107
+
2108
+ Env* env = Env::Default();
2109
+
2110
+ port::Mutex mu;
2111
+ MutexLock l(&mu);
2112
+
2113
+ InternalKeyComparator cmp(BytewiseComparator());
2114
+ Options options;
2115
+ VersionSet vset(dbname, &options, NULL, &cmp);
2116
+ bool save_manifest;
2117
+ ASSERT_OK(vset.Recover(&save_manifest));
2118
+ VersionEdit vbase;
2119
+ uint64_t fnum = 1;
2120
+ for (int i = 0; i < num_base_files; i++) {
2121
+ InternalKey start(MakeKey(2*fnum), 1, kTypeValue);
2122
+ InternalKey limit(MakeKey(2*fnum+1), 1, kTypeDeletion);
2123
+ vbase.AddFile(2, fnum++, 1 /* file size */, start, limit);
2124
+ }
2125
+ ASSERT_OK(vset.LogAndApply(&vbase, &mu));
2126
+
2127
+ uint64_t start_micros = env->NowMicros();
2128
+
2129
+ for (int i = 0; i < iters; i++) {
2130
+ VersionEdit vedit;
2131
+ vedit.DeleteFile(2, fnum);
2132
+ InternalKey start(MakeKey(2*fnum), 1, kTypeValue);
2133
+ InternalKey limit(MakeKey(2*fnum+1), 1, kTypeDeletion);
2134
+ vedit.AddFile(2, fnum++, 1 /* file size */, start, limit);
2135
+ vset.LogAndApply(&vedit, &mu);
2136
+ }
2137
+ uint64_t stop_micros = env->NowMicros();
2138
+ unsigned int us = stop_micros - start_micros;
2139
+ char buf[16];
2140
+ snprintf(buf, sizeof(buf), "%d", num_base_files);
2141
+ fprintf(stderr,
2142
+ "BM_LogAndApply/%-6s %8d iters : %9u us (%7.0f us / iter)\n",
2143
+ buf, iters, us, ((float)us) / iters);
2144
+ }
2145
+
2146
+ } // namespace leveldb
2147
+
2148
+ int main(int argc, char** argv) {
2149
+ if (argc > 1 && std::string(argv[1]) == "--benchmark") {
2150
+ leveldb::BM_LogAndApply(1000, 1);
2151
+ leveldb::BM_LogAndApply(1000, 100);
2152
+ leveldb::BM_LogAndApply(1000, 10000);
2153
+ leveldb::BM_LogAndApply(100, 100000);
2154
+ return 0;
2155
+ }
2156
+
2157
+ return leveldb::test::RunAllTests();
2158
+ }