diff --git a/source/libs/index/inc/index_fst.h b/source/libs/index/inc/index_fst.h index a1d4962e8be815847ca1a25689588dcb157c318f..20037f829adae78ea866429650c06da6ec79202c 100644 --- a/source/libs/index/inc/index_fst.h +++ b/source/libs/index/inc/index_fst.h @@ -30,6 +30,7 @@ extern "C" { typedef struct Fst Fst; typedef struct FstNode FstNode; +typedef struct StreamWithState StreamWithState; typedef enum { Included, Excluded, Unbounded} FstBound; @@ -283,6 +284,9 @@ Output fstEmptyFinalOutput(Fst *fst, bool *null); FstStreamBuilder *fstSearch(Fst *fst, AutomationCtx *ctx); FstStreamWithStateBuilder *fstSearchWithState(Fst *fst, AutomationCtx *ctx); +// into stream to expand later +StreamWithState* streamBuilderIntoStream(FstStreamBuilder *sb); + bool fstVerify(Fst *fst); diff --git a/source/libs/index/src/index_fst.c b/source/libs/index/src/index_fst.c index 37bdcb0ecfa15a0a2726de07d4a69470b44f4b0e..54058489c2f5c74e427133e42f70994bbac21a26 100644 --- a/source/libs/index/src/index_fst.c +++ b/source/libs/index/src/index_fst.c @@ -1094,6 +1094,10 @@ bool fstGet(Fst *fst, FstSlice *b, Output *out) { FstStreamBuilder *fstSearch(Fst *fst, AutomationCtx *ctx) { return fstStreamBuilderCreate(fst, ctx); } +StreamWithState* streamBuilderIntoStream(FstStreamBuilder *sb) { + if (sb == NULL) { return NULL; } + return streamWithStateCreate(sb->fst, sb->aut, sb->min, sb->max); +} FstStreamWithStateBuilder *fstSearchWithState(Fst *fst, AutomationCtx *ctx) { return fstStreamBuilderCreate(fst, ctx); } diff --git a/source/libs/index/test/indexTests.cpp b/source/libs/index/test/indexTests.cpp index 0cfb0fedc37706bfddebd7c025690baf380be014..f582536817ad8137ac32ad650bff5dbdb6ee76a1 100644 --- a/source/libs/index/test/indexTests.cpp +++ b/source/libs/index/test/indexTests.cpp @@ -59,9 +59,22 @@ class FstReadMemory { return ok; } // add later - bool Search(const std::string &key, std::vector &result) { + bool Search(AutomationCtx *ctx, std::vector &result) { + FstStreamBuilder *sb = fstSearch(_fst, ctx); + StreamWithState *st = streamBuilderIntoStream(sb); + StreamWithStateResult *rt = NULL; + + while ((rt = streamWithStateNextWith(st, NULL)) != NULL) { + result.push_back((uint64_t)(rt->out.out)); + } return true; } + bool SearchWithTimeCostUs(AutomationCtx *ctx, std::vector &result) { + int64_t s = taosGetTimestampUs(); + bool ok = this->Search(ctx, result); + int64_t e = taosGetTimestampUs(); + return ok; + } ~FstReadMemory() { fstCountingWriterDestroy(_w); @@ -186,11 +199,43 @@ void checkFstPerf() { printf("success to init fst read"); } Performance_fstReadRecords(m); - delete m; } +void checkFstPrefixSearch() { + FstWriter *fw = new FstWriter; + int64_t s = taosGetTimestampUs(); + int count = 2; + std::string key("ab"); + + for (int i = 0; i < count; i++) { + key[1] = key[1] + i; + fw->Put(key, i); + } + int64_t e = taosGetTimestampUs(); + + std::cout << "insert data count : " << count << "elapas time: " << e - s << std::endl; + delete fw; + FstReadMemory *m = new FstReadMemory(1024 * 64); + if (m->init() == false) { + std::cout << "init readMemory failed" << std::endl; + delete m; + return; + } + + // prefix search + std::vector result; + AutomationCtx *ctx = automCtxCreate((void *)"ab", AUTOMATION_PREFIX); + m->Search(ctx, result); + assert(result.size() == count); + for (int i = 0; i < result.size(); i++) { + assert(result[i] == i); // check result + } + + free(ctx); + delete m; +} void validateFst() { int val = 100; int count = 100; @@ -209,6 +254,8 @@ void validateFst() { FstReadMemory *m = new FstReadMemory(1024 * 64); if (m->init() == false) { std::cout << "init readMemory failed" << std::endl; + delete m; + return; } { @@ -230,10 +277,12 @@ void validateFst() { } } delete m; - } + + int main(int argc, char** argv) { checkFstPerf(); + //checkFstPrefixSearch(); return 1; }