leveldb-ruby 0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (113) hide show
  1. data/README +17 -0
  2. data/ext/leveldb/extconf.rb +10 -0
  3. data/ext/leveldb/leveldb.cc +181 -0
  4. data/leveldb/Makefile +172 -0
  5. data/leveldb/db/builder.cc +90 -0
  6. data/leveldb/db/builder.h +36 -0
  7. data/leveldb/db/corruption_test.cc +354 -0
  8. data/leveldb/db/db_bench.cc +677 -0
  9. data/leveldb/db/db_impl.cc +1236 -0
  10. data/leveldb/db/db_impl.h +180 -0
  11. data/leveldb/db/db_iter.cc +298 -0
  12. data/leveldb/db/db_iter.h +26 -0
  13. data/leveldb/db/db_test.cc +1192 -0
  14. data/leveldb/db/dbformat.cc +87 -0
  15. data/leveldb/db/dbformat.h +165 -0
  16. data/leveldb/db/dbformat_test.cc +112 -0
  17. data/leveldb/db/filename.cc +135 -0
  18. data/leveldb/db/filename.h +80 -0
  19. data/leveldb/db/filename_test.cc +122 -0
  20. data/leveldb/db/log_format.h +35 -0
  21. data/leveldb/db/log_reader.cc +254 -0
  22. data/leveldb/db/log_reader.h +108 -0
  23. data/leveldb/db/log_test.cc +500 -0
  24. data/leveldb/db/log_writer.cc +103 -0
  25. data/leveldb/db/log_writer.h +48 -0
  26. data/leveldb/db/memtable.cc +108 -0
  27. data/leveldb/db/memtable.h +85 -0
  28. data/leveldb/db/repair.cc +384 -0
  29. data/leveldb/db/skiplist.h +378 -0
  30. data/leveldb/db/skiplist_test.cc +378 -0
  31. data/leveldb/db/snapshot.h +66 -0
  32. data/leveldb/db/table_cache.cc +95 -0
  33. data/leveldb/db/table_cache.h +50 -0
  34. data/leveldb/db/version_edit.cc +268 -0
  35. data/leveldb/db/version_edit.h +106 -0
  36. data/leveldb/db/version_edit_test.cc +46 -0
  37. data/leveldb/db/version_set.cc +1060 -0
  38. data/leveldb/db/version_set.h +306 -0
  39. data/leveldb/db/write_batch.cc +138 -0
  40. data/leveldb/db/write_batch_internal.h +45 -0
  41. data/leveldb/db/write_batch_test.cc +89 -0
  42. data/leveldb/include/leveldb/cache.h +99 -0
  43. data/leveldb/include/leveldb/comparator.h +63 -0
  44. data/leveldb/include/leveldb/db.h +148 -0
  45. data/leveldb/include/leveldb/env.h +302 -0
  46. data/leveldb/include/leveldb/iterator.h +100 -0
  47. data/leveldb/include/leveldb/options.h +198 -0
  48. data/leveldb/include/leveldb/slice.h +109 -0
  49. data/leveldb/include/leveldb/status.h +100 -0
  50. data/leveldb/include/leveldb/table.h +70 -0
  51. data/leveldb/include/leveldb/table_builder.h +91 -0
  52. data/leveldb/include/leveldb/write_batch.h +64 -0
  53. data/leveldb/port/port.h +23 -0
  54. data/leveldb/port/port_android.cc +64 -0
  55. data/leveldb/port/port_android.h +150 -0
  56. data/leveldb/port/port_chromium.cc +80 -0
  57. data/leveldb/port/port_chromium.h +97 -0
  58. data/leveldb/port/port_example.h +115 -0
  59. data/leveldb/port/port_osx.cc +50 -0
  60. data/leveldb/port/port_osx.h +125 -0
  61. data/leveldb/port/port_posix.cc +50 -0
  62. data/leveldb/port/port_posix.h +94 -0
  63. data/leveldb/port/sha1_portable.cc +298 -0
  64. data/leveldb/port/sha1_portable.h +25 -0
  65. data/leveldb/port/sha1_test.cc +39 -0
  66. data/leveldb/port/win/stdint.h +24 -0
  67. data/leveldb/table/block.cc +263 -0
  68. data/leveldb/table/block.h +43 -0
  69. data/leveldb/table/block_builder.cc +109 -0
  70. data/leveldb/table/block_builder.h +57 -0
  71. data/leveldb/table/format.cc +131 -0
  72. data/leveldb/table/format.h +103 -0
  73. data/leveldb/table/iterator.cc +67 -0
  74. data/leveldb/table/iterator_wrapper.h +63 -0
  75. data/leveldb/table/merger.cc +197 -0
  76. data/leveldb/table/merger.h +26 -0
  77. data/leveldb/table/table.cc +175 -0
  78. data/leveldb/table/table_builder.cc +227 -0
  79. data/leveldb/table/table_test.cc +845 -0
  80. data/leveldb/table/two_level_iterator.cc +182 -0
  81. data/leveldb/table/two_level_iterator.h +34 -0
  82. data/leveldb/util/arena.cc +68 -0
  83. data/leveldb/util/arena.h +68 -0
  84. data/leveldb/util/arena_test.cc +68 -0
  85. data/leveldb/util/cache.cc +255 -0
  86. data/leveldb/util/cache_test.cc +169 -0
  87. data/leveldb/util/coding.cc +194 -0
  88. data/leveldb/util/coding.h +104 -0
  89. data/leveldb/util/coding_test.cc +173 -0
  90. data/leveldb/util/comparator.cc +72 -0
  91. data/leveldb/util/crc32c.cc +332 -0
  92. data/leveldb/util/crc32c.h +45 -0
  93. data/leveldb/util/crc32c_test.cc +72 -0
  94. data/leveldb/util/env.cc +77 -0
  95. data/leveldb/util/env_chromium.cc +612 -0
  96. data/leveldb/util/env_posix.cc +606 -0
  97. data/leveldb/util/env_test.cc +102 -0
  98. data/leveldb/util/hash.cc +45 -0
  99. data/leveldb/util/hash.h +19 -0
  100. data/leveldb/util/histogram.cc +128 -0
  101. data/leveldb/util/histogram.h +41 -0
  102. data/leveldb/util/logging.cc +81 -0
  103. data/leveldb/util/logging.h +47 -0
  104. data/leveldb/util/mutexlock.h +39 -0
  105. data/leveldb/util/options.cc +28 -0
  106. data/leveldb/util/random.h +59 -0
  107. data/leveldb/util/status.cc +75 -0
  108. data/leveldb/util/testharness.cc +65 -0
  109. data/leveldb/util/testharness.h +129 -0
  110. data/leveldb/util/testutil.cc +51 -0
  111. data/leveldb/util/testutil.h +53 -0
  112. data/lib/leveldb.rb +36 -0
  113. metadata +183 -0
