作者: 谢瑞阳 10225101483 徐翔宇 10225101535

615 行
16 KiB

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