Utils - random graph generator hacked
Summary: RandomGraphGenerator added Reviewers: teon.banek, mislav.bradac, buda Reviewed By: buda Subscribers: pullbot Differential Revision: https://phabricator.memgraph.io/D165
This commit is contained in:
parent
35668d5b9f
commit
2215173a58
@ -72,11 +72,11 @@ std::string TypedValueToString(const TypedValue &value) {
|
||||
switch (value.type()) {
|
||||
case TypedValue::Type::Vertex: {
|
||||
auto va = value.Value<VertexAccessor>();
|
||||
ss << "Vertex(";
|
||||
ss << "V(";
|
||||
PrintIterable(ss, va.labels(), ":", [&](auto label) {
|
||||
return va.db_accessor().label_name(label);
|
||||
});
|
||||
ss << "{";
|
||||
ss << " {";
|
||||
PrintIterable(ss, va.Properties(), ", ", [&](const auto kv) {
|
||||
return va.db_accessor().property_name(kv.first) + ": " +
|
||||
TypedValueToString(kv.second);
|
||||
@ -86,8 +86,8 @@ std::string TypedValueToString(const TypedValue &value) {
|
||||
}
|
||||
case TypedValue::Type::Edge: {
|
||||
auto ea = value.Value<EdgeAccessor>();
|
||||
ss << "Edge[" << ea.db_accessor().edge_type_name(ea.edge_type());
|
||||
ss << "{";
|
||||
ss << "E[" << ea.db_accessor().edge_type_name(ea.edge_type());
|
||||
ss << " {";
|
||||
PrintIterable(ss, ea.Properties(), ", ", [&](const auto kv) {
|
||||
return ea.db_accessor().property_name(kv.first) + ": " +
|
||||
TypedValueToString(kv.second);
|
||||
@ -155,6 +155,8 @@ void PrintResults(ResultStreamFaker results) {
|
||||
emit_horizontal_line();
|
||||
for (const auto &result_vec : result_strings) emit_result_vec(result_vec);
|
||||
emit_horizontal_line();
|
||||
std::cout << "Found " << results_data.size() << " matching results"
|
||||
<< std::endl;
|
||||
|
||||
// output the summary
|
||||
std::cout << "Query summary: {";
|
||||
|
149
src/utils/random_graph_generator.hpp
Normal file
149
src/utils/random_graph_generator.hpp
Normal file
@ -0,0 +1,149 @@
|
||||
//
|
||||
// Copyright 2017 Memgraph
|
||||
// Created by Florijan Stamenkovic on 23.03.17.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstdlib>
|
||||
#include <functional>
|
||||
#include <vector>
|
||||
|
||||
#include "database/graph_db_accessor.hpp"
|
||||
#include "storage/property_value.hpp"
|
||||
#include "storage/vertex_accessor.hpp"
|
||||
#include "utils/assert.hpp"
|
||||
|
||||
namespace utils {
|
||||
|
||||
/**
|
||||
* Returns a lambda that generates random ints
|
||||
* in the [from, to) range.
|
||||
*/
|
||||
auto RandomIntGenerator(int from, int to) {
|
||||
permanent_assert(from < to, "Must have from < to");
|
||||
int range = to - from;
|
||||
return [from, range]() -> int { return rand() % range + from; };
|
||||
}
|
||||
|
||||
/**
|
||||
* Random graph generator. Define a random graph
|
||||
* over a sequence of steps, and then commit.
|
||||
* You can only commit once and can't change
|
||||
* graph afterwards.
|
||||
*/
|
||||
class RandomGraphGenerator {
|
||||
public:
|
||||
RandomGraphGenerator(GraphDbAccessor &dba) : dba_(dba) {}
|
||||
|
||||
/**
|
||||
* Adds the given number of vertices, with
|
||||
* the given labels.
|
||||
*/
|
||||
void AddVertices(uint count, std::vector<std::string> label_names) {
|
||||
permanent_assert(!did_commit_, "Already committed");
|
||||
|
||||
std::vector<GraphDb::Label> labels;
|
||||
for (const auto &label_name : label_names)
|
||||
labels.push_back(dba_.label(label_name));
|
||||
|
||||
for (uint i = 0; i < count; ++i) {
|
||||
auto vertex = dba_.insert_vertex();
|
||||
for (auto label : labels) vertex.add_label(label);
|
||||
vertices_.push_back(vertex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the given number of edges to the graph.
|
||||
*
|
||||
* @param count The number of edges to add.
|
||||
* @param edge_type_name Name of the edge type.
|
||||
* @param from_filter Filter of from vertices for new edges.
|
||||
* By default all vertices are accepted.
|
||||
* @param to_filter Filter of to vertices for new edges.
|
||||
* By default all vertices are accepted.
|
||||
*/
|
||||
void AddEdges(uint count, const std::string &edge_type_name,
|
||||
std::function<bool(VertexAccessor &va)> from_filter = {},
|
||||
std::function<bool(VertexAccessor &va)> to_filter = {}) {
|
||||
permanent_assert(!did_commit_, "Already committed");
|
||||
|
||||
// create two temporary sets of vertices we will poll from
|
||||
auto vertices_from = Filter(vertices_, from_filter);
|
||||
auto vertices_to = Filter(vertices_, from_filter);
|
||||
|
||||
auto edge_type = dba_.edge_type(edge_type_name);
|
||||
for (int i = 0; i < count; ++i)
|
||||
edges_.push_back(dba_.insert_edge(
|
||||
vertices_from[rand() % vertices_from.size()].get(),
|
||||
vertices_to[rand() % vertices_to.size()].get(), edge_type));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a generated property on a random vertex.
|
||||
*
|
||||
* @tparam TValue Type of value to set.
|
||||
* @param count The number of vertices to set the property on.
|
||||
* @param prop_name Name of the property.
|
||||
* @param predicate Filter that accepts or rejects a Vertex.
|
||||
* @param value_generator Function that accepts nothing and
|
||||
* returns a property.
|
||||
*/
|
||||
template <typename TValue>
|
||||
void SetVertexProperty(
|
||||
uint count, const std::string &prop_name,
|
||||
std::function<TValue()> value_generator,
|
||||
std::function<bool(VertexAccessor &va)> predicate = {}) {
|
||||
permanent_assert(!did_commit_, "Already committed");
|
||||
|
||||
auto property = dba_.property(prop_name);
|
||||
for (auto va : Filter(vertices_, predicate))
|
||||
va.get().PropsSet(property, value_generator());
|
||||
}
|
||||
|
||||
/**
|
||||
* Commits the random graph to storage.
|
||||
* Can only be called once.
|
||||
*/
|
||||
void Commit() {
|
||||
debug_assert(!did_commit_, "Already committed random graph");
|
||||
dba_.commit();
|
||||
}
|
||||
|
||||
private:
|
||||
GraphDbAccessor &dba_;
|
||||
|
||||
// storage for data we operate on
|
||||
std::vector<VertexAccessor> vertices_;
|
||||
std::vector<EdgeAccessor> edges_;
|
||||
|
||||
// can't perform ops after committing
|
||||
bool did_commit_{false};
|
||||
|
||||
/**
|
||||
* Helper function for filtering.
|
||||
* Accepts a vector of TItems, a predicate
|
||||
* that accepts it or not, and returns a
|
||||
* vector of reference wrappers to accepted
|
||||
* items.
|
||||
*
|
||||
* @tparam TItem Type of item.
|
||||
* @param collection The collection to filter on.
|
||||
* @param predicate A predicate. By default always true.
|
||||
* @return A collection of reference_wrappers to TItems.
|
||||
*/
|
||||
template <typename TItem>
|
||||
std::vector<std::reference_wrapper<TItem>> Filter(
|
||||
std::vector<TItem> &collection,
|
||||
std::function<bool(TItem &item)> predicate = {}) {
|
||||
if (!predicate) predicate = [](TItem &item) { return true; };
|
||||
std::vector<std::reference_wrapper<TItem>> r_val;
|
||||
for (TItem &item : collection)
|
||||
if (predicate(item)) r_val.emplace_back(std::ref(item));
|
||||
|
||||
return r_val;
|
||||
}
|
||||
};
|
||||
}
|
@ -3,6 +3,19 @@
|
||||
#include "dbms/dbms.hpp"
|
||||
#include "query/console.hpp"
|
||||
#include "query/interpreter.hpp"
|
||||
#include "utils/random_graph_generator.hpp"
|
||||
|
||||
void random_generate(Dbms &dbms) {
|
||||
auto dba = dbms.active();
|
||||
utils::RandomGraphGenerator generator(*dba);
|
||||
|
||||
generator.AddVertices(1000000, {"Person"});
|
||||
generator.AddEdges(5000000, "Friend");
|
||||
generator.SetVertexProperty<int>(1000000, "age", utils::RandomIntGenerator(3, 60));
|
||||
generator.SetVertexProperty<int>(1000000, "height", utils::RandomIntGenerator(120, 200));
|
||||
|
||||
generator.Commit();
|
||||
}
|
||||
|
||||
void fill_db(Dbms &dbms) {
|
||||
auto dba = dbms.active();
|
||||
@ -63,7 +76,9 @@ int main(int argc, char *argv[]) {
|
||||
REGISTER_ARGS(argc, argv);
|
||||
|
||||
Dbms dbms;
|
||||
fill_db(dbms);
|
||||
std::cout << "Generating graph..." << std::endl;
|
||||
// fill_db(dbms);
|
||||
random_generate(dbms);
|
||||
query::Repl(dbms);
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user