From 7cbf25f2f6d38efa384c7f8e0a5b2b2d274ebb00 Mon Sep 17 00:00:00 2001 From: Christian Mollekopf Date: Sun, 30 Nov 2014 17:57:31 +0100 Subject: Moved buffertest to store/test and turned it into a reproducible benchmark. --- store/CMakeLists.txt | 1 + store/database.cpp | 6 +- store/database.h | 3 +- store/test/CMakeLists.txt | 21 +++++++ store/test/calendar.fbs | 12 ++++ store/test/storagebenchmark.cpp | 132 ++++++++++++++++++++++++++++++++++++++++ 6 files changed, 171 insertions(+), 4 deletions(-) create mode 100644 store/CMakeLists.txt create mode 100644 store/test/CMakeLists.txt create mode 100644 store/test/calendar.fbs create mode 100644 store/test/storagebenchmark.cpp (limited to 'store') 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 @@ #include #include -Database::Database() +Database::Database(const QString &path) { int rc; QDir dir; - dir.mkdir("./testdb"); + dir.mkdir(path); //create file rc = mdb_env_create(&env); - rc = mdb_env_open(env, "./testdb", 0, 0664); + rc = mdb_env_open(env, path.toStdString().data(), 0, 0664); const int dbSize = 10485760*100; //10MB * 100 mdb_env_set_mapsize(env, dbSize); 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 @@ #include #include +#include class Database { public: - Database(); + Database(const QString &path); ~Database(); MDB_txn *startTransaction(); 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 @@ +set(CMAKE_AUTOMOC ON) +include_directories(${CMAKE_CURRENT_BINARY_DIR}) + +set(store_path "../") +set(store_SRCS + ${store_path}/database.cpp +) + +generate_flatbuffers(calendar) + +macro(manual_tests) + foreach(_testname ${ARGN}) + add_executable(${_testname} ${_testname}.cpp ${store_SRCS}) + qt5_use_modules(${_testname} Core Test) + target_link_libraries(${_testname} lmdb) + endforeach(_testname) +endmacro(auto_tests) + +manual_tests ( + storagebenchmark +) diff --git a/store/test/calendar.fbs b/store/test/calendar.fbs new file mode 100644 index 0000000..203ee43 --- /dev/null +++ b/store/test/calendar.fbs @@ -0,0 +1,12 @@ +// example IDL file + +namespace Calendar; + +table Event { + summary:string; + description:string; + attachment:[byte]; +} + +root_type Event; +file_identifier "AKFB"; 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 @@ +#include + +#include "calendar_generated.h" +#include +#include +#include +#include +#include +#include + +#include "store/database.h" + +using namespace Calendar; +using namespace flatbuffers; + +static std::string createEvent() +{ + FlatBufferBuilder fbb; + { + auto summary = fbb.CreateString("summary"); + + const int attachmentSize = 1024*2; // 2KB + int8_t rawData[attachmentSize]; + auto data = fbb.CreateVector(rawData, attachmentSize); + + Calendar::EventBuilder eventBuilder(fbb); + eventBuilder.add_summary(summary); + eventBuilder.add_attachment(data); + auto eventLocation = eventBuilder.Finish(); + FinishEventBuffer(fbb, eventLocation); + } + return std::string(reinterpret_cast(fbb.GetBufferPointer()), fbb.GetSize()); +} + +static void readEvent(const std::string &data) +{ + auto readEvent = GetEvent(data.c_str()); + std::cout << readEvent->summary()->c_str() << std::endl; +} + +class StorageBenchmark : public QObject +{ + Q_OBJECT +private: + //This should point to a directory on disk and not a ramdisk (since we're measuring performance) + QString testDataPath; + QString dbPath; + QString filePath; + +private Q_SLOTS: + void initTestCase() + { + testDataPath = "./"; + dbPath = testDataPath + "testdb"; + filePath = testDataPath + "buffer.fb"; + + QDir dir(testDataPath); + dir.remove("testdb/data.mdb"); + dir.remove("testdb/lock.mdb"); + dir.remove(filePath); + } + + void testWriteRead_data() + { + QTest::addColumn("useDb"); + QTest::addColumn("count"); + + const int count = 50000; + QTest::newRow("db, 50k") << true << count; + QTest::newRow("file, 50k") << false << count; + } + + void testWriteRead() + { + QFETCH(bool, useDb); + QFETCH(int, count); + + Database db(dbPath); + + std::ofstream myfile; + myfile.open(filePath.toStdString()); + + QTime time; + time.start(); + { + auto transaction = db.startTransaction(); + for (int i = 0; i < count; i++) { + const auto key = QString("key%1").arg(i); + auto event = createEvent(); + if (useDb) { + db.write(key.toStdString(), event, transaction); + } else { + myfile << event; + } + } + if (useDb) { + db.endTransaction(transaction); + } else { + myfile.close(); + } + } + const int writeDuration = time.elapsed(); + qDebug() << "Writing took[ms]: " << writeDuration; + + time.start(); + { + for (int i = 0; i < count; i++) { + const auto key = QString("key%1").arg(i); + if (useDb) { + db.read(key.toStdString()); + } + } + } + const int readDuration = time.elapsed(); + if (useDb) { + qDebug() << "Reading took[ms]: " << readDuration; + } else { + qDebug() << "File reading is not implemented."; + } + } + + void testSizes() + { + QFileInfo dbInfo(dbPath, "data.mdb"); + QFileInfo fileInfo(filePath); + qDebug() << "Database size [kb]: " << dbInfo.size()/1024; + qDebug() << "File size [kb]: " << fileInfo.size()/1024; + } +}; + +QTEST_MAIN(StorageBenchmark) +#include "storagebenchmark.moc" -- cgit v1.2.3