aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2018-05-14 22:25:26 +0200
committerdec05eba <dec05eba@protonmail.com>2020-08-18 23:25:46 +0200
commitfa8d14018891d90e23fce0e510a01728970932f2 (patch)
tree723d8d126c87f974598fd865c22c516ea14bd699
parentc820b10adddc7a229cf2de99937d05a5715d2ab0 (diff)
Implement node load/fetch order
-rw-r--r--include/odhtdb/Database.hpp5
-rw-r--r--include/odhtdb/DatabaseOrder.hpp18
-rw-r--r--include/odhtdb/DatabaseStorage.hpp5
-rw-r--r--src/Database.cpp12
-rw-r--r--src/DatabaseStorage.cpp28
-rw-r--r--tests/main.cpp4
6 files changed, 56 insertions, 16 deletions
diff --git a/include/odhtdb/Database.hpp b/include/odhtdb/Database.hpp
index 332a784..11a6cd4 100644
--- a/include/odhtdb/Database.hpp
+++ b/include/odhtdb/Database.hpp
@@ -12,6 +12,7 @@
#include "Encryption.hpp"
#include "OwnedMemory.hpp"
#include "DatabaseOperation.hpp"
+#include "DatabaseOrder.hpp"
#include <opendht/dhtrunner.h>
#include <vector>
#include <ntp/NtpClient.hpp>
@@ -162,9 +163,9 @@ namespace odhtdb
~Database();
// Safe to call multiple times with same node hash, will be ignored if the node is already beeing seeded
- void seed(const DatabaseNode &nodeToSeed);
+ void seed(const DatabaseNode &nodeToSeed, DatabaseFetchOrder fetchOrder = DatabaseFetchOrder::OLDEST_FIRST);
void stopSeeding(const Hash &nodeHash);
- void loadNode(const Hash &nodeHash);
+ void loadNode(const Hash &nodeHash, DatabaseLoadOrder loadOrder = DatabaseLoadOrder::OLDEST_FIRST);
// Throws DatabaseCreateException on failure.
std::unique_ptr<DatabaseCreateResponse> create();
diff --git a/include/odhtdb/DatabaseOrder.hpp b/include/odhtdb/DatabaseOrder.hpp
new file mode 100644
index 0000000..d9c3906
--- /dev/null
+++ b/include/odhtdb/DatabaseOrder.hpp
@@ -0,0 +1,18 @@
+#pragma once
+
+#include "types.hpp"
+
+namespace odhtdb
+{
+ enum class DatabaseFetchOrder : u8
+ {
+ OLDEST_FIRST,
+ NEWEST_FIRST
+ };
+
+ enum class DatabaseLoadOrder : u8
+ {
+ OLDEST_FIRST,
+ NEWEST_FIRST
+ };
+}
diff --git a/include/odhtdb/DatabaseStorage.hpp b/include/odhtdb/DatabaseStorage.hpp
index 73b22b9..a004619 100644
--- a/include/odhtdb/DatabaseStorage.hpp
+++ b/include/odhtdb/DatabaseStorage.hpp
@@ -9,6 +9,7 @@
#include "Permission.hpp"
#include "OwnedMemory.hpp"
#include "DatabaseOperation.hpp"
+#include "DatabaseOrder.hpp"
#include <vector>
#include <stdexcept>
#include <boost/filesystem/path.hpp>
@@ -75,7 +76,7 @@ namespace odhtdb
DatabaseStorage(Database *database, const boost::filesystem::path &storagePath);
~DatabaseStorage();
- void loadNode(const Hash &nodeHash);
+ void loadNode(const Hash &nodeHash, DatabaseLoadOrder loadOrder);
bool doesNodeExist(const Hash &nodeHash) const;
bool doesDataExist(const Hash &requestHash) const;
@@ -96,7 +97,7 @@ namespace odhtdb
void addUser(const Hash &nodeHash, const Signature::PublicKey &userPublicKey, const DataView &groupId);
void fetchNodeRaw(const Hash &nodeHash, FetchNodeRawCallbackFunc callbackFunc);
- void fetchNodeAddDataRaw(const Hash &nodeHash, FetchNodeAddDataRawCallbackFunc callbackFunc);
+ void fetchNodeAddDataRaw(const Hash &nodeHash, FetchNodeAddDataRawCallbackFunc callbackFunc, DatabaseFetchOrder fetchOrder);
void fetchNodeUserActionGaps(const Hash &nodeHash, FetchNodeUserActionGapsCallbackFunc callbackFunc);
void fetchNodeUserLatestActionCounter(const Hash &nodeHash, FetchNodeUserLatestActionCounterCallbackFunc callbackFunc);
diff --git a/src/Database.cpp b/src/Database.cpp
index ddef6d1..93dec99 100644
--- a/src/Database.cpp
+++ b/src/Database.cpp
@@ -170,7 +170,7 @@ namespace odhtdb
u64 range;
};
- void Database::seed(const DatabaseNode &nodeToSeed)
+ void Database::seed(const DatabaseNode &nodeToSeed, DatabaseFetchOrder fetchOrder)
{
if(seedInfoMap.find(*nodeToSeed.getRequestHash()) != seedInfoMap.end())
{
@@ -208,7 +208,7 @@ namespace odhtdb
newSeedInfo.reponseKeyInfoHash = responseKeyShared;
// TODO: If this response key is spammed, generate a new one.
- auto responseKeyFuture = node.listen(*newSeedInfo.reponseKeyInfoHash, [this, nodeToSeed](const shared_ptr<Value> &value)
+ auto responseKeyFuture = node.listen(*responseKeyShared, [this, nodeToSeed](const shared_ptr<Value> &value)
{
const Hash requestHash(value->data.data(), value->data.size());
if(requestHash == *nodeToSeed.getRequestHash())
@@ -233,6 +233,7 @@ namespace odhtdb
return true; // We sent the request, ignore our own requests
bool userWantsCreateNode = deserializer.extract<u8>() == 1;
+ DatabaseFetchOrder fetchOrder = deserializer.extract<DatabaseFetchOrder>();
if(userWantsCreateNode)
{
@@ -287,7 +288,7 @@ namespace odhtdb
if(!ok)
Log::error("Failed to put response for old data for 'add' data");
});
- });
+ }, fetchOrder);
}
catch (std::exception &e)
{
@@ -302,6 +303,7 @@ namespace odhtdb
serializer.add(responseKey, OPENDHT_INFOHASH_LEN);
bool iHaveCreateNode = databaseStorage.doesNodeExist(*nodeToSeed.getRequestHash());
serializer.add(iHaveCreateNode ? (u8)0 : (u8)1);
+ serializer.add(fetchOrder);
DataViewMap<u64> userLatestActionCounter;
databaseStorage.fetchNodeUserActionGaps(*nodeToSeed.getRequestHash(), [&serializer, &userLatestActionCounter](const DataView userPublicKey, u64 actionGapStart, u64 actionGapRange)
@@ -349,9 +351,9 @@ namespace odhtdb
}
}
- void Database::loadNode(const Hash &nodeHash)
+ void Database::loadNode(const Hash &nodeHash, DatabaseLoadOrder loadOrder)
{
- databaseStorage.loadNode(nodeHash);
+ databaseStorage.loadNode(nodeHash, loadOrder);
}
unique_ptr<DatabaseCreateResponse> Database::create()
diff --git a/src/DatabaseStorage.cpp b/src/DatabaseStorage.cpp
index 6064ee5..8bef77e 100644
--- a/src/DatabaseStorage.cpp
+++ b/src/DatabaseStorage.cpp
@@ -215,11 +215,19 @@ namespace odhtdb
cleanup();
}
- void DatabaseStorage::loadNode(const Hash &nodeHash)
+ void DatabaseStorage::loadNode(const Hash &nodeHash, DatabaseLoadOrder loadOrder)
{
+ string orderByString;
+ if(loadOrder == DatabaseLoadOrder::OLDEST_FIRST)
+ orderByString = " ORDER BY timestamp ASC";
+ else if(loadOrder == DatabaseLoadOrder::NEWEST_FIRST)
+ orderByString = " ORDER BY timestamp DESC";
+
if(database->onCreateNodeCallbackFunc)
{
- SqlQuery nodeQuery(sqliteDb, "SELECT timestamp, creatorPublicKey, adminGroupId From Node WHERE nodeHash = ?", { DataView(nodeHash.getData(), nodeHash.getSize()) });
+ string queryStr = "SELECT timestamp, creatorPublicKey, adminGroupId From Node WHERE nodeHash = ?";
+ queryStr += orderByString;
+ SqlQuery nodeQuery(sqliteDb, queryStr.c_str(), { DataView(nodeHash.getData(), nodeHash.getSize()) });
while(nodeQuery.next())
{
u64 timestamp = nodeQuery.getInt64(0);
@@ -234,7 +242,9 @@ namespace odhtdb
}
}
- SqlQuery nodeQuery(sqliteDb, "SELECT id, requestHash, operation, timestamp, creatorPublicKey From NodeAddData WHERE node = ? AND decrypted = 1", { DataView(nodeHash.getData(), nodeHash.getSize()) });
+ string queryStr = "SELECT id, requestHash, operation, timestamp, creatorPublicKey From NodeAddData WHERE node = ? AND decrypted = 1";
+ queryStr += orderByString;
+ SqlQuery nodeQuery(sqliteDb, queryStr.c_str(), { DataView(nodeHash.getData(), nodeHash.getSize()) });
while(nodeQuery.next())
{
i64 rowId = nodeQuery.getInt64(0);
@@ -732,9 +742,17 @@ namespace odhtdb
}
}
- void DatabaseStorage::fetchNodeAddDataRaw(const Hash &nodeHash, FetchNodeAddDataRawCallbackFunc callbackFunc)
+ void DatabaseStorage::fetchNodeAddDataRaw(const Hash &nodeHash, FetchNodeAddDataRawCallbackFunc callbackFunc, DatabaseFetchOrder fetchOrder)
{
- SqlQuery query(sqliteDb, "SELECT rawData.data, nodeAddData.creatorPublicKey, nodeAddData.userActionCounter From NodeAddData AS nodeAddData INNER JOIN NodeAddDataRaw AS rawData ON rawData.nodeAddDataId = nodeAddData.id WHERE nodeAddData.node = ?", { DataView(nodeHash.getData(), nodeHash.getSize()) });
+ string orderByString;
+ if(fetchOrder == DatabaseFetchOrder::OLDEST_FIRST)
+ orderByString = " ORDER BY nodeAddData.timestamp ASC";
+ else if(fetchOrder == DatabaseFetchOrder::NEWEST_FIRST)
+ orderByString = " ORDER BY nodeAddData.timestamp DESC";
+
+ string queryStr = "SELECT rawData.data, nodeAddData.creatorPublicKey, nodeAddData.userActionCounter From NodeAddData AS nodeAddData INNER JOIN NodeAddDataRaw AS rawData ON rawData.nodeAddDataId = nodeAddData.id WHERE nodeAddData.node = ?";
+ queryStr += orderByString;
+ SqlQuery query(sqliteDb, queryStr.c_str(), { DataView(nodeHash.getData(), nodeHash.getSize()) });
while(query.next())
{
const DataView rawData = query.getBlob(0);
diff --git a/tests/main.cpp b/tests/main.cpp
index 0174384..07e7131 100644
--- a/tests/main.cpp
+++ b/tests/main.cpp
@@ -193,7 +193,7 @@ int main()
database.addUser(databaseNode, *adminUserKey, localUserKeyPair.getPublicKey(), databaseCreateResponse->getNodeAdminGroupId()->getView());
database.addData(databaseNode, localUserKeyPair, DataView{ (void*)"hello, aaald!", 13 });
- database.seed(databaseNode);
+ database.seed(databaseNode, DatabaseFetchOrder::NEWEST_FIRST);
this_thread::sleep_for(chrono::seconds(3));
assertEquals(1, createNodeCounter);
@@ -210,7 +210,7 @@ int main()
Database database("bootstrap.ring.cx", 4222, storagePath, callbackFuncs);
database.loadNode(*databaseNode.getRequestHash());
- database.seed(databaseNode);
+ database.seed(databaseNode, DatabaseFetchOrder::NEWEST_FIRST);
this_thread::sleep_for(chrono::seconds(3));
assertEquals(1, createNodeCounter);