leveldb-ruby 0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
+ }