summaryrefslogtreecommitdiffstats
path: root/common/storage_kyoto.cpp
diff options
context:
space:
mode:
authorAaron Seigo <aseigo@kde.org>2014-12-14 12:00:05 +0100
committerAaron Seigo <aseigo@kde.org>2014-12-14 12:00:05 +0100
commit7cc25005b8c46d1fa783d33def2c6923e8ef8469 (patch)
tree64fa59d17af29838396cf37b912b3babd885e5dd /common/storage_kyoto.cpp
parentbfc32f265e8ad72823db960fed371d72596003b7 (diff)
parenta6ed70495f9f3ecb21c26860dda16aadcdc91c3a (diff)
downloadsink-7cc25005b8c46d1fa783d33def2c6923e8ef8469.tar.gz
sink-7cc25005b8c46d1fa783d33def2c6923e8ef8469.zip
Merge branch 'unqlite'
Diffstat (limited to 'common/storage_kyoto.cpp')
-rw-r--r--common/storage_kyoto.cpp234
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
28class Storage::Private
29{
30public:
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
41Storage::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
61Storage::Private::~Private()
62{
63 if (dbOpen && inTransaction) {
64 db.end_transaction(false);
65 }
66}
67
68Storage::Storage(const QString &storageRoot, const QString &name, AccessMode mode)
69 : d(new Private(storageRoot, name, mode))
70{
71}
72
73Storage::~Storage()
74{
75 delete d;
76}
77
78bool Storage::isInTransaction() const
79{
80 return d->inTransaction;
81}
82
83bool 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
102bool 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
117void 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
127bool 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
137bool 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
147void 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
178void 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
215qint64 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
225void 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}