c.cc 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565
  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. #include "leveldb/c.h"
  5. #include <string.h>
  6. #include <cstdint>
  7. #include <cstdlib>
  8. #include "leveldb/cache.h"
  9. #include "leveldb/comparator.h"
  10. #include "leveldb/db.h"
  11. #include "leveldb/env.h"
  12. #include "leveldb/filter_policy.h"
  13. #include "leveldb/iterator.h"
  14. #include "leveldb/options.h"
  15. #include "leveldb/status.h"
  16. #include "leveldb/write_batch.h"
  17. using leveldb::Cache;
  18. using leveldb::Comparator;
  19. using leveldb::CompressionType;
  20. using leveldb::DB;
  21. using leveldb::Env;
  22. using leveldb::FileLock;
  23. using leveldb::FilterPolicy;
  24. using leveldb::Iterator;
  25. using leveldb::kMajorVersion;
  26. using leveldb::kMinorVersion;
  27. using leveldb::Logger;
  28. using leveldb::NewBloomFilterPolicy;
  29. using leveldb::NewLRUCache;
  30. using leveldb::Options;
  31. using leveldb::RandomAccessFile;
  32. using leveldb::Range;
  33. using leveldb::ReadOptions;
  34. using leveldb::SequentialFile;
  35. using leveldb::Slice;
  36. using leveldb::Snapshot;
  37. using leveldb::Status;
  38. using leveldb::WritableFile;
  39. using leveldb::WriteBatch;
  40. using leveldb::WriteOptions;
  41. extern "C" {
  42. struct leveldb_t {
  43. DB* rep;
  44. };
  45. struct leveldb_iterator_t {
  46. Iterator* rep;
  47. };
  48. struct leveldb_writebatch_t {
  49. WriteBatch rep;
  50. };
  51. struct leveldb_snapshot_t {
  52. const Snapshot* rep;
  53. };
  54. struct leveldb_readoptions_t {
  55. ReadOptions rep;
  56. };
  57. struct leveldb_writeoptions_t {
  58. WriteOptions rep;
  59. };
  60. struct leveldb_options_t {
  61. Options rep;
  62. };
  63. struct leveldb_cache_t {
  64. Cache* rep;
  65. };
  66. struct leveldb_seqfile_t {
  67. SequentialFile* rep;
  68. };
  69. struct leveldb_randomfile_t {
  70. RandomAccessFile* rep;
  71. };
  72. struct leveldb_writablefile_t {
  73. WritableFile* rep;
  74. };
  75. struct leveldb_logger_t {
  76. Logger* rep;
  77. };
  78. struct leveldb_filelock_t {
  79. FileLock* rep;
  80. };
  81. struct leveldb_comparator_t : public Comparator {
  82. ~leveldb_comparator_t() override { (*destructor_)(state_); }
  83. int Compare(const Slice& a, const Slice& b) const override {
  84. return (*compare_)(state_, a.data(), a.size(), b.data(), b.size());
  85. }
  86. const char* Name() const override { return (*name_)(state_); }
  87. // No-ops since the C binding does not support key shortening methods.
  88. void FindShortestSeparator(std::string*, const Slice&) const override {}
  89. void FindShortSuccessor(std::string* key) const override {}
  90. void* state_;
  91. void (*destructor_)(void*);
  92. int (*compare_)(void*, const char* a, size_t alen, const char* b,
  93. size_t blen);
  94. const char* (*name_)(void*);
  95. };
  96. struct leveldb_filterpolicy_t : public FilterPolicy {
  97. ~leveldb_filterpolicy_t() override { (*destructor_)(state_); }
  98. const char* Name() const override { return (*name_)(state_); }
  99. void CreateFilter(const Slice* keys, int n, std::string* dst) const override {
  100. std::vector<const char*> key_pointers(n);
  101. std::vector<size_t> key_sizes(n);
  102. for (int i = 0; i < n; i++) {
  103. key_pointers[i] = keys[i].data();
  104. key_sizes[i] = keys[i].size();
  105. }
  106. size_t len;
  107. char* filter = (*create_)(state_, &key_pointers[0], &key_sizes[0], n, &len);
  108. dst->append(filter, len);
  109. std::free(filter);
  110. }
  111. bool KeyMayMatch(const Slice& key, const Slice& filter) const override {
  112. return (*key_match_)(state_, key.data(), key.size(), filter.data(),
  113. filter.size());
  114. }
  115. void* state_;
  116. void (*destructor_)(void*);
  117. const char* (*name_)(void*);
  118. char* (*create_)(void*, const char* const* key_array,
  119. const size_t* key_length_array, int num_keys,
  120. size_t* filter_length);
  121. uint8_t (*key_match_)(void*, const char* key, size_t length,
  122. const char* filter, size_t filter_length);
  123. };
  124. struct leveldb_env_t {
  125. Env* rep;
  126. bool is_default;
  127. };
  128. static bool SaveError(char** errptr, const Status& s) {
  129. assert(errptr != nullptr);
  130. if (s.ok()) {
  131. return false;
  132. } else if (*errptr == nullptr) {
  133. *errptr = strdup(s.ToString().c_str());
  134. } else {
  135. // TODO(sanjay): Merge with existing error?
  136. std::free(*errptr);
  137. *errptr = strdup(s.ToString().c_str());
  138. }
  139. return true;
  140. }
  141. static char* CopyString(const std::string& str) {
  142. char* result =
  143. reinterpret_cast<char*>(std::malloc(sizeof(char) * str.size()));
  144. std::memcpy(result, str.data(), sizeof(char) * str.size());
  145. return result;
  146. }
  147. leveldb_t* leveldb_open(const leveldb_options_t* options, const char* name,
  148. char** errptr) {
  149. DB* db;
  150. if (SaveError(errptr, DB::Open(options->rep, std::string(name), &db))) {
  151. return nullptr;
  152. }
  153. leveldb_t* result = new leveldb_t;
  154. result->rep = db;
  155. return result;
  156. }
  157. void leveldb_close(leveldb_t* db) {
  158. delete db->rep;
  159. delete db;
  160. }
  161. void leveldb_put(leveldb_t* db, const leveldb_writeoptions_t* options,
  162. const char* key, size_t keylen, const char* val, size_t vallen,
  163. char** errptr) {
  164. SaveError(errptr,
  165. db->rep->Put(options->rep, Slice(key, keylen), Slice(val, vallen)));
  166. }
  167. void leveldb_delete(leveldb_t* db, const leveldb_writeoptions_t* options,
  168. const char* key, size_t keylen, char** errptr) {
  169. SaveError(errptr, db->rep->Delete(options->rep, Slice(key, keylen)));
  170. }
  171. void leveldb_write(leveldb_t* db, const leveldb_writeoptions_t* options,
  172. leveldb_writebatch_t* batch, char** errptr) {
  173. SaveError(errptr, db->rep->Write(options->rep, &batch->rep));
  174. }
  175. char* leveldb_get(leveldb_t* db, const leveldb_readoptions_t* options,
  176. const char* key, size_t keylen, size_t* vallen,
  177. char** errptr) {
  178. char* result = nullptr;
  179. std::string tmp;
  180. Status s = db->rep->Get(options->rep, Slice(key, keylen), &tmp);
  181. if (s.ok()) {
  182. *vallen = tmp.size();
  183. result = CopyString(tmp);
  184. } else {
  185. *vallen = 0;
  186. if (!s.IsNotFound()) {
  187. SaveError(errptr, s);
  188. }
  189. }
  190. return result;
  191. }
  192. leveldb_iterator_t* leveldb_create_iterator(
  193. leveldb_t* db, const leveldb_readoptions_t* options) {
  194. leveldb_iterator_t* result = new leveldb_iterator_t;
  195. result->rep = db->rep->NewIterator(options->rep);
  196. return result;
  197. }
  198. const leveldb_snapshot_t* leveldb_create_snapshot(leveldb_t* db) {
  199. leveldb_snapshot_t* result = new leveldb_snapshot_t;
  200. result->rep = db->rep->GetSnapshot();
  201. return result;
  202. }
  203. void leveldb_release_snapshot(leveldb_t* db,
  204. const leveldb_snapshot_t* snapshot) {
  205. db->rep->ReleaseSnapshot(snapshot->rep);
  206. delete snapshot;
  207. }
  208. char* leveldb_property_value(leveldb_t* db, const char* propname) {
  209. std::string tmp;
  210. if (db->rep->GetProperty(Slice(propname), &tmp)) {
  211. // We use strdup() since we expect human readable output.
  212. return strdup(tmp.c_str());
  213. } else {
  214. return nullptr;
  215. }
  216. }
  217. void leveldb_approximate_sizes(leveldb_t* db, int num_ranges,
  218. const char* const* range_start_key,
  219. const size_t* range_start_key_len,
  220. const char* const* range_limit_key,
  221. const size_t* range_limit_key_len,
  222. uint64_t* sizes) {
  223. Range* ranges = new Range[num_ranges];
  224. for (int i = 0; i < num_ranges; i++) {
  225. ranges[i].start = Slice(range_start_key[i], range_start_key_len[i]);
  226. ranges[i].limit = Slice(range_limit_key[i], range_limit_key_len[i]);
  227. }
  228. db->rep->GetApproximateSizes(ranges, num_ranges, sizes);
  229. delete[] ranges;
  230. }
  231. void leveldb_compact_range(leveldb_t* db, const char* start_key,
  232. size_t start_key_len, const char* limit_key,
  233. size_t limit_key_len) {
  234. Slice a, b;
  235. db->rep->CompactRange(
  236. // Pass null Slice if corresponding "const char*" is null
  237. (start_key ? (a = Slice(start_key, start_key_len), &a) : nullptr),
  238. (limit_key ? (b = Slice(limit_key, limit_key_len), &b) : nullptr));
  239. }
  240. void leveldb_destroy_db(const leveldb_options_t* options, const char* name,
  241. char** errptr) {
  242. SaveError(errptr, DestroyDB(name, options->rep));
  243. }
  244. void leveldb_repair_db(const leveldb_options_t* options, const char* name,
  245. char** errptr) {
  246. SaveError(errptr, RepairDB(name, options->rep));
  247. }
  248. void leveldb_iter_destroy(leveldb_iterator_t* iter) {
  249. delete iter->rep;
  250. delete iter;
  251. }
  252. uint8_t leveldb_iter_valid(const leveldb_iterator_t* iter) {
  253. return iter->rep->Valid();
  254. }
  255. void leveldb_iter_seek_to_first(leveldb_iterator_t* iter) {
  256. iter->rep->SeekToFirst();
  257. }
  258. void leveldb_iter_seek_to_last(leveldb_iterator_t* iter) {
  259. iter->rep->SeekToLast();
  260. }
  261. void leveldb_iter_seek(leveldb_iterator_t* iter, const char* k, size_t klen) {
  262. iter->rep->Seek(Slice(k, klen));
  263. }
  264. void leveldb_iter_next(leveldb_iterator_t* iter) { iter->rep->Next(); }
  265. void leveldb_iter_prev(leveldb_iterator_t* iter) { iter->rep->Prev(); }
  266. const char* leveldb_iter_key(const leveldb_iterator_t* iter, size_t* klen) {
  267. Slice s = iter->rep->key();
  268. *klen = s.size();
  269. return s.data();
  270. }
  271. const char* leveldb_iter_value(const leveldb_iterator_t* iter, size_t* vlen) {
  272. Slice s = iter->rep->value();
  273. *vlen = s.size();
  274. return s.data();
  275. }
  276. void leveldb_iter_get_error(const leveldb_iterator_t* iter, char** errptr) {
  277. SaveError(errptr, iter->rep->status());
  278. }
  279. leveldb_writebatch_t* leveldb_writebatch_create() {
  280. return new leveldb_writebatch_t;
  281. }
  282. void leveldb_writebatch_destroy(leveldb_writebatch_t* b) { delete b; }
  283. void leveldb_writebatch_clear(leveldb_writebatch_t* b) { b->rep.Clear(); }
  284. void leveldb_writebatch_put(leveldb_writebatch_t* b, const char* key,
  285. size_t klen, const char* val, size_t vlen) {
  286. b->rep.Put(Slice(key, klen), Slice(val, vlen));
  287. }
  288. void leveldb_writebatch_delete(leveldb_writebatch_t* b, const char* key,
  289. size_t klen) {
  290. b->rep.Delete(Slice(key, klen));
  291. }
  292. void leveldb_writebatch_iterate(const leveldb_writebatch_t* b, void* state,
  293. void (*put)(void*, const char* k, size_t klen,
  294. const char* v, size_t vlen),
  295. void (*deleted)(void*, const char* k,
  296. size_t klen)) {
  297. class H : public WriteBatch::Handler {
  298. public:
  299. void* state_;
  300. void (*put_)(void*, const char* k, size_t klen, const char* v, size_t vlen);
  301. void (*deleted_)(void*, const char* k, size_t klen);
  302. void Put(const Slice& key, const Slice& value) override {
  303. (*put_)(state_, key.data(), key.size(), value.data(), value.size());
  304. }
  305. void Delete(const Slice& key) override {
  306. (*deleted_)(state_, key.data(), key.size());
  307. }
  308. };
  309. H handler;
  310. handler.state_ = state;
  311. handler.put_ = put;
  312. handler.deleted_ = deleted;
  313. b->rep.Iterate(&handler);
  314. }
  315. void leveldb_writebatch_append(leveldb_writebatch_t* destination,
  316. const leveldb_writebatch_t* source) {
  317. destination->rep.Append(source->rep);
  318. }
  319. leveldb_options_t* leveldb_options_create() { return new leveldb_options_t; }
  320. void leveldb_options_destroy(leveldb_options_t* options) { delete options; }
  321. void leveldb_options_set_comparator(leveldb_options_t* opt,
  322. leveldb_comparator_t* cmp) {
  323. opt->rep.comparator = cmp;
  324. }
  325. void leveldb_options_set_filter_policy(leveldb_options_t* opt,
  326. leveldb_filterpolicy_t* policy) {
  327. opt->rep.filter_policy = policy;
  328. }
  329. void leveldb_options_set_create_if_missing(leveldb_options_t* opt, uint8_t v) {
  330. opt->rep.create_if_missing = v;
  331. }
  332. void leveldb_options_set_error_if_exists(leveldb_options_t* opt, uint8_t v) {
  333. opt->rep.error_if_exists = v;
  334. }
  335. void leveldb_options_set_paranoid_checks(leveldb_options_t* opt, uint8_t v) {
  336. opt->rep.paranoid_checks = v;
  337. }
  338. void leveldb_options_set_env(leveldb_options_t* opt, leveldb_env_t* env) {
  339. opt->rep.env = (env ? env->rep : nullptr);
  340. }
  341. void leveldb_options_set_info_log(leveldb_options_t* opt, leveldb_logger_t* l) {
  342. opt->rep.info_log = (l ? l->rep : nullptr);
  343. }
  344. void leveldb_options_set_write_buffer_size(leveldb_options_t* opt, size_t s) {
  345. opt->rep.write_buffer_size = s;
  346. }
  347. void leveldb_options_set_max_open_files(leveldb_options_t* opt, int n) {
  348. opt->rep.max_open_files = n;
  349. }
  350. void leveldb_options_set_cache(leveldb_options_t* opt, leveldb_cache_t* c) {
  351. opt->rep.block_cache = c->rep;
  352. }
  353. void leveldb_options_set_block_size(leveldb_options_t* opt, size_t s) {
  354. opt->rep.block_size = s;
  355. }
  356. void leveldb_options_set_block_restart_interval(leveldb_options_t* opt, int n) {
  357. opt->rep.block_restart_interval = n;
  358. }
  359. void leveldb_options_set_max_file_size(leveldb_options_t* opt, size_t s) {
  360. opt->rep.max_file_size = s;
  361. }
  362. void leveldb_options_set_compression(leveldb_options_t* opt, int t) {
  363. opt->rep.compression = static_cast<CompressionType>(t);
  364. }
  365. leveldb_comparator_t* leveldb_comparator_create(
  366. void* state, void (*destructor)(void*),
  367. int (*compare)(void*, const char* a, size_t alen, const char* b,
  368. size_t blen),
  369. const char* (*name)(void*)) {
  370. leveldb_comparator_t* result = new leveldb_comparator_t;
  371. result->state_ = state;
  372. result->destructor_ = destructor;
  373. result->compare_ = compare;
  374. result->name_ = name;
  375. return result;
  376. }
  377. void leveldb_comparator_destroy(leveldb_comparator_t* cmp) { delete cmp; }
  378. leveldb_filterpolicy_t* leveldb_filterpolicy_create(
  379. void* state, void (*destructor)(void*),
  380. char* (*create_filter)(void*, const char* const* key_array,
  381. const size_t* key_length_array, int num_keys,
  382. size_t* filter_length),
  383. uint8_t (*key_may_match)(void*, const char* key, size_t length,
  384. const char* filter, size_t filter_length),
  385. const char* (*name)(void*)) {
  386. leveldb_filterpolicy_t* result = new leveldb_filterpolicy_t;
  387. result->state_ = state;
  388. result->destructor_ = destructor;
  389. result->create_ = create_filter;
  390. result->key_match_ = key_may_match;
  391. result->name_ = name;
  392. return result;
  393. }
  394. void leveldb_filterpolicy_destroy(leveldb_filterpolicy_t* filter) {
  395. delete filter;
  396. }
  397. leveldb_filterpolicy_t* leveldb_filterpolicy_create_bloom(int bits_per_key) {
  398. // Make a leveldb_filterpolicy_t, but override all of its methods so
  399. // they delegate to a NewBloomFilterPolicy() instead of user
  400. // supplied C functions.
  401. struct Wrapper : public leveldb_filterpolicy_t {
  402. static void DoNothing(void*) {}
  403. ~Wrapper() { delete rep_; }
  404. const char* Name() const { return rep_->Name(); }
  405. void CreateFilter(const Slice* keys, int n, std::string* dst) const {
  406. return rep_->CreateFilter(keys, n, dst);
  407. }
  408. bool KeyMayMatch(const Slice& key, const Slice& filter) const {
  409. return rep_->KeyMayMatch(key, filter);
  410. }
  411. const FilterPolicy* rep_;
  412. };
  413. Wrapper* wrapper = new Wrapper;
  414. wrapper->rep_ = NewBloomFilterPolicy(bits_per_key);
  415. wrapper->state_ = nullptr;
  416. wrapper->destructor_ = &Wrapper::DoNothing;
  417. return wrapper;
  418. }
  419. leveldb_readoptions_t* leveldb_readoptions_create() {
  420. return new leveldb_readoptions_t;
  421. }
  422. void leveldb_readoptions_destroy(leveldb_readoptions_t* opt) { delete opt; }
  423. void leveldb_readoptions_set_verify_checksums(leveldb_readoptions_t* opt,
  424. uint8_t v) {
  425. opt->rep.verify_checksums = v;
  426. }
  427. void leveldb_readoptions_set_fill_cache(leveldb_readoptions_t* opt, uint8_t v) {
  428. opt->rep.fill_cache = v;
  429. }
  430. void leveldb_readoptions_set_snapshot(leveldb_readoptions_t* opt,
  431. const leveldb_snapshot_t* snap) {
  432. opt->rep.snapshot = (snap ? snap->rep : nullptr);
  433. }
  434. leveldb_writeoptions_t* leveldb_writeoptions_create() {
  435. return new leveldb_writeoptions_t;
  436. }
  437. void leveldb_writeoptions_destroy(leveldb_writeoptions_t* opt) { delete opt; }
  438. void leveldb_writeoptions_set_sync(leveldb_writeoptions_t* opt, uint8_t v) {
  439. opt->rep.sync = v;
  440. }
  441. leveldb_cache_t* leveldb_cache_create_lru(size_t capacity) {
  442. leveldb_cache_t* c = new leveldb_cache_t;
  443. c->rep = NewLRUCache(capacity);
  444. return c;
  445. }
  446. void leveldb_cache_destroy(leveldb_cache_t* cache) {
  447. delete cache->rep;
  448. delete cache;
  449. }
  450. leveldb_env_t* leveldb_create_default_env() {
  451. leveldb_env_t* result = new leveldb_env_t;
  452. result->rep = Env::Default();
  453. result->is_default = true;
  454. return result;
  455. }
  456. void leveldb_env_destroy(leveldb_env_t* env) {
  457. if (!env->is_default) delete env->rep;
  458. delete env;
  459. }
  460. char* leveldb_env_get_test_directory(leveldb_env_t* env) {
  461. std::string result;
  462. if (!env->rep->GetTestDirectory(&result).ok()) {
  463. return nullptr;
  464. }
  465. char* buffer = static_cast<char*>(std::malloc(result.size() + 1));
  466. std::memcpy(buffer, result.data(), result.size());
  467. buffer[result.size()] = '\0';
  468. return buffer;
  469. }
  470. void leveldb_free(void* ptr) { std::free(ptr); }
  471. int leveldb_major_version() { return kMajorVersion; }
  472. int leveldb_minor_version() { return kMinorVersion; }
  473. } // end extern "C"