小组成员:10215300402-朱维清 & 10222140408 谷杰
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

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