filiptepper-leveldb-ruby 0.14

Sign up to get free protection for your applications and to get access to all the features.
Files changed (123) hide show
  1. data/LICENSE +24 -0
  2. data/README +72 -0
  3. data/ext/leveldb/extconf.rb +14 -0
  4. data/ext/leveldb/leveldb.cc +530 -0
  5. data/ext/leveldb/platform.rb +83 -0
  6. data/leveldb/Makefile +191 -0
  7. data/leveldb/build_detect_platform +160 -0
  8. data/leveldb/db/builder.cc +88 -0
  9. data/leveldb/db/builder.h +34 -0
  10. data/leveldb/db/c.cc +581 -0
  11. data/leveldb/db/corruption_test.cc +359 -0
  12. data/leveldb/db/db_bench.cc +970 -0
  13. data/leveldb/db/db_impl.cc +1448 -0
  14. data/leveldb/db/db_impl.h +194 -0
  15. data/leveldb/db/db_iter.cc +299 -0
  16. data/leveldb/db/db_iter.h +26 -0
  17. data/leveldb/db/db_test.cc +1901 -0
  18. data/leveldb/db/dbformat.cc +140 -0
  19. data/leveldb/db/dbformat.h +227 -0
  20. data/leveldb/db/dbformat_test.cc +112 -0
  21. data/leveldb/db/filename.cc +139 -0
  22. data/leveldb/db/filename.h +80 -0
  23. data/leveldb/db/filename_test.cc +122 -0
  24. data/leveldb/db/log_format.h +35 -0
  25. data/leveldb/db/log_reader.cc +259 -0
  26. data/leveldb/db/log_reader.h +108 -0
  27. data/leveldb/db/log_test.cc +500 -0
  28. data/leveldb/db/log_writer.cc +103 -0
  29. data/leveldb/db/log_writer.h +48 -0
  30. data/leveldb/db/memtable.cc +145 -0
  31. data/leveldb/db/memtable.h +91 -0
  32. data/leveldb/db/repair.cc +389 -0
  33. data/leveldb/db/skiplist.h +379 -0
  34. data/leveldb/db/skiplist_test.cc +378 -0
  35. data/leveldb/db/snapshot.h +66 -0
  36. data/leveldb/db/table_cache.cc +121 -0
  37. data/leveldb/db/table_cache.h +61 -0
  38. data/leveldb/db/version_edit.cc +266 -0
  39. data/leveldb/db/version_edit.h +107 -0
  40. data/leveldb/db/version_edit_test.cc +46 -0
  41. data/leveldb/db/version_set.cc +1402 -0
  42. data/leveldb/db/version_set.h +370 -0
  43. data/leveldb/db/version_set_test.cc +179 -0
  44. data/leveldb/db/write_batch.cc +147 -0
  45. data/leveldb/db/write_batch_internal.h +49 -0
  46. data/leveldb/db/write_batch_test.cc +120 -0
  47. data/leveldb/helpers/memenv/memenv.cc +374 -0
  48. data/leveldb/helpers/memenv/memenv.h +20 -0
  49. data/leveldb/helpers/memenv/memenv_test.cc +232 -0
  50. data/leveldb/include/leveldb/c.h +275 -0
  51. data/leveldb/include/leveldb/cache.h +99 -0
  52. data/leveldb/include/leveldb/comparator.h +63 -0
  53. data/leveldb/include/leveldb/db.h +161 -0
  54. data/leveldb/include/leveldb/env.h +323 -0
  55. data/leveldb/include/leveldb/filter_policy.h +70 -0
  56. data/leveldb/include/leveldb/iterator.h +100 -0
  57. data/leveldb/include/leveldb/options.h +195 -0
  58. data/leveldb/include/leveldb/slice.h +109 -0
  59. data/leveldb/include/leveldb/status.h +106 -0
  60. data/leveldb/include/leveldb/table.h +85 -0
  61. data/leveldb/include/leveldb/table_builder.h +92 -0
  62. data/leveldb/include/leveldb/write_batch.h +64 -0
  63. data/leveldb/port/atomic_pointer.h +144 -0
  64. data/leveldb/port/port.h +21 -0
  65. data/leveldb/port/port_android.cc +64 -0
  66. data/leveldb/port/port_android.h +159 -0
  67. data/leveldb/port/port_example.h +125 -0
  68. data/leveldb/port/port_posix.cc +50 -0
  69. data/leveldb/port/port_posix.h +129 -0
  70. data/leveldb/port/win/stdint.h +24 -0
  71. data/leveldb/table/block.cc +267 -0
  72. data/leveldb/table/block.h +44 -0
  73. data/leveldb/table/block_builder.cc +109 -0
  74. data/leveldb/table/block_builder.h +57 -0
  75. data/leveldb/table/filter_block.cc +111 -0
  76. data/leveldb/table/filter_block.h +68 -0
  77. data/leveldb/table/filter_block_test.cc +128 -0
  78. data/leveldb/table/format.cc +145 -0
  79. data/leveldb/table/format.h +108 -0
  80. data/leveldb/table/iterator.cc +67 -0
  81. data/leveldb/table/iterator_wrapper.h +63 -0
  82. data/leveldb/table/merger.cc +197 -0
  83. data/leveldb/table/merger.h +26 -0
  84. data/leveldb/table/table.cc +276 -0
  85. data/leveldb/table/table_builder.cc +270 -0
  86. data/leveldb/table/table_test.cc +838 -0
  87. data/leveldb/table/two_level_iterator.cc +182 -0
  88. data/leveldb/table/two_level_iterator.h +34 -0
  89. data/leveldb/util/arena.cc +68 -0
  90. data/leveldb/util/arena.h +68 -0
  91. data/leveldb/util/arena_test.cc +68 -0
  92. data/leveldb/util/bloom.cc +95 -0
  93. data/leveldb/util/bloom_test.cc +159 -0
  94. data/leveldb/util/cache.cc +328 -0
  95. data/leveldb/util/cache_test.cc +186 -0
  96. data/leveldb/util/coding.cc +194 -0
  97. data/leveldb/util/coding.h +104 -0
  98. data/leveldb/util/coding_test.cc +173 -0
  99. data/leveldb/util/comparator.cc +76 -0
  100. data/leveldb/util/crc32c.cc +332 -0
  101. data/leveldb/util/crc32c.h +45 -0
  102. data/leveldb/util/crc32c_test.cc +72 -0
  103. data/leveldb/util/env.cc +96 -0
  104. data/leveldb/util/env_posix.cc +609 -0
  105. data/leveldb/util/env_test.cc +104 -0
  106. data/leveldb/util/filter_policy.cc +11 -0
  107. data/leveldb/util/hash.cc +45 -0
  108. data/leveldb/util/hash.h +19 -0
  109. data/leveldb/util/histogram.cc +139 -0
  110. data/leveldb/util/histogram.h +42 -0
  111. data/leveldb/util/logging.cc +81 -0
  112. data/leveldb/util/logging.h +47 -0
  113. data/leveldb/util/mutexlock.h +39 -0
  114. data/leveldb/util/options.cc +29 -0
  115. data/leveldb/util/posix_logger.h +98 -0
  116. data/leveldb/util/random.h +59 -0
  117. data/leveldb/util/status.cc +75 -0
  118. data/leveldb/util/testharness.cc +77 -0
  119. data/leveldb/util/testharness.h +138 -0
  120. data/leveldb/util/testutil.cc +51 -0
  121. data/leveldb/util/testutil.h +53 -0
  122. data/lib/leveldb.rb +76 -0
  123. metadata +175 -0
