summaryrefslogtreecommitdiffstats
path: root/vespalib
diff options
context:
space:
mode:
authorHenning Baldersheim <balder@yahoo-inc.com>2017-01-05 11:21:23 +0000
committerHenning Baldersheim <balder@yahoo-inc.com>2017-01-05 11:47:21 +0000
commit9a70779d68a5f9ab211d97b69a932a1043052ff6 (patch)
tree7af51fe4c78b54dfcda6480b364bf546c2a549e5 /vespalib
parent2215bcf9d1ba62af6906769f666665b226b1ba20 (diff)
Move trace slime serialization too vespa.
Diffstat (limited to 'vespalib')
-rw-r--r--vespalib/src/tests/trace/.gitignore2
-rw-r--r--vespalib/src/tests/trace/CMakeLists.txt8
-rw-r--r--vespalib/src/tests/trace/trace_serialization.cpp110
-rw-r--r--vespalib/src/vespa/vespalib/trace/CMakeLists.txt2
-rw-r--r--vespalib/src/vespa/vespalib/trace/slime_trace_deserializer.cpp68
-rw-r--r--vespalib/src/vespa/vespalib/trace/slime_trace_deserializer.h31
-rw-r--r--vespalib/src/vespa/vespalib/trace/slime_trace_serializer.cpp62
-rw-r--r--vespalib/src/vespa/vespalib/trace/slime_trace_serializer.h32
8 files changed, 314 insertions, 1 deletions
diff --git a/vespalib/src/tests/trace/.gitignore b/vespalib/src/tests/trace/.gitignore
index 51b4ee1aef8..420e2121bba 100644
--- a/vespalib/src/tests/trace/.gitignore
+++ b/vespalib/src/tests/trace/.gitignore
@@ -1,4 +1,4 @@
.depend
Makefile
-trace_test
vespalib_trace_test_app
+vespalib_trace_serialization_test_app
diff --git a/vespalib/src/tests/trace/CMakeLists.txt b/vespalib/src/tests/trace/CMakeLists.txt
index c87c3f1b3a8..f719222835e 100644
--- a/vespalib/src/tests/trace/CMakeLists.txt
+++ b/vespalib/src/tests/trace/CMakeLists.txt
@@ -6,3 +6,11 @@ vespa_add_executable(vespalib_trace_test_app TEST
vespalib
)
vespa_add_test(NAME vespalib_trace_test_app COMMAND vespalib_trace_test_app)
+
+vespa_add_executable(staging_vespalib_trace_serialization_test_app TEST
+ SOURCES
+ trace_serialization.cpp
+ DEPENDS
+ vespalib
+)
+vespa_add_test(NAME staging_vespalib_trace_serialization_test_app COMMAND staging_vespalib_trace_serialization_test_app)
diff --git a/vespalib/src/tests/trace/trace_serialization.cpp b/vespalib/src/tests/trace/trace_serialization.cpp
new file mode 100644
index 00000000000..a7896d43338
--- /dev/null
+++ b/vespalib/src/tests/trace/trace_serialization.cpp
@@ -0,0 +1,110 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+#include <vespa/fastos/fastos.h>
+#include <vespa/log/log.h>
+LOG_SETUP("trace_test");
+#include <vespa/vespalib/testkit/test_kit.h>
+#include <vespa/vespalib/trace/tracenode.h>
+#include <vespa/vespalib/trace/slime_trace_serializer.h>
+#include <vespa/vespalib/trace/slime_trace_deserializer.h>
+
+using namespace vespalib;
+using namespace vespalib::slime;
+
+TEST("that a single trace node is serialized") {
+ TraceNode node;
+ Slime slime;
+ SlimeTraceSerializer serializer(slime.setObject());
+ node.accept(serializer);
+ Inspector & i(slime.get());
+ EXPECT_TRUE(i["timestamp"].valid());
+ EXPECT_EQUAL(0l, i["timestamp"].asLong());
+ EXPECT_FALSE(i["payload"].valid());
+}
+
+TEST("that a trace node with children is serialized") {
+ TraceNode node;
+ node.addChild("foo", 1234);
+ node.addChild("bar", 1235);
+ Slime slime;
+ SlimeTraceSerializer serializer(slime.setObject());
+ node.accept(serializer);
+ Inspector & i(slime.get());
+ EXPECT_TRUE(i["timestamp"].valid());
+ EXPECT_EQUAL(0l, i["timestamp"].asLong());
+ EXPECT_TRUE(i["children"].valid());
+ Inspector & iBar(i["children"][0]);
+ Inspector & iFoo(i["children"][1]);
+ EXPECT_TRUE(iFoo.valid());
+ EXPECT_TRUE(iBar.valid());
+ EXPECT_EQUAL(1234, iFoo["timestamp"].asLong());
+ EXPECT_EQUAL("foo", iFoo["payload"].asString().make_string());
+ EXPECT_EQUAL(1235, iBar["timestamp"].asLong());
+ EXPECT_EQUAL("bar", iBar["payload"].asString().make_string());
+}
+
+TEST("that an empty root trace node can be deserialized") {
+ Slime slime;
+ Cursor & root(slime.setObject());
+ SlimeTraceDeserializer deserializer(root);
+ TraceNode node(deserializer.deserialize());
+ EXPECT_FALSE(node.hasNote());
+ EXPECT_EQUAL(0, node.getTimestamp());
+}
+
+
+TEST("that a single trace node can be deserialized") {
+ Slime slime;
+ Cursor & root(slime.setObject());
+ root.setLong("timestamp", 1234);
+ root.setString("payload", "hello");
+ SlimeTraceDeserializer deserializer(root);
+ TraceNode node(deserializer.deserialize());
+ EXPECT_EQUAL(1234, node.getTimestamp());
+ EXPECT_TRUE(node.hasNote());
+ EXPECT_EQUAL("hello", node.getNote());
+}
+
+TEST("that a trace node with children can be deserialized") {
+ Slime slime;
+ Cursor & root(slime.setObject());
+ Cursor & rootChildren(root.setArray("children"));
+ Cursor & foo(rootChildren.addObject());
+ foo.setLong("timestamp", 123);
+ Cursor &fooArray(foo.setArray("children"));
+ Cursor &foobar(fooArray.addObject());
+ foobar.setLong("timestamp", 45);
+ foobar.setString("payload", "world");
+ Cursor & bar(rootChildren.addObject());
+ bar.setLong("timestamp", 67);
+ bar.setString("payload", "!");
+
+ vespalib::slime::SimpleBuffer buf;
+ vespalib::slime::JsonFormat::encode(slime, buf, false);
+
+ SlimeTraceDeserializer deserializer(root);
+ TraceNode node(deserializer.deserialize());
+ EXPECT_FALSE(node.hasNote());
+ ASSERT_EQUAL(2u, node.getNumChildren());
+ TraceNode fooNode(node.getChild(0));
+ ASSERT_EQUAL(1u, fooNode.getNumChildren());
+ TraceNode fooBarNode(fooNode.getChild(0));
+ EXPECT_EQUAL("world", fooBarNode.getNote());
+ TraceNode barNode(node.getChild(1));
+ EXPECT_EQUAL("!", barNode.getNote());
+ ASSERT_EQUAL(0u, barNode.getNumChildren());
+}
+
+TEST("test serialization and deserialization") {
+ TraceNode root;
+ root.addChild("foo", 45);
+ root.addChild("bar");
+ root.addChild(TraceNode());
+ Slime slime;
+ SlimeTraceSerializer s(slime.setObject());
+ root.accept(s);
+ SlimeTraceDeserializer d(slime.get());
+ TraceNode root2(d.deserialize());
+ ASSERT_EQUAL(3u, root2.getNumChildren());
+}
+
+TEST_MAIN() { TEST_RUN_ALL(); }
diff --git a/vespalib/src/vespa/vespalib/trace/CMakeLists.txt b/vespalib/src/vespa/vespalib/trace/CMakeLists.txt
index d114ed4d953..87cd9428494 100644
--- a/vespalib/src/vespa/vespalib/trace/CMakeLists.txt
+++ b/vespalib/src/vespa/vespalib/trace/CMakeLists.txt
@@ -3,5 +3,7 @@ vespa_add_library(vespalib_vespalib_trace OBJECT
SOURCES
trace.cpp
tracenode.cpp
+ slime_trace_serializer.cpp
+ slime_trace_deserializer.cpp
DEPENDS
)
diff --git a/vespalib/src/vespa/vespalib/trace/slime_trace_deserializer.cpp b/vespalib/src/vespa/vespalib/trace/slime_trace_deserializer.cpp
new file mode 100644
index 00000000000..fc28dfbb40b
--- /dev/null
+++ b/vespalib/src/vespa/vespalib/trace/slime_trace_deserializer.cpp
@@ -0,0 +1,68 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+#include <vespa/vespalib/trace/slime_trace_deserializer.h>
+#include <vespa/vespalib/trace/slime_trace_serializer.h>
+#include <vespa/vespalib/trace/tracenode.h>
+
+using namespace vespalib::slime;
+
+namespace vespalib {
+
+SlimeTraceDeserializer::SlimeTraceDeserializer(const Inspector & inspector)
+ : _inspector(inspector)
+{
+}
+
+TraceNode
+SlimeTraceDeserializer::deserialize() const
+{
+ return deserialize(_inspector);
+}
+
+TraceNode
+SlimeTraceDeserializer::deserialize(const Inspector & inspector)
+{
+ TraceNode node(deserializeTraceNode(inspector));
+ deserializeChildren(inspector[SlimeTraceSerializer::CHILDREN], node);
+ return node;
+}
+
+TraceNode
+SlimeTraceDeserializer::deserializeTraceNode(const Inspector & inspector)
+{
+ int64_t timestamp(decodeTimestamp(inspector));
+ if (hasPayload(inspector)) {
+ std::string note(decodePayload(inspector));
+ return TraceNode(note, timestamp);
+ }
+ return TraceNode(timestamp);
+}
+
+bool
+SlimeTraceDeserializer::hasPayload(const Inspector & inspector)
+{
+ return inspector[SlimeTraceSerializer::PAYLOAD].valid();
+}
+
+vespalib::string
+SlimeTraceDeserializer::decodePayload(const Inspector & inspector)
+{
+ return inspector[SlimeTraceSerializer::PAYLOAD].asString().make_string();
+}
+
+int64_t
+SlimeTraceDeserializer::decodeTimestamp(const Inspector & inspector)
+{
+ return inspector[SlimeTraceSerializer::TIMESTAMP].asLong();
+}
+
+void
+SlimeTraceDeserializer::deserializeChildren(const Inspector & inspector, TraceNode & node)
+{
+ for (size_t i(0); i < inspector.children(); i++) {
+ Inspector & child(inspector[i]);
+ TraceNode childNode(deserialize(child));
+ node.addChild(childNode);
+ }
+}
+
+}
diff --git a/vespalib/src/vespa/vespalib/trace/slime_trace_deserializer.h b/vespalib/src/vespa/vespalib/trace/slime_trace_deserializer.h
new file mode 100644
index 00000000000..dc8c6dc5cff
--- /dev/null
+++ b/vespalib/src/vespa/vespalib/trace/slime_trace_deserializer.h
@@ -0,0 +1,31 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+#pragma once
+
+#include <vespa/vespalib/data/slime/slime.h>
+#include <vespa/vespalib/stllike/string.h>
+#include <stack>
+
+namespace vespalib {
+
+class TraceNode;
+
+/**
+ * For deserializing a TraceNode and its children. Note that the ordering of nodes
+ * are NOT guaranteed.
+ */
+class SlimeTraceDeserializer
+{
+public:
+ SlimeTraceDeserializer(const slime::Inspector & inspector);
+ TraceNode deserialize() const;
+private:
+ static TraceNode deserialize(const slime::Inspector & inspector);
+ static TraceNode deserializeTraceNode(const slime::Inspector & inspector);
+ static void deserializeChildren(const slime::Inspector & inspector, TraceNode & node);
+ static bool hasPayload(const slime::Inspector & inspector);
+ static int64_t decodeTimestamp(const slime::Inspector & inspector);
+ static vespalib::string decodePayload(const slime::Inspector & inspector);
+ const slime::Inspector & _inspector;
+};
+
+}
diff --git a/vespalib/src/vespa/vespalib/trace/slime_trace_serializer.cpp b/vespalib/src/vespa/vespalib/trace/slime_trace_serializer.cpp
new file mode 100644
index 00000000000..4332d6bf045
--- /dev/null
+++ b/vespalib/src/vespa/vespalib/trace/slime_trace_serializer.cpp
@@ -0,0 +1,62 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+#include <vespa/vespalib/trace/slime_trace_serializer.h>
+#include <vespa/vespalib/trace/trace.h>
+
+using namespace vespalib::slime;
+
+namespace vespalib {
+
+const Memory SlimeTraceSerializer::TIMESTAMP("timestamp");
+const Memory SlimeTraceSerializer::PAYLOAD("payload");
+const Memory SlimeTraceSerializer::CHILDREN("children");
+
+SlimeTraceSerializer::SlimeTraceSerializer(Cursor & cursor)
+ : _cursors()
+{
+ _cursors.push(&cursor);
+}
+
+void
+SlimeTraceSerializer::visit(const TraceNode & node)
+{
+ assert(!_cursors.empty());
+ Cursor * current(_cursors.top());
+ assert(current != NULL);
+ _cursors.pop();
+ addTimestamp(*current, node);
+ addPayload(*current, node);
+ addChildrenCursors(*current, node);
+}
+
+void
+SlimeTraceSerializer::addTimestamp(Cursor & current, const TraceNode & node)
+{
+ current.setLong(TIMESTAMP, node.getTimestamp());
+}
+
+void
+SlimeTraceSerializer::addPayload(Cursor & current, const TraceNode & node)
+{
+ if (node.hasNote()) {
+ current.setString(PAYLOAD, Memory(node.getNote()));
+ }
+}
+
+void
+SlimeTraceSerializer::addChildrenCursors(Cursor & current, const TraceNode & node)
+{
+ if (node.getNumChildren() > 0) {
+ addChildrenCursorsToStack(current.setArray(CHILDREN), node);
+ }
+}
+
+void
+SlimeTraceSerializer::addChildrenCursorsToStack(Cursor & childrenArray, const TraceNode & node)
+{
+ for (uint32_t childIndex(0); childIndex < node.getNumChildren(); childIndex++) {
+ Cursor & child(childrenArray.addObject());
+ _cursors.push(&child);
+ }
+}
+
+}
diff --git a/vespalib/src/vespa/vespalib/trace/slime_trace_serializer.h b/vespalib/src/vespa/vespalib/trace/slime_trace_serializer.h
new file mode 100644
index 00000000000..3b50f0878bf
--- /dev/null
+++ b/vespalib/src/vespa/vespalib/trace/slime_trace_serializer.h
@@ -0,0 +1,32 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+#pragma once
+
+#include <vespa/vespalib/trace/tracevisitor.h>
+#include <vespa/vespalib/data/slime/slime.h>
+#include <stack>
+
+namespace vespalib {
+
+class TraceNode;
+
+/**
+ * A serializer of TraceNodes using the TraceVisitor API. The serialized order of the nodes are NOT
+ * guaranteed to be in the same order as the original.
+ */
+class SlimeTraceSerializer : public TraceVisitor
+{
+public:
+ SlimeTraceSerializer(slime::Cursor & cursor);
+ void visit(const TraceNode & node);
+ static const slime::Memory TIMESTAMP;
+ static const slime::Memory PAYLOAD;
+ static const slime::Memory CHILDREN;
+private:
+ void addTimestamp(slime::Cursor & current, const TraceNode & node);
+ void addPayload(slime::Cursor & current, const TraceNode & node);
+ void addChildrenCursors(slime::Cursor & current, const TraceNode & node);
+ void addChildrenCursorsToStack(slime::Cursor & childrenArray, const TraceNode & node);
+ std::stack<slime::Cursor *> _cursors;
+};
+
+}