OverviewFilesCommitsIssuesDocsReleasesPeers

opencog-atomspace-rocks commits / 984ef28

Add support for a read-only open mode.
984ef28fcdd6a1f21aab25b3cf42e8dfc036ca46
by Linas Vepstas <linasvepstas@gmail.com> · 2026-01-20T17:56:15.000Z

Changed files (4) +82 -19

opencog/persist/monospace/MonoStorage.cc +35 -8
……@@ -50,7 +50,7 @@ static const char* version_key = "*-Version-*";
5050/* ================================================================ */
5151// Constructors
5252
53void MonoStorage::init(const char * uri)
53void MonoStorage::init(const char * uri, bool read_only)
5454{
5555#define URIX_LEN (sizeof("monospace://") - 1) // Should be 12
5656 // We expect the URI to be for the form (note: three slashes)
……@@ -64,8 +64,8 @@ void MonoStorage::init(const char * uri)
6464 // Prefix for bloom filter -- first 2 chars.
6565 // options.prefix_extractor.reset(rocksdb::NewFixedPrefixTransform(2));
6666
67 // Create the file if it doesn't exist yet.
68 options.create_if_missing = true;
67 // Create the file if it doesn't exist yet (not in read-only mode).
68 options.create_if_missing = not read_only;
6969
7070 // The primary consumer of disk and RAM in RocksDB are the `*.sst`
7171 // files: each one is opened and memory-mapped. RocksDB does NOT
……@@ -105,18 +105,27 @@ void MonoStorage::init(const char * uri)
105105#endif
106106
107107 // Open the file.
108 rocksdb::Status s = rocksdb::DB::Open(options, file, &_rfile);
108 rocksdb::Status s;
109 if (read_only)
110 s = rocksdb::DB::OpenForReadOnly(options, file, &_rfile);
111 else
112 s = rocksdb::DB::Open(options, file, &_rfile);
109113
110114 if (not s.ok())
111115 throw IOException(TRACE_INFO, "Can't open file: %s",
112116 s.ToString().c_str());
113117
118 _read_only = read_only;
119
114120 // Verify the version number. Version numbers are not currently used;
115121 // this is for future-proofing future versions.
116122 std::string version;
117123 s = _rfile->Get(rocksdb::ReadOptions(), version_key, &version);
118124 if (not s.ok())
119125 {
126 if (read_only)
127 throw IOException(TRACE_INFO,
128 "Cannot open read-only: DB has no version (not initialized)");
120129 s = _rfile->Put(rocksdb::WriteOptions(), version_key, "1");
121130 }
122131 else
……@@ -130,6 +139,9 @@ void MonoStorage::init(const char * uri)
130139 s = _rfile->Get(rocksdb::ReadOptions(), aid_key, &sid);
131140 if (not s.ok())
132141 {
142 if (read_only)
143 throw IOException(TRACE_INFO,
144 "Cannot open read-only: DB has no aid (not initialized)");
133145 _next_aid = 1;
134146 sid = aidtostr(1);
135147 s = _rfile->Put(rocksdb::WriteOptions(), aid_key, sid);
……@@ -148,9 +160,11 @@ void MonoStorage::init(const char * uri)
148160 throw IOException(TRACE_INFO,
149161 "Cannot use MonoStorageNode to open multi-space storage '%s'\n", uri);
150162
151printf("Mono: opened=%s\n", file.c_str());
163printf("Mono: opened=%s%s\n", file.c_str(), read_only ? " (read-only)" : "");
152164printf("Mono: initial aid=%lu\n", _next_aid.load());
153165
166 if (read_only) return;
167
154168 // Set up a SID for the TV predicate key.
155169 // This must match what the AtomSpace is using.
156170 // Tack on a leading colon, for convenience.
……@@ -162,12 +176,20 @@ void MonoStorage::open()
162176{
163177 // User might call us twice. If so, ignore the second call.
164178 if (_rfile) return;
165 init(_name.c_str());
179 init(_name.c_str(), false);
180}
181
182void MonoStorage::open_read_only()
183{
184 // User might call us twice. If so, ignore the second call.
185 if (_rfile) return;
186 init(_name.c_str(), true);
166187}
167188
168189MonoStorage::MonoStorage(std::string uri) :
169190 StorageNode(MONO_STORAGE_NODE, std::move(uri)),
170191 _rfile(nullptr),
192 _read_only(false),
171193 _next_aid(0),
172194 _unknown_type(false)
173195{
……@@ -198,11 +220,15 @@ void MonoStorage::close()
198220{
199221 if (nullptr == _rfile) return;
200222
201 logger().debug("Mono: storing final aid=%lu\n", _next_aid.load());
202 write_aid();
223 if (not _read_only)
224 {
225 logger().debug("Mono: storing final aid=%lu\n", _next_aid.load());
226 write_aid();
227 }
203228 delete _rfile;
204229 _rfile = nullptr;
205230 _next_aid = 0;
231 _read_only = false;
206232}
207233
208234void MonoStorage::write_aid(void)
……@@ -228,6 +254,7 @@ bool MonoStorage::connected(void)
228254///
229255void MonoStorage::barrier()
230256{
257 if (_read_only) return;
231258 // belt and suspenders.
232259 write_aid();
233260}
opencog/persist/monospace/MonoStorage.h +5 -1
……@@ -51,10 +51,13 @@ class MonoStorage : public StorageNode
5151 friend class MonoSatisfyingSet;
5252 friend class MonoJoinCallback;
5353 private:
54 void init(const char *);
54 void init(const char *, bool read_only = false);
5555 std::string _uri;
5656 rocksdb::DB* _rfile;
5757
58 // True if opened in read-only mode.
59 bool _read_only;
60
5861 // unique ID's
5962 std::atomic_uint64_t _next_aid;
6063 uint64_t strtoaid(const std::string&) const;
……@@ -104,6 +107,7 @@ class MonoStorage : public StorageNode
104107 virtual ~MonoStorage();
105108
106109 void open(void);
110 void open_read_only(void);
107111 void close(void);
108112 bool connected(void); // connection to DB is alive
109113
opencog/persist/rocks/RocksStorage.cc +37 -9
……@@ -50,7 +50,7 @@ static const char* version_key = "*-Version-*";
5050/* ================================================================ */
5151// Constructors
5252
53void RocksStorage::init(const char * uri)
53void RocksStorage::init(const char * uri, bool read_only)
5454{
5555#define URIX_LEN (sizeof("rocks://") - 1) // Should be 8
5656 // We expect the URI to be for the form (note: three slashes)
……@@ -73,8 +73,8 @@ void RocksStorage::init(const char * uri)
7373 // Prefix for bloom filter -- first 2 chars.
7474 // options.prefix_extractor.reset(rocksdb::NewFixedPrefixTransform(2));
7575
76 // Create the file if it doesn't exist yet.
77 options.create_if_missing = true;
76 // Create the file if it doesn't exist yet (not in read-only mode).
77 options.create_if_missing = not read_only;
7878
7979 // The primary consumer of disk and RAM in RocksDB are the `*.sst`
8080 // files: each one is opened and memory-mapped. RocksDB does NOT
……@@ -114,12 +114,18 @@ void RocksStorage::init(const char * uri)
114114#endif
115115
116116 // Open the file.
117 rocksdb::Status s = rocksdb::DB::Open(options, file, &_rfile);
117 rocksdb::Status s;
118 if (read_only)
119 s = rocksdb::DB::OpenForReadOnly(options, file, &_rfile);
120 else
121 s = rocksdb::DB::Open(options, file, &_rfile);
118122
119123 if (not s.ok())
120124 throw IOException(TRACE_INFO, "Can't open file: %s",
121125 s.ToString().c_str());
122126
127 _read_only = read_only;
128
123129 // Does the file contain multiple atomspaces?
124130 auto it = _rfile->NewIterator(rocksdb::ReadOptions());
125131 it->Seek("f@");
……@@ -137,6 +143,9 @@ void RocksStorage::init(const char * uri)
137143 s = _rfile->Get(rocksdb::ReadOptions(), version_key, &version);
138144 if (not s.ok())
139145 {
146 if (read_only)
147 throw IOException(TRACE_INFO,
148 "Cannot open read-only: DB has no version (not initialized)");
140149 _rfile->Put(rocksdb::WriteOptions(), version_key, "2");
141150 }
142151 else
……@@ -148,7 +157,8 @@ void RocksStorage::init(const char * uri)
148157
149158 // If it's version 1, and does not (yet) contain multiple
150159 // spaces, it is safe to upgrade to version 2.
151 if (0 == version.compare("1") and not _multi_space)
160 // Skip upgrade in read-only mode.
161 if (not read_only and 0 == version.compare("1") and not _multi_space)
152162 _rfile->Put(rocksdb::WriteOptions(), version_key, "2");
153163 }
154164
……@@ -157,6 +167,9 @@ void RocksStorage::init(const char * uri)
157167 s = _rfile->Get(rocksdb::ReadOptions(), aid_key, &sid);
158168 if (not s.ok())
159169 {
170 if (read_only)
171 throw IOException(TRACE_INFO,
172 "Cannot open read-only: DB has no aid (not initialized)");
160173 _next_aid = 1;
161174 sid = aidtostr(1);
162175 s = _rfile->Put(rocksdb::WriteOptions(), aid_key, sid);
……@@ -165,10 +178,12 @@ void RocksStorage::init(const char * uri)
165178 _next_aid = strtoaid(sid) + 1; // next unused...
166179
167180// Informational prints.
168printf("Rocks: opened=%s\n", file.c_str());
181printf("Rocks: opened=%s%s\n", file.c_str(), read_only ? " (read-only)" : "");
169182printf("Rocks: DB-version=%s multi-space=%d initial aid=%lu\n",
170183get_version().c_str(), _multi_space, _next_aid.load());
171184
185 if (read_only) return;
186
172187 // Set up a SID for the TV predicate key.
173188 // This must match what the AtomSpace is using.
174189 // Tack on a leading colon, for convenience.
……@@ -180,13 +195,21 @@ void RocksStorage::open()
180195{
181196 // User might call us twice. If so, ignore the second call.
182197 if (_rfile) return;
183 init(_name.c_str());
198 init(_name.c_str(), false);
199}
200
201void RocksStorage::open_read_only()
202{
203 // User might call us twice. If so, ignore the second call.
204 if (_rfile) return;
205 init(_name.c_str(), true);
184206}
185207
186208RocksStorage::RocksStorage(std::string uri) :
187209 StorageNode(ROCKS_STORAGE_NODE, std::move(uri)),
188210 _rfile(nullptr),
189211 _multi_space(false),
212 _read_only(false),
190213 _unknown_type(false),
191214 _next_aid(0)
192215{
……@@ -217,14 +240,18 @@ void RocksStorage::close()
217240{
218241 if (nullptr == _rfile) return;
219242
220 logger().debug("Rocks: storing final aid=%lu\n", _next_aid.load());
221 write_aid();
243 if (not _read_only)
244 {
245 logger().debug("Rocks: storing final aid=%lu\n", _next_aid.load());
246 write_aid();
247 }
222248 delete _rfile;
223249 _rfile = nullptr;
224250 _next_aid = 0;
225251
226252 // Invalidate the local cache.
227253 _multi_space = false;
254 _read_only = false;
228255 _frame_map.clear();
229256 _fid_map.clear();
230257 _top_frames.clear();
……@@ -278,6 +305,7 @@ bool RocksStorage::connected(void)
278305///
279306void RocksStorage::barrier(AtomSpace* as)
280307{
308 if (_read_only) return;
281309 // belt and suspenders.
282310 write_aid();
283311}
opencog/persist/rocks/RocksStorage.h +5 -1
……@@ -48,7 +48,7 @@ namespace opencog
4848class RocksStorage : public StorageNode
4949{
5050 private:
51 void init(const char *);
51 void init(const char *, bool read_only = false);
5252 std::string _uri;
5353 rocksdb::DB* _rfile;
5454
……@@ -58,6 +58,9 @@ class RocksStorage : public StorageNode
5858 // True if file contains more than one atomspace.
5959 bool _multi_space;
6060
61 // True if opened in read-only mode.
62 bool _read_only;
63
6164 // Exception due to unknown Atom type.
6265 bool _unknown_type;
6366
……@@ -140,6 +143,7 @@ class RocksStorage : public StorageNode
140143 virtual ~RocksStorage();
141144
142145 void open(void);
146 void open_read_only(void);
143147 void close(void);
144148 bool connected(void); // connection to DB is alive
145149