小组成员:谢瑞阳、徐翔宇
Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

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