c.cc 16 KB

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