Skip to content
This repository was archived by the owner on Sep 19, 2023. It is now read-only.

Commit b86d7f4

Browse files
authored
Add SecondaryDB (#15)
* Add secondarydb, initial commit * copied the wrong test code lol * restore "except *" catches
1 parent 7ae0187 commit b86d7f4

File tree

3 files changed

+66
-5
lines changed

3 files changed

+66
-5
lines changed

rocksdb/_rocksdb.pyx

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1972,13 +1972,17 @@ cdef class DB(object):
19721972
cdef string db_path
19731973

19741974
def __cinit__(self, db_name, Options opts, dict column_families=None,
1975-
read_only=False, *args, **kwargs):
1975+
read_only=False, secondary_path=None, *args, **kwargs):
19761976
cdef Status st
19771977
cdef bytes default_cf_name = db.kDefaultColumnFamilyName
19781978
self.wrapped_db = NULL
19791979
self.opts = None
19801980
self.cf_handles = []
19811981
self.cf_options = []
1982+
if isinstance(secondary_path, str):
1983+
self.db_path = path_to_string(secondary_path)
1984+
else:
1985+
self.db_path = path_to_string(db_name)
19821986

19831987
if opts.in_use:
19841988
raise InvalidArgument(
@@ -2019,12 +2023,21 @@ cdef class DB(object):
20192023
self.cf_options.append(cf_options)
20202024
if type(self) != DB:
20212025
return
2022-
db_path = path_to_string(db_name)
2023-
if read_only:
2026+
if isinstance(secondary_path, str):
2027+
primary_db = path_to_string(db_name)
2028+
with nogil:
2029+
st = db.DB_OpenSecondary_ColumnFamilies(
2030+
deref(opts.opts),
2031+
primary_db,
2032+
self.db_path,
2033+
self.column_family_descriptors,
2034+
&self.column_family_handles,
2035+
&self.wrapped_db)
2036+
elif read_only:
20242037
with nogil:
20252038
st = db.DB_OpenForReadOnly_ColumnFamilies(
20262039
deref(opts.opts),
2027-
db_path,
2040+
self.db_path,
20282041
self.column_family_descriptors,
20292042
&self.column_family_handles,
20302043
&self.wrapped_db,
@@ -2033,7 +2046,7 @@ cdef class DB(object):
20332046
with nogil:
20342047
st = db.DB_Open_ColumnFamilies(
20352048
deref(opts.opts),
2036-
db_path,
2049+
self.db_path,
20372050
self.column_family_descriptors,
20382051
&self.column_family_handles,
20392052
&self.wrapped_db)
@@ -2635,6 +2648,10 @@ cdef class DB(object):
26352648
if copts:
26362649
copts.in_use = False
26372650

2651+
def try_catch_up_with_primary(self):
2652+
with nogil:
2653+
self.wrapped_db.TryCatchUpWithPrimary()
2654+
26382655

26392656
def repair_db(db_name, Options opts):
26402657
cdef Status st

rocksdb/db.pxd

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,7 @@ cdef extern from "rocksdb/db.h" namespace "rocksdb":
170170
Status DisableFileDeletions() nogil except+
171171
Status EnableFileDeletions() nogil except+
172172
Status Close() nogil except+
173+
Status TryCatchUpWithPrimary() nogil except+
173174

174175
# TODO: Status GetSortedWalFiles(VectorLogPtr& files)
175176
# TODO: SequenceNumber GetLatestSequenceNumber()
@@ -195,6 +196,19 @@ cdef extern from "rocksdb/db.h" namespace "rocksdb":
195196
vector[ColumnFamilyHandle*]*,
196197
DB**) nogil except+
197198

199+
cdef Status DB_OpenSecondary "rocksdb::DB::OpenAsSecondary"(
200+
const options.Options&,
201+
const string&,
202+
cpp_bool) nogil except+
203+
204+
cdef Status DB_OpenSecondary_ColumnFamilies "rocksdb::DB::OpenAsSecondary"(
205+
const options.Options&,
206+
const string&, # primary db path
207+
const string&, # secondary db path
208+
const vector[ColumnFamilyDescriptor]&,
209+
vector[ColumnFamilyHandle*]*,
210+
DB**) nogil except+
211+
198212
cdef Status DB_OpenForReadOnly "rocksdb::DB::OpenForReadOnly"(
199213
const options.Options&,
200214
const string&,

rocksdb/tests/test_db.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -735,3 +735,33 @@ def test_compact_range(self):
735735

736736
self.db.compact_range(column_family=self.cf_b)
737737

738+
739+
class TestSecondaryDB(TestHelper):
740+
def setUp(self):
741+
TestHelper.setUp(self)
742+
self.db = rocksdb.DB(os.path.join(self.db_loc, "test_primary"), rocksdb.Options(create_if_missing=True))
743+
self.secondary_db = rocksdb.DB(os.path.join(self.db_loc, "test_primary"), rocksdb.Options(create_if_missing=True),
744+
secondary_path=os.path.join(self.db_loc, "test_secondary"))
745+
746+
def test_catch_up(self):
747+
748+
# Just your ordinary test_write_batch test
749+
750+
batch = rocksdb.WriteBatch()
751+
batch.put(b"key", b"v1")
752+
batch.delete(b"key")
753+
batch.put(b"key", b"v2")
754+
batch.put(b"key", b"v3")
755+
batch.put(b"a", b"b")
756+
757+
self.db.write(batch)
758+
ref = {b'a': b'b', b'key': b'v3'}
759+
ret = self.db.multi_get([b'key', b'a'])
760+
self.assertEqual(ref, ret)
761+
762+
# Now let's try updating the secondary db
763+
764+
self.secondary_db.try_catch_up_with_primary()
765+
766+
ret = self.secondary_db.multi_get([b'key', b'a'])
767+
self.assertEqual(ref, ret)

0 commit comments

Comments
 (0)