diff options
author | Aaron Seigo <aseigo@kde.org> | 2014-12-14 12:00:05 +0100 |
---|---|---|
committer | Aaron Seigo <aseigo@kde.org> | 2014-12-14 12:00:05 +0100 |
commit | 7cc25005b8c46d1fa783d33def2c6923e8ef8469 (patch) | |
tree | 64fa59d17af29838396cf37b912b3babd885e5dd /common/storage_kyoto.cpp | |
parent | bfc32f265e8ad72823db960fed371d72596003b7 (diff) | |
parent | a6ed70495f9f3ecb21c26860dda16aadcdc91c3a (diff) | |
download | sink-7cc25005b8c46d1fa783d33def2c6923e8ef8469.tar.gz sink-7cc25005b8c46d1fa783d33def2c6923e8ef8469.zip |
Merge branch 'unqlite'
Diffstat (limited to 'common/storage_kyoto.cpp')
-rw-r--r-- | common/storage_kyoto.cpp | 234 |
1 files changed, 0 insertions, 234 deletions
diff --git a/common/storage_kyoto.cpp b/common/storage_kyoto.cpp deleted file mode 100644 index 4179c8b..0000000 --- a/common/storage_kyoto.cpp +++ /dev/null | |||
@@ -1,234 +0,0 @@ | |||
1 | #include "storage.h" | ||
2 | |||
3 | #include <iostream> | ||
4 | |||
5 | #include <QAtomicInt> | ||
6 | #include <QDebug> | ||
7 | #include <QDir> | ||
8 | #include <QFileInfo> | ||
9 | #include <QReadWriteLock> | ||
10 | #include <QString> | ||
11 | #include <QTime> | ||
12 | |||
13 | #include <kchashdb.h> | ||
14 | |||
15 | //FIXME: Private::db needs to be shared process-wide for a given db; from the kc docs: | ||
16 | // "It is forbidden for multible database objects in a process to open the same database at the same time." | ||
17 | |||
18 | //TODO: research what can be done about this (from kc docs): | ||
19 | // "To avoid data missing or corruption, it is important to close every database file by the | ||
20 | // BasicDB::close method when the database is no longer in use." | ||
21 | |||
22 | //TODO: research answers for max open files limit -> | ||
23 | // "After that got sources of kyotocabinet and researched that for every kyoto File() | ||
24 | // object special TSDKey object created, and this object create pthread_key. By default | ||
25 | // one process can create limited number of this keys, and this number defined in PTHREAD_KEYS_MAX." | ||
26 | // - http://stackoverflow.com/questions/22023419/kyotocabinet-and-scalajava-limit-of-db-files-open | ||
27 | |||
28 | class Storage::Private | ||
29 | { | ||
30 | public: | ||
31 | Private(const QString &storageRoot, const QString &name, AccessMode m); | ||
32 | ~Private(); | ||
33 | |||
34 | QString name; | ||
35 | kyotocabinet::TreeDB db; | ||
36 | AccessMode mode; | ||
37 | bool dbOpen; | ||
38 | bool inTransaction; | ||
39 | }; | ||
40 | |||
41 | Storage::Private::Private(const QString &storageRoot, const QString &n, AccessMode m) | ||
42 | : name(n), | ||
43 | mode(m), | ||
44 | dbOpen(false), | ||
45 | inTransaction(false) | ||
46 | { | ||
47 | QDir dir; | ||
48 | dir.mkdir(storageRoot); | ||
49 | |||
50 | //create file | ||
51 | uint32_t openMode = kyotocabinet::BasicDB::OCREATE | | ||
52 | (mode == ReadOnly ? kyotocabinet::BasicDB::OREADER | ||
53 | : kyotocabinet::BasicDB::OWRITER); | ||
54 | dbOpen = db.open((storageRoot + "/" + name + ".kch").toStdString(), openMode); | ||
55 | if (!dbOpen) { | ||
56 | std::cerr << "Could not open database: " << db.error().codename(db.error().code()) << " " << db.error().message() << std::endl; | ||
57 | // TODO: handle error | ||
58 | } | ||
59 | } | ||
60 | |||
61 | Storage::Private::~Private() | ||
62 | { | ||
63 | if (dbOpen && inTransaction) { | ||
64 | db.end_transaction(false); | ||
65 | } | ||
66 | } | ||
67 | |||
68 | Storage::Storage(const QString &storageRoot, const QString &name, AccessMode mode) | ||
69 | : d(new Private(storageRoot, name, mode)) | ||
70 | { | ||
71 | } | ||
72 | |||
73 | Storage::~Storage() | ||
74 | { | ||
75 | delete d; | ||
76 | } | ||
77 | |||
78 | bool Storage::isInTransaction() const | ||
79 | { | ||
80 | return d->inTransaction; | ||
81 | } | ||
82 | |||
83 | bool Storage::startTransaction(AccessMode type) | ||
84 | { | ||
85 | if (!d->dbOpen) { | ||
86 | return false; | ||
87 | } | ||
88 | |||
89 | if (type == ReadWrite && d->mode != ReadWrite) { | ||
90 | return false; | ||
91 | } | ||
92 | |||
93 | if (d->inTransaction) { | ||
94 | return true; | ||
95 | } | ||
96 | |||
97 | //TODO handle errors | ||
98 | d->inTransaction = d->db.begin_transaction(); | ||
99 | return d->inTransaction; | ||
100 | } | ||
101 | |||
102 | bool Storage::commitTransaction() | ||
103 | { | ||
104 | if (!d->dbOpen) { | ||
105 | return false; | ||
106 | } | ||
107 | |||
108 | if (!d->inTransaction) { | ||
109 | return false; | ||
110 | } | ||
111 | |||
112 | bool success = d->db.end_transaction(true); | ||
113 | d->inTransaction = false; | ||
114 | return success; | ||
115 | } | ||
116 | |||
117 | void Storage::abortTransaction() | ||
118 | { | ||
119 | if (!d->dbOpen || !d->inTransaction) { | ||
120 | return; | ||
121 | } | ||
122 | |||
123 | d->db.end_transaction(false); | ||
124 | d->inTransaction = false; | ||
125 | } | ||
126 | |||
127 | bool Storage::write(const char *key, size_t keySize, const char *value, size_t valueSize) | ||
128 | { | ||
129 | if (!d->dbOpen) { | ||
130 | return false; | ||
131 | } | ||
132 | |||
133 | bool success = d->db.set(key, keySize, value, valueSize); | ||
134 | return success; | ||
135 | } | ||
136 | |||
137 | bool Storage::write(const std::string &sKey, const std::string &sValue) | ||
138 | { | ||
139 | if (!d->dbOpen) { | ||
140 | return false; | ||
141 | } | ||
142 | |||
143 | bool success = d->db.set(sKey, sValue); | ||
144 | return success; | ||
145 | } | ||
146 | |||
147 | void Storage::read(const std::string &sKey, | ||
148 | const std::function<bool(const std::string &value)> &resultHandler, | ||
149 | const std::function<void(const Storage::Error &error)> &errorHandler) | ||
150 | { | ||
151 | if (!d->dbOpen) { | ||
152 | Error error(d->name.toStdString(), -1, "Not open"); | ||
153 | errorHandler(error); | ||
154 | return; | ||
155 | } | ||
156 | |||
157 | std::string value; | ||
158 | if (sKey.empty()) { | ||
159 | kyotocabinet::DB::Cursor *cursor = d->db.cursor(); | ||
160 | cursor->jump(); | ||
161 | |||
162 | std::string key, value; | ||
163 | while (cursor->get_value(&value, true) && resultHandler(value)) {} | ||
164 | |||
165 | delete cursor; | ||
166 | return; | ||
167 | } else { | ||
168 | if (d->db.get(sKey, &value)) { | ||
169 | resultHandler(value); | ||
170 | return; | ||
171 | } | ||
172 | } | ||
173 | |||
174 | Error error(d->name.toStdString(), d->db.error().code(), d->db.error().message()); | ||
175 | errorHandler(error); | ||
176 | } | ||
177 | |||
178 | void Storage::read(const std::string &sKey, | ||
179 | const std::function<bool(void *ptr, int size)> &resultHandler, | ||
180 | const std::function<void(const Storage::Error &error)> &errorHandler) | ||
181 | { | ||
182 | if (!d->dbOpen) { | ||
183 | Error error(d->name.toStdString(), -1, "Not open"); | ||
184 | errorHandler(error); | ||
185 | return; | ||
186 | } | ||
187 | |||
188 | size_t valueSize; | ||
189 | char *valueBuffer; | ||
190 | if (sKey.empty()) { | ||
191 | kyotocabinet::DB::Cursor *cursor = d->db.cursor(); | ||
192 | cursor->jump(); | ||
193 | |||
194 | while ((valueBuffer = cursor->get_value(&valueSize, true))) { | ||
195 | bool ok = resultHandler(valueBuffer, valueSize); | ||
196 | delete[] valueBuffer; | ||
197 | if (!ok) { | ||
198 | break; | ||
199 | } | ||
200 | } | ||
201 | |||
202 | delete cursor; | ||
203 | } else { | ||
204 | valueBuffer = d->db.get(sKey.data(), sKey.size(), &valueSize); | ||
205 | if (valueBuffer) { | ||
206 | resultHandler(valueBuffer, valueSize); | ||
207 | } else { | ||
208 | Error error(d->name.toStdString(), d->db.error().code(), d->db.error().message()); | ||
209 | errorHandler(error); | ||
210 | } | ||
211 | delete[] valueBuffer; | ||
212 | } | ||
213 | } | ||
214 | |||
215 | qint64 Storage::diskUsage() const | ||
216 | { | ||
217 | if (!d->dbOpen) { | ||
218 | return 0; | ||
219 | } | ||
220 | |||
221 | QFileInfo info(QString::fromStdString(d->db.path())); | ||
222 | return info.size(); | ||
223 | } | ||
224 | |||
225 | void Storage::removeFromDisk() const | ||
226 | { | ||
227 | if (!d->dbOpen) { | ||
228 | return; | ||
229 | } | ||
230 | |||
231 | QFileInfo info(QString::fromStdString(d->db.path())); | ||
232 | QDir dir = info.dir(); | ||
233 | dir.remove(info.fileName()); | ||
234 | } | ||