Browse Source

improve cmd:match (multimatch); fix missing 'delete's

master
Erik Zscheile 2 years ago
parent
commit
3a792cca63
2 changed files with 64 additions and 11 deletions
  1. +1
    -1
      CMakeLists.txt
  2. +63
    -10
      main.cxx

+ 1
- 1
CMakeLists.txt View File

@@ -1,7 +1,7 @@
cmake_minimum_required(VERSION 3.0)
project(zstreedb2 CXX)
set(INSTALL_BIN_DIR bin CACHE PATH "Installation directory for binaries")
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

find_package(Threads REQUIRED)


+ 63
- 10
main.cxx View File

@@ -4,8 +4,11 @@
**/

#include <stdio.h>
#include <stdlib.h>
#include <algorithm>
#include <thread>
#include <unordered_map>
#include <utility>
#include <rocksdb/db.h>

#include "args.hpp"
@@ -20,6 +23,41 @@ static void cleanup() {
delete db;
}

static void filter_match(vector<string> &selv, string &&key, const string &value) {
vector<rocksdb::Status> sts;
vector<string> values;

// 1. retrieve values
{
string sufx = "." + move(key);
vector<string> keys;
vector<rocksdb::Slice> key_slices;
keys.reserve(selv.size());
key_slices.reserve(selv.size());
for(const auto &i : selv)
key_slices.emplace_back(keys.emplace_back(i + sufx));
string().swap(sufx);
sts = db->MultiGet({}, key_slices, &values);
}

// 2. find matches
{
auto it_s = sts.begin();
auto it_v = values.begin();
auto it_sel = selv.begin();

while(it_sel != selv.end()) {
if(!it_s->ok() || *it_v != value) {
it_s = sts.erase(it_s);
it_v = values.erase(it_v);
it_sel = selv.erase(it_sel);
continue;
}
++it_s; ++it_v; ++it_sel;
}
}
}

#define AC(C) case ztdb::args_t::C:

int main(const int argc, char *argv[]) {
@@ -51,7 +89,7 @@ int main(const int argc, char *argv[]) {
if(!st.ok())
errmsg(2, "db open failed: " + st.ToString());
}
atexit(cleanup);

switch(args.cmd) {
AC(GET)
@@ -160,16 +198,31 @@ int main(const int argc, char *argv[]) {
AC(MATCH)
{
if(args.cmd_args.empty())
errmsg(1, "invalid invocation to 'zstreedb2 m KEY VALUE'");
errmsg(1, "invalid invocation to 'zstreedb2 m (KEY VALUE)+'");

vector<string> selv;

{
const string key = "." + args.sel_node;
const auto it = db->NewIterator({});
for(it->SeekToFirst(); it->Valid(); it->Next())
if(it->key().ends_with(key) && it->value() == args.cmd_args.front()) {
auto slc = it->key();
slc.remove_suffix(key.size());
selv.emplace_back(slc.data(), slc.size());
}
delete it;
}

const string key = "." + args.sel_node;
const auto it = db->NewIterator({});
for(it->SeekToFirst(); it->Valid(); it->Next())
if(it->key().ends_with(key) && it->value() == args.cmd_args.front()) {
auto slc = it->key();
slc.remove_suffix(key.size());
printf("%.*s\n", static_cast<int>(slc.size()), slc.data());
}
args.cmd_args.erase(args.cmd_args.begin());
auto it = args.cmd_args.begin();
while(it != args.cmd_args.end() && (it + 1) != args.cmd_args.end()) {
filter_match(selv, std::move(*it), *(it + 1));
it += 2;
}

for(const auto &i : selv)
printf("%.*s\n", static_cast<int>(i.size()), i.data());
}
break;



Loading…
Cancel
Save