data/README ADDED
@@ -0,0 +1,17 @@
1
+ LevelDB Ruby bindings.
2
+
3
+ Do this:
4
+
5
+ gem install leveldb-ruby
6
+
7
+
8
+ And then run this:
9
+
10
+ require 'rubygems' # on ruby < 1.9
11
+ require 'leveldb'
12
+
13
+ db = LevelDB.new "/tmp/asdf"
14
+ db.put "it", "works"
15
+ db.get "it"
16
+
17
+ Only a very few operations are supported right now:
@@ -0,0 +1,10 @@
1
+ require 'mkmf'
2
+ require 'fileutils'
3
+
4
+ Dir.chdir "../../leveldb"
5
+ system "make libleveldb.a" or abort
6
+ Dir.chdir "../ext/leveldb"
7
+
8
+ $CFLAGS << " -I../../leveldb/include"
9
+ $LIBS << " -L../../leveldb -Wl,--whole-archive -lleveldb -Wl,--no-whole-archive"
10
+ create_makefile "leveldb/leveldb"
@@ -0,0 +1,181 @@
1
+ #include <ruby.h>
2
+
3
+ #include "leveldb/db.h"
4
+ #include "leveldb/write_batch.h"
5
+
6
+ static VALUE m_leveldb;
7
+ static VALUE c_db;
8
+ static VALUE c_error;
9
+
10
+ // support 1.9 and 1.8
11
+ #ifndef RSTRING_PTR
12
+ #define RSTRING_PTR(v) RSTRING(v)->ptr
13
+ #endif
14
+
15
+ // convert status errors into exceptions
16
+ #define RAISE_ON_ERROR(status) do { \
17
+ if(!status.ok()) { \
18
+ VALUE exc = rb_exc_new2(c_error, status.ToString().c_str()); \
19
+ rb_exc_raise(exc); \
20
+ } \
21
+ } while(0)
22
+
23
+ typedef struct bound_db {
24
+ leveldb::DB* db;
25
+ } bound_db;
26
+
27
+ static void db_free(bound_db* db) {
28
+ delete db->db;
29
+ }
30
+
31
+ static VALUE db_make(VALUE klass, VALUE v_pathname, VALUE v_create_if_necessary, VALUE v_break_if_exists) {
32
+ Check_Type(v_pathname, T_STRING);
33
+
34
+ bound_db* db = new bound_db;
35
+ char* pathname_c = RSTRING_PTR(v_pathname);
36
+ std::string pathname = std::string((char*)RSTRING_PTR(v_pathname));
37
+
38
+ leveldb::Options options;
39
+ if(RTEST(v_create_if_necessary)) options.create_if_missing = true;
40
+ if(RTEST(v_break_if_exists)) options.error_if_exists = true;
41
+ leveldb::Status status = leveldb::DB::Open(options, pathname, &db->db);
42
+ RAISE_ON_ERROR(status);
43
+
44
+ VALUE o_db = Data_Wrap_Struct(klass, NULL, db_free, db);
45
+ VALUE argv[1] = { v_pathname };
46
+ rb_obj_call_init(o_db, 1, argv);
47
+
48
+ return o_db;
49
+ }
50
+
51
+ static VALUE db_close(VALUE self) {
52
+ bound_db* db;
53
+ Data_Get_Struct(self, bound_db, db);
54
+
55
+ db_free(db);
56
+ return Qtrue;
57
+ }
58
+
59
+ static VALUE db_get(VALUE self, VALUE v_key) {
60
+ Check_Type(v_key, T_STRING);
61
+
62
+ bound_db* db;
63
+ Data_Get_Struct(self, bound_db, db);
64
+
65
+ std::string key = std::string((char*)RSTRING_PTR(v_key));
66
+ std::string value;
67
+ leveldb::Status status = db->db->Get(leveldb::ReadOptions(), key, &value);
68
+ if(status.IsNotFound()) return Qnil;
69
+
70
+ RAISE_ON_ERROR(status);
71
+ return rb_str_new2(value.c_str());
72
+ }
73
+
74
+ static VALUE db_delete(VALUE self, VALUE v_key) {
75
+ Check_Type(v_key, T_STRING);
76
+
77
+ bound_db* db;
78
+ Data_Get_Struct(self, bound_db, db);
79
+
80
+ std::string key = std::string((char*)RSTRING_PTR(v_key));
81
+ std::string value;
82
+ leveldb::Status status = db->db->Get(leveldb::ReadOptions(), key, &value);
83
+
84
+ if(status.IsNotFound()) return Qnil;
85
+
86
+ status = db->db->Delete(leveldb::WriteOptions(), key);
87
+ RAISE_ON_ERROR(status);
88
+
89
+ return rb_str_new2(value.c_str());
90
+ }
91
+
92
+ static VALUE db_exists(VALUE self, VALUE v_key) {
93
+ Check_Type(v_key, T_STRING);
94
+
95
+ bound_db* db;
96
+ Data_Get_Struct(self, bound_db, db);
97
+
98
+ std::string key = std::string((char*)RSTRING_PTR(v_key));
99
+ std::string value;
100
+ leveldb::Status status = db->db->Get(leveldb::ReadOptions(), key, &value);
101
+
102
+ if(status.IsNotFound()) return Qfalse;
103
+ return Qtrue;
104
+ }
105
+
106
+ static VALUE db_put(VALUE self, VALUE v_key, VALUE v_value) {
107
+ Check_Type(v_key, T_STRING);
108
+ Check_Type(v_value, T_STRING);
109
+
110
+ bound_db* db;
111
+ Data_Get_Struct(self, bound_db, db);
112
+
113
+ std::string key = std::string((char*)RSTRING_PTR(v_key));
114
+ std::string value = std::string((char*)RSTRING_PTR(v_value));
115
+
116
+ leveldb::Status status = db->db->Put(leveldb::WriteOptions(), key, value);
117
+
118
+ RAISE_ON_ERROR(status);
119
+
120
+ return v_value;
121
+ }
122
+
123
+ static VALUE db_size(VALUE self) {
124
+ long count = 0;
125
+
126
+ bound_db* db;
127
+ Data_Get_Struct(self, bound_db, db);
128
+ leveldb::Iterator* it = db->db->NewIterator(leveldb::ReadOptions());
129
+
130
+ // apparently this is how we have to do it. slow and painful!
131
+ for (it->SeekToFirst(); it->Valid(); it->Next()) count++;
132
+ RAISE_ON_ERROR(it->status());
133
+ delete it;
134
+ return INT2NUM(count);
135
+ }
136
+
137
+ static VALUE db_each(VALUE self) {
138
+ bound_db* db;
139
+ Data_Get_Struct(self, bound_db, db);
140
+ leveldb::Iterator* it = db->db->NewIterator(leveldb::ReadOptions());
141
+
142
+ for (it->SeekToFirst(); it->Valid(); it->Next()) {
143
+ VALUE key = rb_str_new2(it->key().ToString().c_str());
144
+ VALUE value = rb_str_new2(it->value().ToString().c_str());
145
+ VALUE ary = rb_ary_new2(2);
146
+ rb_ary_push(ary, key);
147
+ rb_ary_push(ary, value);
148
+ rb_yield(ary);
149
+ }
150
+
151
+ RAISE_ON_ERROR(it->status());
152
+ delete it;
153
+
154
+ return self;
155
+ }
156
+
157
+ static VALUE db_init(VALUE self, VALUE v_pathname) {
158
+ rb_iv_set(self, "@pathname", v_pathname);
159
+ return self;
160
+ }
161
+
162
+ extern "C" {
163
+ void Init_leveldb() {
164
+ VALUE m_leveldb;
165
+
166
+ m_leveldb = rb_define_module("LevelDB");
167
+
168
+ c_db = rb_define_class_under(m_leveldb, "DB", rb_cObject);
169
+ rb_define_singleton_method(c_db, "make", (VALUE (*)(...))db_make, 3);
170
+ rb_define_method(c_db, "initialize", (VALUE (*)(...))db_init, 1);
171
+ rb_define_method(c_db, "get", (VALUE (*)(...))db_get, 1);
172
+ rb_define_method(c_db, "delete", (VALUE (*)(...))db_delete, 1);
173
+ rb_define_method(c_db, "put", (VALUE (*)(...))db_put, 2);
174
+ rb_define_method(c_db, "exists?", (VALUE (*)(...))db_exists, 1);
175
+ rb_define_method(c_db, "close", (VALUE (*)(...))db_close, 0);
176
+ rb_define_method(c_db, "size", (VALUE (*)(...))db_size, 0);
177
+ rb_define_method(c_db, "each", (VALUE (*)(...))db_each, 0);
178
+
179
+ c_error = rb_define_class_under(m_leveldb, "Error", rb_eStandardError);
180
+ }
181
+ }
@@ -0,0 +1,172 @@
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
+
5
+ CC = g++
6
+
7
+ #-----------------------------------------------
8
+ # Uncomment exactly one of the lines labelled (A), (B), and (C) below
9
+ # to switch between compilation modes.
10
+
11
+ OPT = -O2 -DNDEBUG # (A) Production use (optimized mode)
12
+ # OPT = -g2 # (B) Debug mode, w/ full line-level debugging symbols
13
+ # OPT = -O2 -g2 -DNDEBUG # (C) Profiling mode: opt, but w/debugging symbols
14
+ #-----------------------------------------------
15
+
16
+
17
+ UNAME := $(shell uname)
18
+
19
+ ifeq ($(UNAME), Darwin)
20
+ # To build for iOS, set PLATFORM=IOS.
21
+ ifndef PLATFORM
22
+ PLATFORM=OSX
23
+ endif # PLATFORM
24
+ PLATFORM_CFLAGS = -DLEVELDB_PLATFORM_OSX
25
+ PORT_MODULE = port_osx.o
26
+ else # UNAME
27
+ PLATFORM_CFLAGS = -DLEVELDB_PLATFORM_POSIX -std=c++0x
28
+ PORT_MODULE = port_posix.o
29
+ endif # UNAME
30
+
31
+ CFLAGS = -c -I. -I./include $(PLATFORM_CFLAGS) $(OPT) -DUSE_SNAPPY=1
32
+
33
+ LDFLAGS=-lpthread
34
+
35
+ LIBOBJECTS = \
36
+ ./db/builder.o \
37
+ ./db/db_impl.o \
38
+ ./db/db_iter.o \
39
+ ./db/filename.o \
40
+ ./db/dbformat.o \
41
+ ./db/log_reader.o \
42
+ ./db/log_writer.o \
43
+ ./db/memtable.o \
44
+ ./db/repair.o \
45
+ ./db/table_cache.o \
46
+ ./db/version_edit.o \
47
+ ./db/version_set.o \
48
+ ./db/write_batch.o \
49
+ ./port/$(PORT_MODULE) \
50
+ ./table/block.o \
51
+ ./table/block_builder.o \
52
+ ./table/format.o \
53
+ ./table/iterator.o \
54
+ ./table/merger.o \
55
+ ./table/table.o \
56
+ ./table/table_builder.o \
57
+ ./table/two_level_iterator.o \
58
+ ./util/arena.o \
59
+ ./util/cache.o \
60
+ ./util/coding.o \
61
+ ./util/comparator.o \
62
+ ./util/crc32c.o \
63
+ ./util/env.o \
64
+ ./util/env_posix.o \
65
+ ./util/hash.o \
66
+ ./util/histogram.o \
67
+ ./util/logging.o \
68
+ ./util/options.o \
69
+ ./util/status.o
70
+
71
+ TESTUTIL = ./util/testutil.o
72
+ TESTHARNESS = ./util/testharness.o $(TESTUTIL)
73
+
74
+ TESTS = \
75
+ arena_test \
76
+ cache_test \
77
+ coding_test \
78
+ corruption_test \
79
+ crc32c_test \
80
+ db_test \
81
+ dbformat_test \
82
+ env_test \
83
+ filename_test \
84
+ log_test \
85
+ skiplist_test \
86
+ table_test \
87
+ version_edit_test \
88
+ write_batch_test
89
+
90
+ PROGRAMS = db_bench $(TESTS)
91
+
92
+ LIBRARY = libleveldb.a
93
+
94
+ ifeq ($(PLATFORM), IOS)
95
+ # Only XCode can build executable applications for iOS.
96
+ all: $(LIBRARY)
97
+ else
98
+ all: $(PROGRAMS) $(LIBRARY)
99
+ endif
100
+
101
+ check: $(TESTS)
102
+ for t in $(TESTS); do echo "***** Running $$t"; ./$$t || exit 1; done
103
+
104
+ clean:
105
+ -rm -f $(PROGRAMS) $(LIBRARY) */*.o ios-x86/*/*.o ios-arm/*/*.o
106
+ -rmdir -p ios-x86/* ios-arm/*
107
+
108
+ $(LIBRARY): $(LIBOBJECTS)
109
+ rm -f $@
110
+ $(AR) -rs $@ $(LIBOBJECTS)
111
+
112
+ db_bench: db/db_bench.o $(LIBOBJECTS) $(TESTUTIL)
113
+ $(CC) $(LDFLAGS) db/db_bench.o $(LIBOBJECTS) $(TESTUTIL) -o $@
114
+
115
+ arena_test: util/arena_test.o $(LIBOBJECTS) $(TESTHARNESS)
116
+ $(CC) $(LDFLAGS) util/arena_test.o $(LIBOBJECTS) $(TESTHARNESS) -o $@
117
+
118
+ cache_test: util/cache_test.o $(LIBOBJECTS) $(TESTHARNESS)
119
+ $(CC) $(LDFLAGS) util/cache_test.o $(LIBOBJECTS) $(TESTHARNESS) -o $@
120
+
121
+ coding_test: util/coding_test.o $(LIBOBJECTS) $(TESTHARNESS)
122
+ $(CC) $(LDFLAGS) util/coding_test.o $(LIBOBJECTS) $(TESTHARNESS) -o $@
123
+
124
+ corruption_test: db/corruption_test.o $(LIBOBJECTS) $(TESTHARNESS)
125
+ $(CC) $(LDFLAGS) db/corruption_test.o $(LIBOBJECTS) $(TESTHARNESS) -o $@
126
+
127
+ crc32c_test: util/crc32c_test.o $(LIBOBJECTS) $(TESTHARNESS)
128
+ $(CC) $(LDFLAGS) util/crc32c_test.o $(LIBOBJECTS) $(TESTHARNESS) -o $@
129
+
130
+ db_test: db/db_test.o $(LIBOBJECTS) $(TESTHARNESS)
131
+ $(CC) $(LDFLAGS) db/db_test.o $(LIBOBJECTS) $(TESTHARNESS) -o $@
132
+
133
+ dbformat_test: db/dbformat_test.o $(LIBOBJECTS) $(TESTHARNESS)
134
+ $(CC) $(LDFLAGS) db/dbformat_test.o $(LIBOBJECTS) $(TESTHARNESS) -o $@
135
+
136
+ env_test: util/env_test.o $(LIBOBJECTS) $(TESTHARNESS)
137
+ $(CC) $(LDFLAGS) util/env_test.o $(LIBOBJECTS) $(TESTHARNESS) -o $@
138
+
139
+ filename_test: db/filename_test.o $(LIBOBJECTS) $(TESTHARNESS)
140
+ $(CC) $(LDFLAGS) db/filename_test.o $(LIBOBJECTS) $(TESTHARNESS) -o $@
141
+
142
+ log_test: db/log_test.o $(LIBOBJECTS) $(TESTHARNESS)
143
+ $(CC) $(LDFLAGS) db/log_test.o $(LIBOBJECTS) $(TESTHARNESS) -o $@
144
+
145
+ table_test: table/table_test.o $(LIBOBJECTS) $(TESTHARNESS)
146
+ $(CC) $(LDFLAGS) table/table_test.o $(LIBOBJECTS) $(TESTHARNESS) -o $@
147
+
148
+ skiplist_test: db/skiplist_test.o $(LIBOBJECTS) $(TESTHARNESS)
149
+ $(CC) $(LDFLAGS) db/skiplist_test.o $(LIBOBJECTS) $(TESTHARNESS) -o $@
150
+
151
+ version_edit_test: db/version_edit_test.o $(LIBOBJECTS) $(TESTHARNESS)
152
+ $(CC) $(LDFLAGS) db/version_edit_test.o $(LIBOBJECTS) $(TESTHARNESS) -o $@
153
+
154
+ write_batch_test: db/write_batch_test.o $(LIBOBJECTS) $(TESTHARNESS)
155
+ $(CC) $(LDFLAGS) db/write_batch_test.o $(LIBOBJECTS) $(TESTHARNESS) -o $@
156
+
157
+ ifeq ($(PLATFORM), IOS)
158
+ # For iOS, create universal object files to be used on both the simulator and
159
+ # a device.
160
+ .cc.o:
161
+ mkdir -p ios-x86/$(dir $@)
162
+ $(CC) $(CFLAGS) -isysroot /Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator4.3.sdk -arch i686 $< -o ios-x86/$@
163
+ mkdir -p ios-arm/$(dir $@)
164
+ $(CC) $(CFLAGS) -isysroot /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS4.3.sdk -arch armv6 -arch armv7 $< -o ios-arm/$@
165
+ lipo ios-x86/$@ ios-arm/$@ -create -output $@
166
+ else
167
+ .cc.o:
168
+ $(CC) $(CFLAGS) $< -o $@
169
+ endif
170
+
171
+ # TODO(gabor): dependencies for .o files
172
+ # TODO(gabor): Build library
@@ -0,0 +1,90 @@
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
+
5
+ #include "db/builder.h"
6
+
7
+ #include "db/filename.h"
8
+ #include "db/dbformat.h"
9
+ #include "db/table_cache.h"
10
+ #include "db/version_edit.h"
11
+ #include "leveldb/db.h"
12
+ #include "leveldb/env.h"
13
+ #include "leveldb/iterator.h"
14
+
15
+ namespace leveldb {
16
+
17
+ Status BuildTable(const std::string& dbname,
18
+ Env* env,
19
+ const Options& options,
20
+ TableCache* table_cache,
21
+ Iterator* iter,
22
+ FileMetaData* meta,
23
+ VersionEdit* edit) {
24
+ Status s;
25
+ meta->file_size = 0;
26
+ iter->SeekToFirst();
27
+
28
+ std::string fname = TableFileName(dbname, meta->number);
29
+ if (iter->Valid()) {
30
+ WritableFile* file;
31
+ s = env->NewWritableFile(fname, &file);
32
+ if (!s.ok()) {
33
+ return s;
34
+ }
35
+
36
+ TableBuilder* builder = new TableBuilder(options, file);
37
+ meta->smallest.DecodeFrom(iter->key());
38
+ for (; iter->Valid(); iter->Next()) {
39
+ Slice key = iter->key();
40
+ meta->largest.DecodeFrom(key);
41
+ builder->Add(key, iter->value());
42
+ }
43
+
44
+ // Finish and check for builder errors
45
+ if (s.ok()) {
46
+ s = builder->Finish();
47
+ if (s.ok()) {
48
+ meta->file_size = builder->FileSize();
49
+ assert(meta->file_size > 0);
50
+ }
51
+ } else {
52
+ builder->Abandon();
53
+ }
54
+ delete builder;
55
+
56
+ // Finish and check for file errors
57
+ if (s.ok()) {
58
+ s = file->Sync();
59
+ }
60
+ if (s.ok()) {
61
+ s = file->Close();
62
+ }
63
+ delete file;
64
+ file = NULL;
65
+
66
+ if (s.ok()) {
67
+ // Verify that the table is usable
68
+ Iterator* it = table_cache->NewIterator(ReadOptions(),
69
+ meta->number,
70
+ meta->file_size);
71
+ s = it->status();
72
+ delete it;
73
+ }
74
+ }
75
+
76
+ // Check for input iterator errors
77
+ if (!iter->status().ok()) {
78
+ s = iter->status();
79
+ }
80
+
81
+ if (s.ok() && meta->file_size > 0) {
82
+ edit->AddFile(0, meta->number, meta->file_size,
83
+ meta->smallest, meta->largest);
84
+ } else {
85
+ env->DeleteFile(fname);
86
+ }
87
+ return s;
88
+ }
89
+
90
+ }