summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Mollekopf <chrigi_1@fastmail.fm>2014-11-30 17:57:31 +0100
committerChristian Mollekopf <chrigi_1@fastmail.fm>2014-11-30 17:57:31 +0100
commit7cbf25f2f6d38efa384c7f8e0a5b2b2d274ebb00 (patch)
tree583e0a4bdebe15c73d9860e78480517034e6ca9f
parent7373f1a92c2d6d0790f6a47a011c107c32064cc8 (diff)
downloadsink-7cbf25f2f6d38efa384c7f8e0a5b2b2d274ebb00.tar.gz
sink-7cbf25f2f6d38efa384c7f8e0a5b2b2d274ebb00.zip
Moved buffertest to store/test and turned it into a reproducible benchmark.
-rw-r--r--CMakeLists.txt4
-rw-r--r--buffertest/CMakeLists.txt30
-rw-r--r--buffertest/main.cpp67
-rw-r--r--store/CMakeLists.txt1
-rw-r--r--store/database.cpp6
-rw-r--r--store/database.h3
-rw-r--r--store/test/CMakeLists.txt21
-rw-r--r--store/test/calendar.fbs (renamed from buffertest/calendar.fbs)0
-rw-r--r--store/test/storagebenchmark.cpp132
9 files changed, 161 insertions, 103 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index f16dc6a..0313b65 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -47,7 +47,7 @@ add_subdirectory(client)
47# the resource 47# the resource
48add_subdirectory(resource) 48add_subdirectory(resource)
49 49
50# the buffertest 50# the store
51add_subdirectory(buffertest) 51add_subdirectory(store)
52 52
53feature_summary(WHAT ALL FATAL_ON_MISSING_REQUIRED_PACKAGES) 53feature_summary(WHAT ALL FATAL_ON_MISSING_REQUIRED_PACKAGES)
diff --git a/buffertest/CMakeLists.txt b/buffertest/CMakeLists.txt
deleted file mode 100644
index fd100d0..0000000
--- a/buffertest/CMakeLists.txt
+++ /dev/null
@@ -1,30 +0,0 @@
1project(toynadi_buffertest)
2
3include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR})
4
5set(store_path "../store/")
6
7set(toynadinbuffertest_SRCS
8 ${store_path}/database.cpp
9 main.cpp
10)
11
12set(SCHEMAS calendar.fbs)
13set(SCHEMA_SOURCEFILES calendar_generated.h)
14
15add_custom_command(OUTPUT ${SCHEMA_SOURCEFILES}
16 COMMAND flatc -c ${CMAKE_CURRENT_SOURCE_DIR}/calendar.fbs
17 COMMENT "Generating buffers"
18 WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
19 DEPENDS ${SCHEMAS}
20 VERBATIM
21)
22
23SET_SOURCE_FILES_PROPERTIES(${SCHEMA_SOURCEFILES} PROPERTIES GENERATED 1)
24ADD_CUSTOM_TARGET(generate_buffers ALL DEPENDS ${SCHEMA_SOURCEFILES})
25
26add_executable(${PROJECT_NAME} ${toynadinbuffertest_SRCS})
27qt5_use_modules(${PROJECT_NAME} Core)
28target_link_libraries(${PROJECT_NAME} lmdb)
29install(TARGETS ${PROJECT_NAME} DESTINATION bin)
30
diff --git a/buffertest/main.cpp b/buffertest/main.cpp
deleted file mode 100644
index 437e5b3..0000000
--- a/buffertest/main.cpp
+++ /dev/null
@@ -1,67 +0,0 @@
1#include "calendar_generated.h"
2#include <iostream>
3#include <fstream>
4#include <QDir>
5#include <QString>
6#include <QTime>
7#include <qdebug.h>
8
9#include "store/database.h"
10
11using namespace Calendar;
12using namespace flatbuffers;
13
14std::string createEvent(bool createAttachment = false)
15{
16 FlatBufferBuilder fbb;
17 {
18 auto summary = fbb.CreateString("summary");
19
20 // const int attachmentSize = 1024 * 1024; // 1MB
21 const int attachmentSize = 1024*2; // 1KB
22 int8_t rawData[attachmentSize];
23 auto data = fbb.CreateVector(rawData, attachmentSize);
24
25 Calendar::EventBuilder eventBuilder(fbb);
26 eventBuilder.add_summary(summary);
27 eventBuilder.add_attachment(data);
28 auto eventLocation = eventBuilder.Finish();
29 FinishEventBuffer(fbb, eventLocation);
30 }
31 return std::string(reinterpret_cast<const char *>(fbb.GetBufferPointer()), fbb.GetSize());
32}
33
34void readEvent(const std::string &data)
35{
36 auto readEvent = GetEvent(data.c_str());
37 std::cout << readEvent->summary()->c_str() << std::endl;
38}
39
40int main(int argc, char **argv)
41{
42 Database db;
43 const int count = 50000;
44 QTime time;
45 time.start();
46 // std::ofstream myfile;
47 // myfile.open ("buffer.fb");
48 //
49 auto transaction = db.startTransaction();
50 for (int i = 0; i < count; i++) {
51 const auto key = QString("key%1").arg(i);
52 auto event = createEvent(true);
53 db.write(key.toStdString(), event, transaction);
54
55 // myfile << createEvent();
56 }
57 db.endTransaction(transaction);
58 // myfile.close();
59 qDebug() << "Writing took: " << time.elapsed();
60
61 time.start();
62 for (int i = 0; i < count; i++) {
63 const auto key = QString("key%1").arg(i);
64 db.read(key.toStdString());
65 }
66 qDebug() << "Reading took: " << time.elapsed();
67}
diff --git a/store/CMakeLists.txt b/store/CMakeLists.txt
new file mode 100644
index 0000000..552439e
--- /dev/null
+++ b/store/CMakeLists.txt
@@ -0,0 +1 @@
add_subdirectory(test)
diff --git a/store/database.cpp b/store/database.cpp
index d6fe7c0..c16a077 100644
--- a/store/database.cpp
+++ b/store/database.cpp
@@ -6,16 +6,16 @@
6#include <QTime> 6#include <QTime>
7#include <qdebug.h> 7#include <qdebug.h>
8 8
9Database::Database() 9Database::Database(const QString &path)
10{ 10{
11 int rc; 11 int rc;
12 12
13 QDir dir; 13 QDir dir;
14 dir.mkdir("./testdb"); 14 dir.mkdir(path);
15 15
16 //create file 16 //create file
17 rc = mdb_env_create(&env); 17 rc = mdb_env_create(&env);
18 rc = mdb_env_open(env, "./testdb", 0, 0664); 18 rc = mdb_env_open(env, path.toStdString().data(), 0, 0664);
19 const int dbSize = 10485760*100; //10MB * 100 19 const int dbSize = 10485760*100; //10MB * 100
20 mdb_env_set_mapsize(env, dbSize); 20 mdb_env_set_mapsize(env, dbSize);
21 21
diff --git a/store/database.h b/store/database.h
index b42b9f7..1a124be 100644
--- a/store/database.h
+++ b/store/database.h
@@ -1,9 +1,10 @@
1#include <lmdb.h> 1#include <lmdb.h>
2#include <string> 2#include <string>
3#include <QString>
3 4
4class Database { 5class Database {
5public: 6public:
6 Database(); 7 Database(const QString &path);
7 ~Database(); 8 ~Database();
8 MDB_txn *startTransaction(); 9 MDB_txn *startTransaction();
9 void endTransaction(MDB_txn *transaction); 10 void endTransaction(MDB_txn *transaction);
diff --git a/store/test/CMakeLists.txt b/store/test/CMakeLists.txt
new file mode 100644
index 0000000..4743cfb
--- /dev/null
+++ b/store/test/CMakeLists.txt
@@ -0,0 +1,21 @@
1set(CMAKE_AUTOMOC ON)
2include_directories(${CMAKE_CURRENT_BINARY_DIR})
3
4set(store_path "../")
5set(store_SRCS
6 ${store_path}/database.cpp
7)
8
9generate_flatbuffers(calendar)
10
11macro(manual_tests)
12 foreach(_testname ${ARGN})
13 add_executable(${_testname} ${_testname}.cpp ${store_SRCS})
14 qt5_use_modules(${_testname} Core Test)
15 target_link_libraries(${_testname} lmdb)
16 endforeach(_testname)
17endmacro(auto_tests)
18
19manual_tests (
20 storagebenchmark
21)
diff --git a/buffertest/calendar.fbs b/store/test/calendar.fbs
index 203ee43..203ee43 100644
--- a/buffertest/calendar.fbs
+++ b/store/test/calendar.fbs
diff --git a/store/test/storagebenchmark.cpp b/store/test/storagebenchmark.cpp
new file mode 100644
index 0000000..939ae0b
--- /dev/null
+++ b/store/test/storagebenchmark.cpp
@@ -0,0 +1,132 @@
1#include <QtTest>
2
3#include "calendar_generated.h"
4#include <iostream>
5#include <fstream>
6#include <QDir>
7#include <QString>
8#include <QTime>
9#include <qdebug.h>
10
11#include "store/database.h"
12
13using namespace Calendar;
14using namespace flatbuffers;
15
16static std::string createEvent()
17{
18 FlatBufferBuilder fbb;
19 {
20 auto summary = fbb.CreateString("summary");
21
22 const int attachmentSize = 1024*2; // 2KB
23 int8_t rawData[attachmentSize];
24 auto data = fbb.CreateVector(rawData, attachmentSize);
25
26 Calendar::EventBuilder eventBuilder(fbb);
27 eventBuilder.add_summary(summary);
28 eventBuilder.add_attachment(data);
29 auto eventLocation = eventBuilder.Finish();
30 FinishEventBuffer(fbb, eventLocation);
31 }
32 return std::string(reinterpret_cast<const char *>(fbb.GetBufferPointer()), fbb.GetSize());
33}
34
35static void readEvent(const std::string &data)
36{
37 auto readEvent = GetEvent(data.c_str());
38 std::cout << readEvent->summary()->c_str() << std::endl;
39}
40
41class StorageBenchmark : public QObject
42{
43 Q_OBJECT
44private:
45 //This should point to a directory on disk and not a ramdisk (since we're measuring performance)
46 QString testDataPath;
47 QString dbPath;
48 QString filePath;
49
50private Q_SLOTS:
51 void initTestCase()
52 {
53 testDataPath = "./";
54 dbPath = testDataPath + "testdb";
55 filePath = testDataPath + "buffer.fb";
56
57 QDir dir(testDataPath);
58 dir.remove("testdb/data.mdb");
59 dir.remove("testdb/lock.mdb");
60 dir.remove(filePath);
61 }
62
63 void testWriteRead_data()
64 {
65 QTest::addColumn<bool>("useDb");
66 QTest::addColumn<int>("count");
67
68 const int count = 50000;
69 QTest::newRow("db, 50k") << true << count;
70 QTest::newRow("file, 50k") << false << count;
71 }
72
73 void testWriteRead()
74 {
75 QFETCH(bool, useDb);
76 QFETCH(int, count);
77
78 Database db(dbPath);
79
80 std::ofstream myfile;
81 myfile.open(filePath.toStdString());
82
83 QTime time;
84 time.start();
85 {
86 auto transaction = db.startTransaction();
87 for (int i = 0; i < count; i++) {
88 const auto key = QString("key%1").arg(i);
89 auto event = createEvent();
90 if (useDb) {
91 db.write(key.toStdString(), event, transaction);
92 } else {
93 myfile << event;
94 }
95 }
96 if (useDb) {
97 db.endTransaction(transaction);
98 } else {
99 myfile.close();
100 }
101 }
102 const int writeDuration = time.elapsed();
103 qDebug() << "Writing took[ms]: " << writeDuration;
104
105 time.start();
106 {
107 for (int i = 0; i < count; i++) {
108 const auto key = QString("key%1").arg(i);
109 if (useDb) {
110 db.read(key.toStdString());
111 }
112 }
113 }
114 const int readDuration = time.elapsed();
115 if (useDb) {
116 qDebug() << "Reading took[ms]: " << readDuration;
117 } else {
118 qDebug() << "File reading is not implemented.";
119 }
120 }
121
122 void testSizes()
123 {
124 QFileInfo dbInfo(dbPath, "data.mdb");
125 QFileInfo fileInfo(filePath);
126 qDebug() << "Database size [kb]: " << dbInfo.size()/1024;
127 qDebug() << "File size [kb]: " << fileInfo.size()/1024;
128 }
129};
130
131QTEST_MAIN(StorageBenchmark)
132#include "storagebenchmark.moc"