diff options
6 files changed, 202 insertions, 1 deletions
diff --git a/searchlib/src/tests/queryeval/blueprint/blueprint_test.cpp b/searchlib/src/tests/queryeval/blueprint/blueprint_test.cpp index e5ee83507ae..0d34b41d5c7 100644 --- a/searchlib/src/tests/queryeval/blueprint/blueprint_test.cpp +++ b/searchlib/src/tests/queryeval/blueprint/blueprint_test.cpp @@ -5,6 +5,7 @@ #include <vespa/searchlib/queryeval/intermediate_blueprints.h> #include <vespa/vespalib/objects/objectdumper.h> #include <vespa/vespalib/objects/visit.h> +#include <vespa/vespalib/data/slime/slime.h> #include <algorithm> #include <vespa/log/log.h> @@ -178,6 +179,7 @@ public: void testSearchCreation(); void testBlueprintMakeNew(); void requireThatAsStringWorks(); + void requireThatAsSlimeWorks(); void requireThatVisitMembersWorks(); void requireThatDocIdLimitInjectionWorks(); int Main() override; @@ -698,6 +700,59 @@ getExpectedBlueprint() "}\n"; } +vespalib::string +getExpectedSlimeBlueprint() { + return "{" + " '(anonymous namespace)::MyOr': {" + " isTermLike: true," + " fields: {" + " '[type]': 'FieldList'," + " '[0]': {" + " '[type]': 'Field'," + " fieldId: 5," + " handle: 7," + " isFilter: false" + " }" + " }," + " estimate: {" + " '[type]': 'HitEstimate'," + " empty: false," + " estHits: 9," + " tree_size: 2," + " allow_termwise_eval: 0" + " }," + " sourceId: 4294967295," + " docid_limit: 0," + " children: {" + " '[type]': 'std::vector'," + " '[0]': {" + " isTermLike: true," + " fields: {" + " '[type]': 'FieldList'," + " '[0]': {" + " '[type]': 'Field'," + " fieldId: 5," + " handle: 7," + " isFilter: false" + " }" + " }," + " '[type]': '(anonymous namespace)::MyTerm'," + " estimate: {" + " '[type]': 'HitEstimate'," + " empty: false," + " estHits: 9," + " tree_size: 1," + " allow_termwise_eval: 1" + " }," + " sourceId: 4294967295," + " docid_limit: 0" + " }" + " }" + " }" + "}"; +} + + struct BlueprintFixture { MyOr _blueprint; @@ -714,6 +769,18 @@ Test::requireThatAsStringWorks() } void +Test::requireThatAsSlimeWorks() +{ + BlueprintFixture f; + vespalib::Slime slime; + f._blueprint.asSlime(vespalib::slime::SlimeInserter(slime)); + auto s = slime.toString(); + vespalib::Slime expectedSlime; + vespalib::slime::JsonFormat::decode(getExpectedSlimeBlueprint(), expectedSlime); + EXPECT_EQUAL(expectedSlime, slime); +} + +void Test::requireThatVisitMembersWorks() { BlueprintFixture f; @@ -749,6 +816,7 @@ Test::Main() testSearchCreation(); testBlueprintMakeNew(); requireThatAsStringWorks(); + requireThatAsSlimeWorks(); requireThatVisitMembersWorks(); requireThatDocIdLimitInjectionWorks(); TEST_DONE(); diff --git a/searchlib/src/vespa/searchlib/queryeval/blueprint.cpp b/searchlib/src/vespa/searchlib/queryeval/blueprint.cpp index c99e07cd355..3f3b4a2300e 100644 --- a/searchlib/src/vespa/searchlib/queryeval/blueprint.cpp +++ b/searchlib/src/vespa/searchlib/queryeval/blueprint.cpp @@ -6,7 +6,9 @@ #include "equiv_blueprint.h" #include <vespa/vespalib/objects/visit.hpp> #include <vespa/vespalib/objects/objectdumper.h> +#include <vespa/vespalib/objects/object2slime.h> #include <vespa/vespalib/util/classname.h> +#include <vespa/vespalib/data/slime/inserter.h> #include <map> #include <vespa/log/log.h> @@ -117,6 +119,15 @@ Blueprint::asString() const return dumper.toString(); } +vespalib::slime::Cursor & +Blueprint::asSlime(const vespalib::slime::Inserter & inserter) const +{ + vespalib::slime::Cursor & cursor = inserter.insertObject(); + vespalib::Object2Slime dumper(cursor); + visit(dumper, "", this); + return cursor; +} + vespalib::string Blueprint::getClassName() const { diff --git a/searchlib/src/vespa/searchlib/queryeval/blueprint.h b/searchlib/src/vespa/searchlib/queryeval/blueprint.h index 165f592867a..4b60e7d0d8b 100644 --- a/searchlib/src/vespa/searchlib/queryeval/blueprint.h +++ b/searchlib/src/vespa/searchlib/queryeval/blueprint.h @@ -9,7 +9,11 @@ #include <vespa/searchlib/fef/termfieldmatchdata.h> #include <vespa/searchlib/fef/termfieldmatchdataarray.h> -namespace vespalib { class ObjectVisitor; }; +namespace vespalib { class ObjectVisitor; } +namespace vespalib::slime { + class Cursor; + class Inserter; +} namespace search::queryeval { @@ -173,6 +177,7 @@ public: // for debug dumping vespalib::string asString() const; + vespalib::slime::Cursor & asSlime(const vespalib::slime::Inserter & cursor) const; virtual vespalib::string getClassName() const; virtual void visitMembers(vespalib::ObjectVisitor &visitor) const; virtual bool isEquiv() const { return false; } diff --git a/staging_vespalib/src/vespa/vespalib/objects/CMakeLists.txt b/staging_vespalib/src/vespa/vespalib/objects/CMakeLists.txt index 12970a7d39b..f3afda94fe6 100644 --- a/staging_vespalib/src/vespa/vespalib/objects/CMakeLists.txt +++ b/staging_vespalib/src/vespa/vespalib/objects/CMakeLists.txt @@ -5,6 +5,7 @@ vespa_add_library(staging_vespalib_vespalib_objects OBJECT namedobject.cpp objectvisitor.cpp objectdumper.cpp + object2slime.cpp visit.cpp objectpredicate.cpp objectoperation.cpp diff --git a/staging_vespalib/src/vespa/vespalib/objects/object2slime.cpp b/staging_vespalib/src/vespa/vespalib/objects/object2slime.cpp new file mode 100644 index 00000000000..f06060529c3 --- /dev/null +++ b/staging_vespalib/src/vespa/vespalib/objects/object2slime.cpp @@ -0,0 +1,75 @@ +// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +#include "object2slime.h" +#include <vespa/vespalib/util/stringfmt.h> +#include <vespa/vespalib/data/slime/cursor.h> + + +namespace vespalib { + +Object2Slime::Object2Slime(slime::Cursor & cursor) + : _cursor(&cursor), + _stack() +{ +} + +Object2Slime::~Object2Slime() = default; + +//----------------------------------------------------------------------------- + +void +Object2Slime::openStruct(const vespalib::string &name, const vespalib::string &type) +{ + _stack.push_back(_cursor); + + if (name.empty()) { + _cursor = & _cursor->setObject(type); + } else { + _cursor = & _cursor->setObject(name); + _cursor->setString("[type]", type); + } +} + +void +Object2Slime::closeStruct() +{ + _cursor = _stack.back(); + _stack.pop_back(); +} + +void +Object2Slime::visitBool(const vespalib::string &name, bool value) +{ + _cursor->setBool(name, value); +} + +void +Object2Slime::visitInt(const vespalib::string &name, int64_t value) +{ + _cursor->setLong(name, value); +} + +void +Object2Slime::visitFloat(const vespalib::string &name, double value) +{ + _cursor->setDouble(name, value); +} + +void +Object2Slime::visitString(const vespalib::string &name, const vespalib::string &value) +{ + _cursor->setString(name, value); +} + +void +Object2Slime::visitNull(const vespalib::string &name) +{ + _cursor->setNix(name); +} + +void +Object2Slime::visitNotImplemented() +{ + _cursor->setNix("not_implemented"); +} + +} // namespace vespalib diff --git a/staging_vespalib/src/vespa/vespalib/objects/object2slime.h b/staging_vespalib/src/vespa/vespalib/objects/object2slime.h new file mode 100644 index 00000000000..9c147047a74 --- /dev/null +++ b/staging_vespalib/src/vespa/vespalib/objects/object2slime.h @@ -0,0 +1,41 @@ +// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +#pragma once + +#include "objectvisitor.h" +#include <vector> + +namespace vespalib { + +namespace slime { class Cursor; } + +/** + * This is a concrete object visitor that will build up a structured + * human-readable string representation of an object. + **/ +class Object2Slime : public ObjectVisitor +{ +private: + slime::Cursor * _cursor; + std::vector<slime::Cursor *> _stack; + +public: + /** + * Create an object dumper with the given indent size; default is + * 4 spaces per indent level. + * + * @param indent indent size in number of spaces + **/ + Object2Slime(slime::Cursor & cursor); + ~Object2Slime(); + + void openStruct(const vespalib::string &name, const vespalib::string &type) override; + void closeStruct() override; + void visitBool(const vespalib::string &name, bool value) override; + void visitInt(const vespalib::string &name, int64_t value) override; + void visitFloat(const vespalib::string &name, double value) override; + void visitString(const vespalib::string &name, const vespalib::string &value) override; + void visitNull(const vespalib::string &name) override; + void visitNotImplemented() override; +}; + +} // namespace vespalib |