forked from townforge/townforge
db_lmdb: do not use DUPSORT for cc_events table
It increase the size somewhat but can store events of arbitrary length.
This commit is contained in:
parent
36bf25a85a
commit
3e93a91c28
@ -2062,7 +2062,7 @@ public:
|
||||
virtual void add_cc_events(uint64_t height, const std::vector<cc::game_event_t> &events) = 0;
|
||||
virtual void remove_cc_events(uint64_t height) = 0;
|
||||
virtual bool get_cc_events(uint64_t height, uint32_t account, uint32_t flag, std::vector<cc::game_event_t> &events) const = 0;
|
||||
virtual bool get_cc_game_events(uint64_t min_height, uint64_t max_height, uint32_t account, uint32_t flag, uint32_t item, uint8_t cmd, bool (*filter)(uint8_t, uint32_t, uint32_t, const std::vector<uint32_t>&, const std::vector<uint32_t>&, const std::vector<std::pair<uint32_t, uint32_t>>&, const std::string&, const std::string& (*get_event)()), std::vector<cc::game_event_t> &events) const = 0;
|
||||
virtual bool get_cc_game_events(uint64_t min_height, uint64_t max_height, uint32_t account, uint32_t flag, uint32_t item, uint8_t cmd, bool (*filter)(uint8_t, uint32_t, const std::vector<uint32_t>&, const std::vector<uint32_t>&, const std::vector<std::pair<uint32_t, uint32_t>>&, const std::string&, const std::string& (*get_event)()), std::vector<cc::game_event_t> &events) const = 0;
|
||||
|
||||
virtual void add_cc_name(const std::string &name, uint32_t type, uint32_t id) = 0;
|
||||
virtual void remove_cc_name(const std::string &name) = 0;
|
||||
|
@ -321,55 +321,6 @@ int BlockchainLMDB::compare_string_nocase(const MDB_val *a, const MDB_val *b)
|
||||
return 0;
|
||||
}
|
||||
|
||||
enum event_match_t: uint32_t { em_account, em_account_flag, em_account_flag_event };
|
||||
int BlockchainLMDB::compare_events(const MDB_val *a, const MDB_val *b)
|
||||
{
|
||||
// a[1] size is an int which tells is how much of the record to match against
|
||||
const uint32_t match = a[1].mv_size;
|
||||
|
||||
const char *aptr = (const char*)a->mv_data;
|
||||
const char *bptr = (const char*)b->mv_data;
|
||||
uint32_t va32, vb32;
|
||||
|
||||
memcpy(&va32, aptr, sizeof(va32));
|
||||
memcpy(&vb32, bptr, sizeof(vb32));
|
||||
if (va32 < vb32)
|
||||
return -1;
|
||||
if (va32 > vb32)
|
||||
return 1;
|
||||
if (match == em_account)
|
||||
return 0;
|
||||
|
||||
aptr += sizeof(va32);
|
||||
bptr += sizeof(vb32);
|
||||
|
||||
memcpy(&va32, aptr, sizeof(va32));
|
||||
memcpy(&vb32, bptr, sizeof(vb32));
|
||||
if (va32 < vb32)
|
||||
return -1;
|
||||
if (va32 > vb32)
|
||||
return 1;
|
||||
if (match == em_account_flag)
|
||||
return 0;
|
||||
|
||||
aptr += sizeof(va32);
|
||||
bptr += sizeof(vb32);
|
||||
|
||||
const ssize_t a_size = a->mv_size - (aptr - (const char*)a->mv_data);
|
||||
const ssize_t b_size = b->mv_size - (bptr - (const char*)b->mv_data);
|
||||
|
||||
unsigned int len = a_size;
|
||||
ssize_t len_diff = (ssize_t) a_size - (ssize_t) b_size;
|
||||
if (len_diff > 0)
|
||||
{
|
||||
len = b_size;
|
||||
len_diff = 1;
|
||||
}
|
||||
|
||||
int diff = memcmp(aptr, bptr, len);
|
||||
return diff ? diff : len_diff<0 ? -1 : len_diff;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace
|
||||
@ -410,7 +361,7 @@ namespace
|
||||
* cc_trade_used nonce uint64_t
|
||||
* cc_orders nonce {order metadata}
|
||||
* cc_shares city/height {share metadata}
|
||||
* cc_events height account/flag/etc/string
|
||||
* cc_events height/index/account {data/string}
|
||||
* cc_names name {name metadata}
|
||||
* cc_discoveries id {discovery metadata}
|
||||
* cc_special_events city {special event metadata}
|
||||
@ -805,14 +756,13 @@ typedef struct mdb_order_t
|
||||
#pragma pack(push, 1)
|
||||
struct mdb_events_data_header_t
|
||||
{
|
||||
uint64_t height;
|
||||
uint32_t index;
|
||||
uint32_t account;
|
||||
uint32_t flag;
|
||||
};
|
||||
struct mdb_events_data_t
|
||||
{
|
||||
uint32_t account;
|
||||
uint32_t flag;
|
||||
std::vector<uint32_t> extra_flags;
|
||||
std::vector<uint32_t> flags;
|
||||
std::vector<uint32_t> counterparties;
|
||||
std::vector<std::pair<uint32_t, uint32_t>> items;
|
||||
int64_t balance;
|
||||
@ -823,12 +773,9 @@ struct mdb_events_data_t
|
||||
|
||||
bool skip_event;
|
||||
mdb_events_data_t(): skip_event(false) {}
|
||||
mdb_events_data_t(uint32_t account, uint32_t flag): account(account), flag(flag), balance(0), nonce(0), tx_fee(0), cmd(0), skip_event(false) {}
|
||||
|
||||
BEGIN_SERIALIZE_OBJECT()
|
||||
FIELD(account)
|
||||
FIELD(flag)
|
||||
FIELD(extra_flags)
|
||||
FIELD(flags)
|
||||
FIELD(counterparties)
|
||||
FIELD(items)
|
||||
VARINT_FIELD_SIGNED(balance)
|
||||
@ -1008,6 +955,22 @@ typedef struct mdb_cc_hunt_info
|
||||
uint32_t bears;
|
||||
} mdb_cc_hunt_info;
|
||||
|
||||
int BlockchainLMDB::compare_events(const MDB_val *a, const MDB_val *b)
|
||||
{
|
||||
const mdb_events_data_header_t *ah = (const mdb_events_data_header_t*)a->mv_data;
|
||||
const mdb_events_data_header_t *bh = (const mdb_events_data_header_t*)b->mv_data;
|
||||
const int64_t dh = ah->height - bh->height;
|
||||
if (dh)
|
||||
return dh > 0 ? 1 : -1;
|
||||
const int32_t di = ah->index - bh->index;
|
||||
if (di)
|
||||
return di;
|
||||
const int32_t da = ah->account - bh->account;
|
||||
if (da)
|
||||
return da;
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::atomic<uint64_t> mdb_txn_safe::num_active_txns{0};
|
||||
std::atomic_flag mdb_txn_safe::creation_gate = ATOMIC_FLAG_INIT;
|
||||
|
||||
@ -2136,7 +2099,7 @@ void BlockchainLMDB::open(const std::string& filename, const int db_flags)
|
||||
lmdb_db_open(txn, LMDB_CC_TRADE_USED, MDB_INTEGERKEY | MDB_CREATE, m_cc_trade_used, "Failed to open db handle for m_cc_trade_used");
|
||||
lmdb_db_open(txn, LMDB_CC_ORDERS, MDB_INTEGERKEY | MDB_CREATE | MDB_DUPSORT | MDB_DUPFIXED, m_cc_orders, "Failed to open db handle for m_cc_orders");
|
||||
lmdb_db_open(txn, LMDB_CC_SHARES, MDB_INTEGERKEY | MDB_CREATE | MDB_DUPSORT | MDB_DUPFIXED, m_cc_shares, "Failed to open db handle for m_cc_shares");
|
||||
lmdb_db_open(txn, LMDB_CC_EVENTS, MDB_INTEGERKEY | MDB_CREATE | MDB_DUPSORT, m_cc_events, "Failed to open db handle for m_cc_events");
|
||||
lmdb_db_open(txn, LMDB_CC_EVENTS, MDB_CREATE, m_cc_events, "Failed to open db handle for m_cc_events");
|
||||
lmdb_db_open(txn, LMDB_CC_NAMES, MDB_CREATE, m_cc_names, "Failed to open db handle for m_cc_names");
|
||||
lmdb_db_open(txn, LMDB_CC_DISCOVERIES, MDB_INTEGERKEY | MDB_CREATE, m_cc_discoveries, "Failed to open db handle for m_cc_discoveries");
|
||||
lmdb_db_open(txn, LMDB_CC_SPECIAL_EVENTS, MDB_INTEGERKEY | MDB_CREATE, m_cc_special_events, "Failed to open db handle for m_cc_special_events");
|
||||
@ -2182,8 +2145,7 @@ void BlockchainLMDB::open(const std::string& filename, const int db_flags)
|
||||
mdb_set_dupsort(txn, m_cc_trade_used, compare_uint64);
|
||||
mdb_set_dupsort(txn, m_cc_orders, compare_uint64);
|
||||
mdb_set_dupsort(txn, m_cc_shares, compare_uint32_uint64);
|
||||
mdb_set_compare(txn, m_cc_events, compare_uint64);
|
||||
mdb_set_dupsort(txn, m_cc_events, compare_events);
|
||||
mdb_set_compare(txn, m_cc_events, compare_events);
|
||||
mdb_set_compare(txn, m_cc_names, compare_string_nocase);
|
||||
mdb_set_compare(txn, m_cc_discoveries, compare_uint32);
|
||||
mdb_set_compare(txn, m_cc_special_events, compare_uint32);
|
||||
@ -8355,13 +8317,27 @@ void BlockchainLMDB::add_cc_events(uint64_t height, const std::vector<cc::game_e
|
||||
|
||||
CURSOR(cc_events)
|
||||
|
||||
MDB_val k, v;
|
||||
int result = mdb_cursor_get(m_cur_cc_events, &k, &v, MDB_LAST);
|
||||
if (result && result != MDB_NOTFOUND)
|
||||
throw0(DB_ERROR(lmdb_error("Failed to get last event data from db: ", result).c_str()));
|
||||
uint32_t next_index = 0;
|
||||
if (result != MDB_NOTFOUND)
|
||||
{
|
||||
if (height == ((const mdb_events_data_header_t*)k.mv_data)->height)
|
||||
next_index = ((const mdb_events_data_header_t*)k.mv_data)->index + 1;
|
||||
}
|
||||
|
||||
for (const auto &e: events)
|
||||
{
|
||||
mdb_events_data_header_t header;
|
||||
mdb_events_data_t data;
|
||||
data.account = e.account;
|
||||
data.flag = e.flags.empty() ? 0 : e.flags.front();
|
||||
if (e.flags.size() > 1)
|
||||
std::copy(e.flags.begin() + 1, e.flags.end(), std::back_inserter(data.extra_flags));
|
||||
|
||||
header.height = height;
|
||||
header.index = next_index++;
|
||||
header.account = e.account;
|
||||
|
||||
data.flags = e.flags;
|
||||
data.counterparties = e.counterparties;
|
||||
data.items = e.items;
|
||||
data.balance = e.balance;
|
||||
@ -8370,15 +8346,13 @@ void BlockchainLMDB::add_cc_events(uint64_t height, const std::vector<cc::game_e
|
||||
data.cmd = e.cmd;
|
||||
data.event = e.event;
|
||||
|
||||
MDB_val k, v[2];
|
||||
k.mv_data = (void*)&height;
|
||||
k.mv_size = sizeof(height);
|
||||
if (!write_event_data(v[0], data))
|
||||
if (!write_event_data(v, data))
|
||||
throw0(DB_ERROR("Failed to serialize event data"));
|
||||
v[1].mv_data = NULL;
|
||||
v[1].mv_size = em_account_flag_event;
|
||||
int result = mdb_cursor_put(m_cur_cc_events, &k, v, 0);
|
||||
if (v[0].mv_data) free(v[0].mv_data);
|
||||
|
||||
k.mv_data = (void*)&header;
|
||||
k.mv_size = sizeof(header);
|
||||
result = mdb_cursor_put(m_cur_cc_events, &k, &v, MDB_APPEND);
|
||||
if (v.mv_data) free(v.mv_data);
|
||||
if (result)
|
||||
throw0(DB_ERROR(lmdb_error("Failed to add event data to db transaction: ", result).c_str()));
|
||||
}
|
||||
@ -8392,20 +8366,25 @@ void BlockchainLMDB::remove_cc_events(uint64_t height)
|
||||
|
||||
CURSOR(cc_events)
|
||||
|
||||
MDB_val k = {sizeof(height), (void*)&height}, v;
|
||||
int result = mdb_cursor_get(m_cur_cc_events, &k, &v, MDB_SET);
|
||||
if (result == MDB_NOTFOUND)
|
||||
return;
|
||||
if (result)
|
||||
throw0(DB_ERROR(lmdb_error("Error getting events data from db: ", result).c_str()));
|
||||
mdb_size_t count;
|
||||
result = mdb_cursor_count(m_cur_cc_events, &count);
|
||||
if (result)
|
||||
throw0(DB_ERROR(lmdb_error("Error counting events data from db: ", result).c_str()));
|
||||
MDEBUG("deleting " << count << " events at height " << height);
|
||||
result = mdb_cursor_del(m_cur_cc_events, MDB_NODUPDATA);
|
||||
if (result)
|
||||
mdb_size_t count = 0;
|
||||
MDB_val k, v;
|
||||
int result = mdb_cursor_get(m_cur_cc_events, &k, &v, MDB_LAST);
|
||||
while (result == 0)
|
||||
{
|
||||
const mdb_events_data_header_t *header = (const mdb_events_data_header_t*)k.mv_data;
|
||||
if (header->height != height)
|
||||
{
|
||||
if (header->height > height)
|
||||
MWARNING("Unexpected event height on deletion: deleting " << height << ", found " << header->height);
|
||||
break;
|
||||
}
|
||||
mdb_cursor_del(m_cur_cc_events, 0);
|
||||
++count;
|
||||
result = mdb_cursor_get(m_cur_cc_events, &k, &v, MDB_PREV);
|
||||
}
|
||||
if (result && result != MDB_NOTFOUND)
|
||||
throw0(DB_ERROR(lmdb_error("Error deleting events data from db: ", result).c_str()));
|
||||
MDEBUG("deleted " << count << " events at height " << height);
|
||||
}
|
||||
|
||||
bool BlockchainLMDB::get_cc_events(uint64_t height, uint32_t account, uint32_t flag, std::vector<cc::game_event_t> &events) const
|
||||
@ -8430,66 +8409,45 @@ bool BlockchainLMDB::get_cc_events(uint64_t height, uint32_t account, uint32_t f
|
||||
TXN_PREFIX_RDONLY();
|
||||
RCURSOR(cc_events)
|
||||
|
||||
const event_match_t match = flag ? em_account_flag : em_account;
|
||||
MDB_cursor_op op = (account || flag) ? MDB_GET_BOTH : MDB_SET;
|
||||
|
||||
mdb_events_data_t ed(account, flag);
|
||||
MDB_val k = {sizeof(uint64_t), (void*)&height};
|
||||
MDB_val v[2] = {{sizeof(ed), (void*)&ed}, {match, NULL}};
|
||||
int result = mdb_cursor_get(m_cur_cc_events, &k, v, op);
|
||||
mdb_events_data_header_t header;
|
||||
header.height = height;
|
||||
header.index = 0;
|
||||
header.account = 0;
|
||||
MDB_val k, v;
|
||||
k.mv_data = (void*)&header;
|
||||
k.mv_size = sizeof(header);
|
||||
int result = mdb_cursor_get(m_cur_cc_events, &k, &v, MDB_SET_RANGE);
|
||||
if (result == MDB_NOTFOUND)
|
||||
{
|
||||
TXN_POSTFIX_RDONLY();
|
||||
return true;
|
||||
}
|
||||
if (result)
|
||||
{
|
||||
MERROR("Events data not found for height " << height << ", account " << account << ", flag " << flag << ": " << mdb_strerror(result));
|
||||
return false;
|
||||
}
|
||||
|
||||
// get the first record since we can end up in the middle :/
|
||||
while (1)
|
||||
{
|
||||
MDB_val k2, v2;
|
||||
result = mdb_cursor_get(m_cur_cc_events, &k2, &v2, MDB_PREV_DUP);
|
||||
if (result == MDB_NOTFOUND)
|
||||
break;
|
||||
if (result)
|
||||
throw0(DB_ERROR(lmdb_error("Error getting event: ", result).c_str()));
|
||||
const mdb_events_data_header_t *edh = (const mdb_events_data_header_t*)v2.mv_data;
|
||||
const bool match = (account == 0 || account == edh->account) && (flag == 0 || flag == edh->flag);
|
||||
if (!match)
|
||||
{
|
||||
result = mdb_cursor_get(m_cur_cc_events, &k2, &v2, MDB_NEXT_DUP);
|
||||
if (result)
|
||||
throw0(DB_ERROR(lmdb_error("Error getting event: ", result).c_str()));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// walk till the first non matching record
|
||||
while (1)
|
||||
{
|
||||
MDB_val k2, v2;
|
||||
result = mdb_cursor_get(m_cur_cc_events, &k2, &v2, MDB_GET_CURRENT);
|
||||
result = mdb_cursor_get(m_cur_cc_events, &k, &v, MDB_GET_CURRENT);
|
||||
if (result)
|
||||
throw0(DB_ERROR(lmdb_error("Error getting event: ", result).c_str()));
|
||||
const uint64_t &height = *(const uint64_t*)k2.mv_data;
|
||||
const mdb_events_data_header_t *edh = (const mdb_events_data_header_t*)v2.mv_data;
|
||||
const bool match = (account == 0 || account == edh->account) && (flag == 0 || flag == edh->flag);
|
||||
if (!match)
|
||||
const mdb_events_data_header_t *edh = (const mdb_events_data_header_t*)k.mv_data;
|
||||
if (edh->height > height)
|
||||
break;
|
||||
mdb_events_data_t ed;
|
||||
if (!read_event_data(v2, ed))
|
||||
throw0(DB_ERROR("Failed to deserialize event data"));
|
||||
std::vector<uint32_t> flags;
|
||||
if (ed.flag != 0)
|
||||
if (account == 0 || account == edh->account)
|
||||
{
|
||||
flags.reserve(1 + ed.extra_flags.size());
|
||||
flags.push_back(ed.flag);
|
||||
for (uint32_t flag: ed.extra_flags)
|
||||
flags.push_back(flag);
|
||||
mdb_events_data_t ed;
|
||||
if (!read_event_data(v, ed))
|
||||
throw0(DB_ERROR("Failed to deserialize event data"));
|
||||
if (flag == 0 || std::find(ed.flags.begin(), ed.flags.end(), flag) != ed.flags.end())
|
||||
{
|
||||
events.push_back({height, ed.cmd, edh->account, std::move(ed.counterparties), std::move(ed.flags), std::move(ed.items), ed.balance, ed.nonce, ed.tx_fee, std::move(ed.event)});
|
||||
}
|
||||
}
|
||||
events.push_back({height, ed.cmd, ed.account, std::move(ed.counterparties), std::move(flags), std::move(ed.items), ed.balance, ed.nonce, ed.tx_fee, std::move(ed.event)});
|
||||
result = mdb_cursor_get(m_cur_cc_events, &k2, &v2, MDB_NEXT_DUP);
|
||||
result = mdb_cursor_get(m_cur_cc_events, &k, &v, MDB_NEXT);
|
||||
if (result == MDB_NOTFOUND)
|
||||
break;
|
||||
if (result)
|
||||
@ -8501,7 +8459,7 @@ bool BlockchainLMDB::get_cc_events(uint64_t height, uint32_t account, uint32_t f
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BlockchainLMDB::get_cc_game_events(uint64_t min_height, uint64_t max_height, uint32_t account, uint32_t flag, uint32_t item, uint8_t cmd, bool (*filter)(uint8_t, uint32_t, uint32_t, const std::vector<uint32_t>&, const std::vector<uint32_t>&, const std::vector<std::pair<uint32_t, uint32_t>>&, const std::string&, const std::string& (*get_event)()), std::vector<cc::game_event_t> &events) const
|
||||
bool BlockchainLMDB::get_cc_game_events(uint64_t min_height, uint64_t max_height, uint32_t account, uint32_t flag, uint32_t item, uint8_t cmd, bool (*filter)(uint8_t, uint32_t, const std::vector<uint32_t>&, const std::vector<uint32_t>&, const std::vector<std::pair<uint32_t, uint32_t>>&, const std::string&, const std::string& (*get_event)()), std::vector<cc::game_event_t> &events) const
|
||||
{
|
||||
LOG_PRINT_L3("BlockchainLMDB::" << __func__);
|
||||
check_open();
|
||||
@ -8511,14 +8469,17 @@ bool BlockchainLMDB::get_cc_game_events(uint64_t min_height, uint64_t max_height
|
||||
TXN_PREFIX_RDONLY();
|
||||
RCURSOR(cc_events)
|
||||
|
||||
const event_match_t match = em_account;
|
||||
|
||||
mdb_events_data_t ed(account, flag);
|
||||
MDB_val k = {sizeof(uint64_t), (void*)&min_height};
|
||||
MDB_val v[2] = {{sizeof(ed), (void*)&ed}, {match, NULL}};
|
||||
int result = mdb_cursor_get(m_cur_cc_events, &k, v, MDB_SET_RANGE);
|
||||
mdb_events_data_header_t header;
|
||||
header.height = min_height;
|
||||
header.index = 0;
|
||||
header.account = 0;
|
||||
MDB_val k, v;
|
||||
k.mv_data = (void*)&header;
|
||||
k.mv_size = sizeof(header);
|
||||
int result = mdb_cursor_get(m_cur_cc_events, &k, &v, MDB_SET_RANGE);
|
||||
if (result == MDB_NOTFOUND)
|
||||
{
|
||||
TXN_POSTFIX_RDONLY();
|
||||
return true;
|
||||
}
|
||||
if (result)
|
||||
@ -8527,62 +8488,38 @@ bool BlockchainLMDB::get_cc_game_events(uint64_t min_height, uint64_t max_height
|
||||
return false;
|
||||
}
|
||||
|
||||
// get the first record since we can end up in the middle :/
|
||||
while (1)
|
||||
{
|
||||
MDB_val k2, v2;
|
||||
result = mdb_cursor_get(m_cur_cc_events, &k2, &v2, MDB_PREV_DUP);
|
||||
if (result == MDB_NOTFOUND)
|
||||
break;
|
||||
if (result)
|
||||
throw0(DB_ERROR(lmdb_error("Error getting event: ", result).c_str()));
|
||||
const mdb_events_data_header_t *edh = (const mdb_events_data_header_t*)v2.mv_data;
|
||||
const bool match = (account == 0 || account == edh->account) && (flag == 0 || flag == edh->flag);
|
||||
if (!match)
|
||||
{
|
||||
result = mdb_cursor_get(m_cur_cc_events, &k2, &v2, MDB_NEXT_DUP);
|
||||
if (result)
|
||||
throw0(DB_ERROR(lmdb_error("Error getting event: ", result).c_str()));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// walk till the first non matching record
|
||||
while (1)
|
||||
{
|
||||
MDB_val k2, v2;
|
||||
result = mdb_cursor_get(m_cur_cc_events, &k2, &v2, MDB_GET_CURRENT);
|
||||
result = mdb_cursor_get(m_cur_cc_events, &k, &v, MDB_GET_CURRENT);
|
||||
if (result)
|
||||
throw0(DB_ERROR(lmdb_error("Error getting event: ", result).c_str()));
|
||||
const uint64_t &height = *(const uint64_t*)k2.mv_data;
|
||||
if (height > max_height)
|
||||
const mdb_events_data_header_t *edh = (const mdb_events_data_header_t*)k.mv_data;
|
||||
if (edh->height > max_height)
|
||||
break;
|
||||
mdb_events_data_t ed;
|
||||
ed.skip_event = true;
|
||||
if (!read_event_data(v2, ed))
|
||||
throw0(DB_ERROR("Failed to deserialize event data"));
|
||||
// optional matches
|
||||
if (account == 0 || ed.account == account)
|
||||
if (flag == 0 || ed.flag == flag)
|
||||
if (cmd == 0 || ed.cmd == cmd)
|
||||
if (account == 0 || account == edh->account)
|
||||
{
|
||||
mdb_events_data_t ed;
|
||||
ed.skip_event = true;
|
||||
if (!read_event_data(v, ed))
|
||||
throw0(DB_ERROR("Failed to deserialize event data"));
|
||||
if (flag == 0 || std::find(ed.flags.begin(), ed.flags.end(), flag) != ed.flags.end())
|
||||
{
|
||||
if (cmd == 0 || cmd == ed.cmd)
|
||||
{
|
||||
if (item == 0 || std::find_if(ed.items.begin(), ed.items.end(), [item](const std::pair<uint32_t, uint32_t> &e){ return e.first == item; }) != ed.items.end())
|
||||
{
|
||||
event_to_decode = &ed.event;
|
||||
if (!filter || (*filter)(ed.cmd, ed.account, ed.flag, ed.extra_flags, ed.counterparties, ed.items, ed.event, &event_decoder))
|
||||
if (!filter || (*filter)(ed.cmd, edh->account, ed.flags, ed.counterparties, ed.items, ed.event, &event_decoder))
|
||||
{
|
||||
std::vector<uint32_t> flags;
|
||||
if (ed.flag)
|
||||
{
|
||||
flags.reserve(1 + ed.extra_flags.size());
|
||||
flags.push_back(ed.flag);
|
||||
for (uint32_t flag: ed.extra_flags)
|
||||
flags.push_back(flag);
|
||||
}
|
||||
event_decoder();
|
||||
events.push_back({height, ed.cmd, ed.account, std::move(ed.counterparties), std::move(flags), std::move(ed.items), ed.balance, ed.nonce, ed.tx_fee, std::move(decoded_event)});
|
||||
events.push_back({edh->height, ed.cmd, edh->account, std::move(ed.counterparties), std::move(ed.flags), std::move(ed.items), ed.balance, ed.nonce, ed.tx_fee, std::move(decoded_event)});
|
||||
}
|
||||
}
|
||||
result = mdb_cursor_get(m_cur_cc_events, &k2, &v2, MDB_NEXT);
|
||||
}
|
||||
}
|
||||
}
|
||||
result = mdb_cursor_get(m_cur_cc_events, &k, &v, MDB_NEXT);
|
||||
if (result == MDB_NOTFOUND)
|
||||
break;
|
||||
if (result)
|
||||
|
@ -605,7 +605,7 @@ private:
|
||||
void add_cc_events(uint64_t height, const std::vector<cc::game_event_t> &events);
|
||||
void remove_cc_events(uint64_t height);
|
||||
bool get_cc_events(uint64_t height, uint32_t account, uint32_t flag, std::vector<cc::game_event_t> &events) const;
|
||||
bool get_cc_game_events(uint64_t min_height, uint64_t max_height, uint32_t account, uint32_t flag, uint32_t item, uint8_t cmd, bool (*filter)(uint8_t, uint32_t, uint32_t, const std::vector<uint32_t>&, const std::vector<uint32_t>&, const std::vector<std::pair<uint32_t, uint32_t>>&, const std::string&, const std::string& (*get_event)()), std::vector<cc::game_event_t> &events) const;
|
||||
bool get_cc_game_events(uint64_t min_height, uint64_t max_height, uint32_t account, uint32_t flag, uint32_t item, uint8_t cmd, bool (*filter)(uint8_t, uint32_t, const std::vector<uint32_t>&, const std::vector<uint32_t>&, const std::vector<std::pair<uint32_t, uint32_t>>&, const std::string&, const std::string& (*get_event)()), std::vector<cc::game_event_t> &events) const;
|
||||
|
||||
void add_cc_name(const std::string &name, uint32_t type, uint32_t id);
|
||||
void remove_cc_name(const std::string &name);
|
||||
|
@ -261,7 +261,7 @@ public:
|
||||
virtual void add_cc_events(uint64_t height, const std::vector<cc::game_event_t> &events) {}
|
||||
virtual void remove_cc_events(uint64_t height) {}
|
||||
virtual bool get_cc_events(uint64_t height, uint32_t account, uint32_t flag, std::vector<cc::game_event_t> &events) const { return false; }
|
||||
virtual bool get_cc_game_events(uint64_t min_height, uint64_t max_height, uint32_t account, uint32_t flag, uint32_t item, uint8_t cmd, bool (*filter)(uint8_t, uint32_t, uint32_t, const std::vector<uint32_t>&, const std::vector<uint32_t>&, const std::vector<std::pair<uint32_t, uint32_t>>&, const std::string&, const std::string& (*get_event)()), std::vector<cc::game_event_t> &events) const { return false; }
|
||||
virtual bool get_cc_game_events(uint64_t min_height, uint64_t max_height, uint32_t account, uint32_t flag, uint32_t item, uint8_t cmd, bool (*filter)(uint8_t, uint32_t, const std::vector<uint32_t>&, const std::vector<uint32_t>&, const std::vector<std::pair<uint32_t, uint32_t>>&, const std::string&, const std::string& (*get_event)()), std::vector<cc::game_event_t> &events) const { return false; }
|
||||
|
||||
virtual void add_cc_name(const std::string &name, uint32_t type, uint32_t id) {}
|
||||
virtual void remove_cc_name(const std::string &name) {}
|
||||
|
@ -197,7 +197,7 @@ namespace
|
||||
return bits;
|
||||
}
|
||||
|
||||
bool filter_news(uint8_t cmd, uint32_t account, uint32_t flag, const std::vector<uint32_t> &extra_flags, const std::vector<uint32_t> &counterparties, const std::vector<std::pair<uint32_t, uint32_t>> &items, const std::string &compressed_event, const std::string& (*get_event)())
|
||||
bool filter_news(uint8_t cmd, uint32_t account, const std::vector<uint32_t> &flags, const std::vector<uint32_t> &counterparties, const std::vector<std::pair<uint32_t, uint32_t>> &items, const std::string &compressed_event, const std::string& (*get_event)())
|
||||
{
|
||||
static const std::vector<uint8_t> ignore {
|
||||
get_cc_tag<uint8_t>(cryptonote::cc_command_allow_styling_t()),
|
||||
@ -4685,7 +4685,7 @@ namespace cryptonote
|
||||
return true;
|
||||
}
|
||||
|
||||
bool (*filter)(uint8_t, uint32_t, uint32_t, const std::vector<uint32_t>&, const std::vector<uint32_t>&, const std::vector<std::pair<uint32_t, uint32_t>>&, const std::string&, const std::string& (*get_event)()) = NULL;
|
||||
bool (*filter)(uint8_t, uint32_t, const std::vector<uint32_t>&, const std::vector<uint32_t>&, const std::vector<std::pair<uint32_t, uint32_t>>&, const std::string&, const std::string& (*get_event)()) = NULL;
|
||||
if (req.filter_news)
|
||||
filter = &filter_news;
|
||||
std::vector<cc::game_event_t> events;
|
||||
@ -4729,7 +4729,7 @@ namespace cryptonote
|
||||
return true;
|
||||
}
|
||||
|
||||
bool (*filter)(uint8_t, uint32_t, uint32_t, const std::vector<uint32_t>&, const std::vector<uint32_t>&, const std::vector<std::pair<uint32_t, uint32_t>>&, const std::string&, const std::string& (*get_event)()) = NULL;
|
||||
bool (*filter)(uint8_t, uint32_t, const std::vector<uint32_t>&, const std::vector<uint32_t>&, const std::vector<std::pair<uint32_t, uint32_t>>&, const std::string&, const std::string& (*get_event)()) = NULL;
|
||||
if (req.filter_news)
|
||||
filter = &filter_news;
|
||||
cc::game_events_t events;
|
||||
|
@ -3237,28 +3237,19 @@ TEST(cc, events)
|
||||
ASSERT_TRUE(db->get_cc_events(200, 0, 0, events));
|
||||
ASSERT_EQ(events.size(), 10);
|
||||
|
||||
// delete 200
|
||||
db->remove_cc_events(200);
|
||||
// delete 240
|
||||
db->remove_cc_events(240);
|
||||
ASSERT_TRUE(db->get_cc_events(240, 0, 0, events));
|
||||
ASSERT_EQ(events.size(), 2);
|
||||
ASSERT_TRUE(db->get_cc_events(200, 0, 0, events));
|
||||
ASSERT_EQ(events.size(), 0);
|
||||
ASSERT_TRUE(db->get_cc_events(200, 0, 0, events));
|
||||
ASSERT_EQ(events.size(), 10);
|
||||
ASSERT_TRUE(db->get_cc_events(127, 0, 0, events));
|
||||
ASSERT_EQ(events.size(), 2);
|
||||
|
||||
// we can add 200 back
|
||||
db->add_cc_events(200, {
|
||||
{200, cmd, 2, {}, {}, {}, 0, 10, 0, "account 2"},
|
||||
{200, cmd, 4, {}, {1}, {}, 0, 11, 0, "account 4, building 1, event 0"},
|
||||
{200, cmd, 5, {}, {2}, {}, 0, 12, 0, "account 5, building 2, event 0"},
|
||||
{200, cmd, 4, {}, {1}, {}, 0, 13, 0, "account 4, building 1, event 1"},
|
||||
{200, cmd, 4, {}, {1}, {}, 0, 14, 0, "account 4, building 1, event 2"},
|
||||
{200, cmd, 5, {}, {3}, {}, 0, 15, 0, "account 5, building 3, event 0"},
|
||||
{200, cmd, 6, {}, {4}, {}, 0, 16, 0, "account 6, building 4, event 0"},
|
||||
{200, cmd, 4, {}, {5}, {}, 0, 17, 0, "account 4, building 5, event 0"},
|
||||
{200, cmd, 4, {}, {}, {}, 0, 18, 0, "account 4"},
|
||||
{200, cmd, 1, {}, {}, {}, 0, 19, 0, "account 1"}
|
||||
});
|
||||
// we can add 240 back
|
||||
db->add_cc_events(240, {{240, cmd, 4, {}, {1}, {}, 0, 90, 0, "building 1"}, {240, cmd, 4, {}, {}, {}, 0, 91, 0, "no building"}});
|
||||
ASSERT_TRUE(db->get_cc_events(240, 0, 0, events));
|
||||
ASSERT_EQ(events.size(), 2);
|
||||
ASSERT_TRUE(db->get_cc_events(200, 0, 0, events));
|
||||
ASSERT_EQ(events.size(), 10);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user