@@ -0,0 +1,370 @@
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
+ // The representation of a DBImpl consists of a set of Versions. The
6
+ // newest version is called "current". Older versions may be kept
7
+ // around to provide a consistent view to live iterators.
8
+ //
9
+ // Each Version keeps track of a set of Table files per level. The
10
+ // entire set of versions is maintained in a VersionSet.
11
+ //
12
+ // Version,VersionSet are thread-compatible, but require external
13
+ // synchronization on all accesses.
14
+
15
+ #ifndef STORAGE_LEVELDB_DB_VERSION_SET_H_
16
+ #define STORAGE_LEVELDB_DB_VERSION_SET_H_
17
+
18
+ #include <map>
19
+ #include <set>
20
+ #include <vector>
21
+ #include "db/dbformat.h"
22
+ #include "db/version_edit.h"
23
+ #include "port/port.h"
24
+
25
+ namespace leveldb {
26
+
27
+ namespace log { class Writer; }
28
+
29
+ class Compaction;
30
+ class Iterator;
31
+ class MemTable;
32
+ class TableBuilder;
33
+ class TableCache;
34
+ class Version;
35
+ class VersionSet;
36
+ class WritableFile;
37
+
38
+ // Return the smallest index i such that files[i]->largest >= key.
39
+ // Return files.size() if there is no such file.
40
+ // REQUIRES: "files" contains a sorted list of non-overlapping files.
41
+ extern int FindFile(const InternalKeyComparator& icmp,
42
+ const std::vector<FileMetaData*>& files,
43
+ const Slice& key);
44
+
45
+ // Returns true iff some file in "files" overlaps the user key range
46
+ // [*smallest,*largest].
47
+ // smallest==NULL represents a key smaller than all keys in the DB.
48
+ // largest==NULL represents a key largest than all keys in the DB.
49
+ // REQUIRES: If disjoint_sorted_files, files[] contains disjoint ranges
50
+ // in sorted order.
51
+ extern bool SomeFileOverlapsRange(
52
+ const InternalKeyComparator& icmp,
53
+ bool disjoint_sorted_files,
54
+ const std::vector<FileMetaData*>& files,
55
+ const Slice* smallest_user_key,
56
+ const Slice* largest_user_key);
57
+
58
+ class Version {
59
+ public:
60
+ // Append to *iters a sequence of iterators that will
61
+ // yield the contents of this Version when merged together.
62
+ // REQUIRES: This version has been saved (see VersionSet::SaveTo)
63
+ void AddIterators(const ReadOptions&, std::vector<Iterator*>* iters);
64
+
65
+ // Lookup the value for key. If found, store it in *val and
66
+ // return OK. Else return a non-OK status. Fills *stats.
67
+ // REQUIRES: lock is not held
68
+ struct GetStats {
69
+ FileMetaData* seek_file;
70
+ int seek_file_level;
71
+ };
72
+ Status Get(const ReadOptions&, const LookupKey& key, std::string* val,
73
+ GetStats* stats);
74
+
75
+ // Adds "stats" into the current state. Returns true if a new
76
+ // compaction may need to be triggered, false otherwise.
77
+ // REQUIRES: lock is held
78
+ bool UpdateStats(const GetStats& stats);
79
+
80
+ // Reference count management (so Versions do not disappear out from
81
+ // under live iterators)
82
+ void Ref();
83
+ void Unref();
84
+
85
+ void GetOverlappingInputs(
86
+ int level,
87
+ const InternalKey* begin, // NULL means before all keys
88
+ const InternalKey* end, // NULL means after all keys
89
+ std::vector<FileMetaData*>* inputs);
90
+
91
+ // Returns true iff some file in the specified level overlaps
92
+ // some part of [*smallest_user_key,*largest_user_key].
93
+ // smallest_user_key==NULL represents a key smaller than all keys in the DB.
94
+ // largest_user_key==NULL represents a key largest than all keys in the DB.
95
+ bool OverlapInLevel(int level,
96
+ const Slice* smallest_user_key,
97
+ const Slice* largest_user_key);
98
+
99
+ // Return the level at which we should place a new memtable compaction
100
+ // result that covers the range [smallest_user_key,largest_user_key].
101
+ int PickLevelForMemTableOutput(const Slice& smallest_user_key,
102
+ const Slice& largest_user_key);
103
+
104
+ int NumFiles(int level) const { return files_[level].size(); }
105
+
106
+ // Return a human readable string that describes this version's contents.
107
+ std::string DebugString() const;
108
+
109
+ private:
110
+ friend class Compaction;
111
+ friend class VersionSet;
112
+
113
+ class LevelFileNumIterator;
114
+ Iterator* NewConcatenatingIterator(const ReadOptions&, int level) const;
115
+
116
+ VersionSet* vset_; // VersionSet to which this Version belongs
117
+ Version* next_; // Next version in linked list
118
+ Version* prev_; // Previous version in linked list
119
+ int refs_; // Number of live refs to this version
120
+
121
+ // List of files per level
122
+ std::vector<FileMetaData*> files_[config::kNumLevels];
123
+
124
+ // Next file to compact based on seek stats.
125
+ FileMetaData* file_to_compact_;
126
+ int file_to_compact_level_;
127
+
128
+ // Level that should be compacted next and its compaction score.
129
+ // Score < 1 means compaction is not strictly needed. These fields
130
+ // are initialized by Finalize().
131
+ double compaction_score_;
132
+ int compaction_level_;
133
+
134
+ explicit Version(VersionSet* vset)
135
+ : vset_(vset), next_(this), prev_(this), refs_(0),
136
+ file_to_compact_(NULL),
137
+ file_to_compact_level_(-1),
138
+ compaction_score_(-1),
139
+ compaction_level_(-1) {
140
+ }
141
+
142
+ ~Version();
143
+
144
+ // No copying allowed
145
+ Version(const Version&);
146
+ void operator=(const Version&);
147
+ };
148
+
149
+ class VersionSet {
150
+ public:
151
+ VersionSet(const std::string& dbname,
152
+ const Options* options,
153
+ TableCache* table_cache,
154
+ const InternalKeyComparator*);
155
+ ~VersionSet();
156
+
157
+ // Apply *edit to the current version to form a new descriptor that
158
+ // is both saved to persistent state and installed as the new
159
+ // current version. Will release *mu while actually writing to the file.
160
+ // REQUIRES: *mu is held on entry.
161
+ // REQUIRES: no other thread concurrently calls LogAndApply()
162
+ Status LogAndApply(VersionEdit* edit, port::Mutex* mu);
163
+
164
+ // Recover the last saved descriptor from persistent storage.
165
+ Status Recover();
166
+
167
+ // Return the current version.
168
+ Version* current() const { return current_; }
169
+
170
+ // Return the current manifest file number
171
+ uint64_t ManifestFileNumber() const { return manifest_file_number_; }
172
+
173
+ // Allocate and return a new file number
174
+ uint64_t NewFileNumber() { return next_file_number_++; }
175
+
176
+ // Return the number of Table files at the specified level.
177
+ int NumLevelFiles(int level) const;
178
+
179
+ // Return the combined file size of all files at the specified level.
180
+ int64_t NumLevelBytes(int level) const;
181
+
182
+ // Return the last sequence number.
183
+ uint64_t LastSequence() const { return last_sequence_; }
184
+
185
+ // Set the last sequence number to s.
186
+ void SetLastSequence(uint64_t s) {
187
+ assert(s >= last_sequence_);
188
+ last_sequence_ = s;
189
+ }
190
+
191
+ // Mark the specified file number as used.
192
+ void MarkFileNumberUsed(uint64_t number);
193
+
194
+ // Return the current log file number.
195
+ uint64_t LogNumber() const { return log_number_; }
196
+
197
+ // Return the log file number for the log file that is currently
198
+ // being compacted, or zero if there is no such log file.
199
+ uint64_t PrevLogNumber() const { return prev_log_number_; }
200
+
201
+ // Pick level and inputs for a new compaction.
202
+ // Returns NULL if there is no compaction to be done.
203
+ // Otherwise returns a pointer to a heap-allocated object that
204
+ // describes the compaction. Caller should delete the result.
205
+ Compaction* PickCompaction();
206
+
207
+ // Return a compaction object for compacting the range [begin,end] in
208
+ // the specified level. Returns NULL if there is nothing in that
209
+ // level that overlaps the specified range. Caller should delete
210
+ // the result.
211
+ Compaction* CompactRange(
212
+ int level,
213
+ const InternalKey* begin,
214
+ const InternalKey* end);
215
+
216
+ // Return the maximum overlapping data (in bytes) at next level for any
217
+ // file at a level >= 1.
218
+ int64_t MaxNextLevelOverlappingBytes();
219
+
220
+ // Create an iterator that reads over the compaction inputs for "*c".
221
+ // The caller should delete the iterator when no longer needed.
222
+ Iterator* MakeInputIterator(Compaction* c);
223
+
224
+ // Returns true iff some level needs a compaction.
225
+ bool NeedsCompaction() const {
226
+ Version* v = current_;
227
+ return (v->compaction_score_ >= 1) || (v->file_to_compact_ != NULL);
228
+ }
229
+
230
+ // Add all files listed in any live version to *live.
231
+ // May also mutate some internal state.
232
+ void AddLiveFiles(std::set<uint64_t>* live);
233
+
234
+ // Return the approximate offset in the database of the data for
235
+ // "key" as of version "v".
236
+ uint64_t ApproximateOffsetOf(Version* v, const InternalKey& key);
237
+
238
+ // Return a human-readable short (single-line) summary of the number
239
+ // of files per level. Uses *scratch as backing store.
240
+ struct LevelSummaryStorage {
241
+ char buffer[100];
242
+ };
243
+ const char* LevelSummary(LevelSummaryStorage* scratch) const;
244
+
245
+ private:
246
+ class Builder;
247
+
248
+ friend class Compaction;
249
+ friend class Version;
250
+
251
+ void Finalize(Version* v);
252
+
253
+ void GetRange(const std::vector<FileMetaData*>& inputs,
254
+ InternalKey* smallest,
255
+ InternalKey* largest);
256
+
257
+ void GetRange2(const std::vector<FileMetaData*>& inputs1,
258
+ const std::vector<FileMetaData*>& inputs2,
259
+ InternalKey* smallest,
260
+ InternalKey* largest);
261
+
262
+ void SetupOtherInputs(Compaction* c);
263
+
264
+ // Save current contents to *log
265
+ Status WriteSnapshot(log::Writer* log);
266
+
267
+ void AppendVersion(Version* v);
268
+
269
+ Env* const env_;
270
+ const std::string dbname_;
271
+ const Options* const options_;
272
+ TableCache* const table_cache_;
273
+ const InternalKeyComparator icmp_;
274
+ uint64_t next_file_number_;
275
+ uint64_t manifest_file_number_;
276
+ uint64_t last_sequence_;
277
+ uint64_t log_number_;
278
+ uint64_t prev_log_number_; // 0 or backing store for memtable being compacted
279
+
280
+ // Opened lazily
281
+ WritableFile* descriptor_file_;
282
+ log::Writer* descriptor_log_;
283
+ Version dummy_versions_; // Head of circular doubly-linked list of versions.
284
+ Version* current_; // == dummy_versions_.prev_
285
+
286
+ // Per-level key at which the next compaction at that level should start.
287
+ // Either an empty string, or a valid InternalKey.
288
+ std::string compact_pointer_[config::kNumLevels];
289
+
290
+ // No copying allowed
291
+ VersionSet(const VersionSet&);
292
+ void operator=(const VersionSet&);
293
+ };
294
+
295
+ // A Compaction encapsulates information about a compaction.
296
+ class Compaction {
297
+ public:
298
+ ~Compaction();
299
+
300
+ // Return the level that is being compacted. Inputs from "level"
301
+ // and "level+1" will be merged to produce a set of "level+1" files.
302
+ int level() const { return level_; }
303
+
304
+ // Return the object that holds the edits to the descriptor done
305
+ // by this compaction.
306
+ VersionEdit* edit() { return &edit_; }
307
+
308
+ // "which" must be either 0 or 1
309
+ int num_input_files(int which) const { return inputs_[which].size(); }
310
+
311
+ // Return the ith input file at "level()+which" ("which" must be 0 or 1).
312
+ FileMetaData* input(int which, int i) const { return inputs_[which][i]; }
313
+
314
+ // Maximum size of files to build during this compaction.
315
+ uint64_t MaxOutputFileSize() const { return max_output_file_size_; }
316
+
317
+ // Is this a trivial compaction that can be implemented by just
318
+ // moving a single input file to the next level (no merging or splitting)
319
+ bool IsTrivialMove() const;
320
+
321
+ // Add all inputs to this compaction as delete operations to *edit.
322
+ void AddInputDeletions(VersionEdit* edit);
323
+
324
+ // Returns true if the information we have available guarantees that
325
+ // the compaction is producing data in "level+1" for which no data exists
326
+ // in levels greater than "level+1".
327
+ bool IsBaseLevelForKey(const Slice& user_key);
328
+
329
+ // Returns true iff we should stop building the current output
330
+ // before processing "internal_key".
331
+ bool ShouldStopBefore(const Slice& internal_key);
332
+
333
+ // Release the input version for the compaction, once the compaction
334
+ // is successful.
335
+ void ReleaseInputs();
336
+
337
+ private:
338
+ friend class Version;
339
+ friend class VersionSet;
340
+
341
+ explicit Compaction(int level);
342
+
343
+ int level_;
344
+ uint64_t max_output_file_size_;
345
+ Version* input_version_;
346
+ VersionEdit edit_;
347
+
348
+ // Each compaction reads inputs from "level_" and "level_+1"
349
+ std::vector<FileMetaData*> inputs_[2]; // The two sets of inputs
350
+
351
+ // State used to check for number of of overlapping grandparent files
352
+ // (parent == level_ + 1, grandparent == level_ + 2)
353
+ std::vector<FileMetaData*> grandparents_;
354
+ size_t grandparent_index_; // Index in grandparent_starts_
355
+ bool seen_key_; // Some output key has been seen
356
+ int64_t overlapped_bytes_; // Bytes of overlap between current output
357
+ // and grandparent files
358
+
359
+ // State for implementing IsBaseLevelForKey
360
+
361
+ // level_ptrs_ holds indices into input_version_->levels_: our state
362
+ // is that we are positioned at one of the file ranges for each
363
+ // higher level than the ones involved in this compaction (i.e. for
364
+ // all L >= level_ + 2).
365
+ size_t level_ptrs_[config::kNumLevels];
366
+ };
367
+
368
+ } // namespace leveldb
369
+
370
+ #endif // STORAGE_LEVELDB_DB_VERSION_SET_H_
@@ -0,0 +1,179 @@
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/version_set.h"
6
+ #include "util/logging.h"
7
+ #include "util/testharness.h"
8
+ #include "util/testutil.h"
9
+
10
+ namespace leveldb {
11
+
12
+ class FindFileTest {
13
+ public:
14
+ std::vector<FileMetaData*> files_;
15
+ bool disjoint_sorted_files_;
16
+
17
+ FindFileTest() : disjoint_sorted_files_(true) { }
18
+
19
+ ~FindFileTest() {
20
+ for (int i = 0; i < files_.size(); i++) {
21
+ delete files_[i];
22
+ }
23
+ }
24
+
25
+ void Add(const char* smallest, const char* largest,
26
+ SequenceNumber smallest_seq = 100,
27
+ SequenceNumber largest_seq = 100) {
28
+ FileMetaData* f = new FileMetaData;
29
+ f->number = files_.size() + 1;
30
+ f->smallest = InternalKey(smallest, smallest_seq, kTypeValue);
31
+ f->largest = InternalKey(largest, largest_seq, kTypeValue);
32
+ files_.push_back(f);
33
+ }
34
+
35
+ int Find(const char* key) {
36
+ InternalKey target(key, 100, kTypeValue);
37
+ InternalKeyComparator cmp(BytewiseComparator());
38
+ return FindFile(cmp, files_, target.Encode());
39
+ }
40
+
41
+ bool Overlaps(const char* smallest, const char* largest) {
42
+ InternalKeyComparator cmp(BytewiseComparator());
43
+ Slice s(smallest != NULL ? smallest : "");
44
+ Slice l(largest != NULL ? largest : "");
45
+ return SomeFileOverlapsRange(cmp, disjoint_sorted_files_, files_,
46
+ (smallest != NULL ? &s : NULL),
47
+ (largest != NULL ? &l : NULL));
48
+ }
49
+ };
50
+
51
+ TEST(FindFileTest, Empty) {
52
+ ASSERT_EQ(0, Find("foo"));
53
+ ASSERT_TRUE(! Overlaps("a", "z"));
54
+ ASSERT_TRUE(! Overlaps(NULL, "z"));
55
+ ASSERT_TRUE(! Overlaps("a", NULL));
56
+ ASSERT_TRUE(! Overlaps(NULL, NULL));
57
+ }
58
+
59
+ TEST(FindFileTest, Single) {
60
+ Add("p", "q");
61
+ ASSERT_EQ(0, Find("a"));
62
+ ASSERT_EQ(0, Find("p"));
63
+ ASSERT_EQ(0, Find("p1"));
64
+ ASSERT_EQ(0, Find("q"));
65
+ ASSERT_EQ(1, Find("q1"));
66
+ ASSERT_EQ(1, Find("z"));
67
+
68
+ ASSERT_TRUE(! Overlaps("a", "b"));
69
+ ASSERT_TRUE(! Overlaps("z1", "z2"));
70
+ ASSERT_TRUE(Overlaps("a", "p"));
71
+ ASSERT_TRUE(Overlaps("a", "q"));
72
+ ASSERT_TRUE(Overlaps("a", "z"));
73
+ ASSERT_TRUE(Overlaps("p", "p1"));
74
+ ASSERT_TRUE(Overlaps("p", "q"));
75
+ ASSERT_TRUE(Overlaps("p", "z"));
76
+ ASSERT_TRUE(Overlaps("p1", "p2"));
77
+ ASSERT_TRUE(Overlaps("p1", "z"));
78
+ ASSERT_TRUE(Overlaps("q", "q"));
79
+ ASSERT_TRUE(Overlaps("q", "q1"));
80
+
81
+ ASSERT_TRUE(! Overlaps(NULL, "j"));
82
+ ASSERT_TRUE(! Overlaps("r", NULL));
83
+ ASSERT_TRUE(Overlaps(NULL, "p"));
84
+ ASSERT_TRUE(Overlaps(NULL, "p1"));
85
+ ASSERT_TRUE(Overlaps("q", NULL));
86
+ ASSERT_TRUE(Overlaps(NULL, NULL));
87
+ }
88
+
89
+
90
+ TEST(FindFileTest, Multiple) {
91
+ Add("150", "200");
92
+ Add("200", "250");
93
+ Add("300", "350");
94
+ Add("400", "450");
95
+ ASSERT_EQ(0, Find("100"));
96
+ ASSERT_EQ(0, Find("150"));
97
+ ASSERT_EQ(0, Find("151"));
98
+ ASSERT_EQ(0, Find("199"));
99
+ ASSERT_EQ(0, Find("200"));
100
+ ASSERT_EQ(1, Find("201"));
101
+ ASSERT_EQ(1, Find("249"));
102
+ ASSERT_EQ(1, Find("250"));
103
+ ASSERT_EQ(2, Find("251"));
104
+ ASSERT_EQ(2, Find("299"));
105
+ ASSERT_EQ(2, Find("300"));
106
+ ASSERT_EQ(2, Find("349"));
107
+ ASSERT_EQ(2, Find("350"));
108
+ ASSERT_EQ(3, Find("351"));
109
+ ASSERT_EQ(3, Find("400"));
110
+ ASSERT_EQ(3, Find("450"));
111
+ ASSERT_EQ(4, Find("451"));
112
+
113
+ ASSERT_TRUE(! Overlaps("100", "149"));
114
+ ASSERT_TRUE(! Overlaps("251", "299"));
115
+ ASSERT_TRUE(! Overlaps("451", "500"));
116
+ ASSERT_TRUE(! Overlaps("351", "399"));
117
+
118
+ ASSERT_TRUE(Overlaps("100", "150"));
119
+ ASSERT_TRUE(Overlaps("100", "200"));
120
+ ASSERT_TRUE(Overlaps("100", "300"));
121
+ ASSERT_TRUE(Overlaps("100", "400"));
122
+ ASSERT_TRUE(Overlaps("100", "500"));
123
+ ASSERT_TRUE(Overlaps("375", "400"));
124
+ ASSERT_TRUE(Overlaps("450", "450"));
125
+ ASSERT_TRUE(Overlaps("450", "500"));
126
+ }
127
+
128
+ TEST(FindFileTest, MultipleNullBoundaries) {
129
+ Add("150", "200");
130
+ Add("200", "250");
131
+ Add("300", "350");
132
+ Add("400", "450");
133
+ ASSERT_TRUE(! Overlaps(NULL, "149"));
134
+ ASSERT_TRUE(! Overlaps("451", NULL));
135
+ ASSERT_TRUE(Overlaps(NULL, NULL));
136
+ ASSERT_TRUE(Overlaps(NULL, "150"));
137
+ ASSERT_TRUE(Overlaps(NULL, "199"));
138
+ ASSERT_TRUE(Overlaps(NULL, "200"));
139
+ ASSERT_TRUE(Overlaps(NULL, "201"));
140
+ ASSERT_TRUE(Overlaps(NULL, "400"));
141
+ ASSERT_TRUE(Overlaps(NULL, "800"));
142
+ ASSERT_TRUE(Overlaps("100", NULL));
143
+ ASSERT_TRUE(Overlaps("200", NULL));
144
+ ASSERT_TRUE(Overlaps("449", NULL));
145
+ ASSERT_TRUE(Overlaps("450", NULL));
146
+ }
147
+
148
+ TEST(FindFileTest, OverlapSequenceChecks) {
149
+ Add("200", "200", 5000, 3000);
150
+ ASSERT_TRUE(! Overlaps("199", "199"));
151
+ ASSERT_TRUE(! Overlaps("201", "300"));
152
+ ASSERT_TRUE(Overlaps("200", "200"));
153
+ ASSERT_TRUE(Overlaps("190", "200"));
154
+ ASSERT_TRUE(Overlaps("200", "210"));
155
+ }
156
+
157
+ TEST(FindFileTest, OverlappingFiles) {
158
+ Add("150", "600");
159
+ Add("400", "500");
160
+ disjoint_sorted_files_ = false;
161
+ ASSERT_TRUE(! Overlaps("100", "149"));
162
+ ASSERT_TRUE(! Overlaps("601", "700"));
163
+ ASSERT_TRUE(Overlaps("100", "150"));
164
+ ASSERT_TRUE(Overlaps("100", "200"));
165
+ ASSERT_TRUE(Overlaps("100", "300"));
166
+ ASSERT_TRUE(Overlaps("100", "400"));
167
+ ASSERT_TRUE(Overlaps("100", "500"));
168
+ ASSERT_TRUE(Overlaps("375", "400"));
169
+ ASSERT_TRUE(Overlaps("450", "450"));
170
+ ASSERT_TRUE(Overlaps("450", "500"));
171
+ ASSERT_TRUE(Overlaps("450", "700"));
172
+ ASSERT_TRUE(Overlaps("600", "700"));
173
+ }
174
+
175
+ } // namespace leveldb
176
+
177
+ int main(int argc, char** argv) {
178
+ return leveldb::test::RunAllTests();
179
+ }