mementus 0.3.0 → 0.3.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/mementus/breadth_first_search.rb +11 -11
- data/lib/mementus/depth_first_search.rb +10 -10
- data/lib/mementus/direction.rb +16 -0
- data/lib/mementus/edge_builder.rb +5 -0
- data/lib/mementus/graph.rb +8 -0
- data/lib/mementus/graph_builder.rb +6 -2
- data/lib/mementus/node_proxy.rb +4 -4
- data/lib/mementus/query/step.rb +1 -1
- data/lib/mementus/structure.rb +15 -23
- data/lib/mementus/version.rb +1 -1
- data/lib/mementus.rb +2 -0
- data/spec/direction_spec.rb +27 -0
- data/spec/graph_spec.rb +3 -10
- data/spec/node_proxy_spec.rb +1 -1
- data/spec/structure_spec.rb +4 -27
- data/spec/traversal_spec.rb +15 -19
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5a5329b3dc6e0429a47324ea39971d0cd87320ea
|
4
|
+
data.tar.gz: e4e2469c67e5368f014d7ef870bb9846c6b57521
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9c551118086f9c08fe6d60127c7f7bf8eb41a4ee2a0c9a0834dde157e05087316ae2189dffc5d2f16ab8f35273dab928a4fc65e4269dab5d25945c465aa725a2
|
7
|
+
data.tar.gz: cac72cbf24feba518297dcf86e9a331a058920ec9d1bf15213f3fa294d4fb36ecffb4b4cabc2e66b0e5f22613b71907946be6f0f9103aa95c5c808e074b97f31
|
@@ -1,27 +1,27 @@
|
|
1
1
|
module Mementus
|
2
2
|
class BreadthFirstSearch
|
3
|
-
def initialize(graph,
|
3
|
+
def initialize(graph, start_id)
|
4
4
|
@graph = graph
|
5
|
-
@
|
6
|
-
@visited = { @
|
5
|
+
@start_id = start_id
|
6
|
+
@visited = { @start_id => true }
|
7
7
|
@queue = []
|
8
8
|
end
|
9
9
|
|
10
10
|
def each(&block)
|
11
|
-
visit(
|
11
|
+
visit(@start_id, &block)
|
12
12
|
end
|
13
13
|
|
14
14
|
private
|
15
15
|
|
16
|
-
def visit(
|
17
|
-
@queue
|
16
|
+
def visit(id, &block)
|
17
|
+
@queue.concat(@graph.adjacent(id))
|
18
18
|
|
19
|
-
while
|
20
|
-
next if @visited[
|
19
|
+
while next_id = @queue.shift
|
20
|
+
next if @visited[next_id]
|
21
21
|
|
22
|
-
@visited[
|
23
|
-
block.call(
|
24
|
-
@queue
|
22
|
+
@visited[next_id] = true
|
23
|
+
block.call(NodeProxy.new(next_id, @graph))
|
24
|
+
@queue.concat(@graph.adjacent(next_id))
|
25
25
|
end
|
26
26
|
end
|
27
27
|
end
|
@@ -1,24 +1,24 @@
|
|
1
1
|
module Mementus
|
2
2
|
class DepthFirstSearch
|
3
|
-
def initialize(graph,
|
3
|
+
def initialize(graph, start_id)
|
4
4
|
@graph = graph
|
5
|
-
@
|
6
|
-
@visited = { @
|
5
|
+
@start_id = start_id
|
6
|
+
@visited = { @start_id => true }
|
7
7
|
end
|
8
8
|
|
9
9
|
def each(&block)
|
10
|
-
visit(
|
10
|
+
visit(@start_id, &block)
|
11
11
|
end
|
12
12
|
|
13
13
|
private
|
14
14
|
|
15
|
-
def visit(
|
16
|
-
|
17
|
-
next if @visited[
|
15
|
+
def visit(id, &block)
|
16
|
+
@graph.each_adjacent(id) do |adjacent_id|
|
17
|
+
next if @visited[adjacent_id]
|
18
18
|
|
19
|
-
@visited[
|
20
|
-
block.call(
|
21
|
-
visit(
|
19
|
+
@visited[adjacent_id] = true
|
20
|
+
block.call(NodeProxy.new(adjacent_id, @graph))
|
21
|
+
visit(adjacent_id, &block)
|
22
22
|
end
|
23
23
|
end
|
24
24
|
end
|
data/lib/mementus/graph.rb
CHANGED
@@ -26,6 +26,10 @@ module Mementus
|
|
26
26
|
@structure.directed?
|
27
27
|
end
|
28
28
|
|
29
|
+
def n(id)
|
30
|
+
Processor.new(self, Pipes::Node.new(id))
|
31
|
+
end
|
32
|
+
|
29
33
|
def has_node?(node)
|
30
34
|
@structure.has_node?(node)
|
31
35
|
end
|
@@ -42,6 +46,10 @@ module Mementus
|
|
42
46
|
@structure.nodes
|
43
47
|
end
|
44
48
|
|
49
|
+
def adjacent(id)
|
50
|
+
@structure.adjacent(id)
|
51
|
+
end
|
52
|
+
|
45
53
|
def each_node(&blk)
|
46
54
|
@structure.each_node(&blk)
|
47
55
|
end
|
@@ -9,11 +9,15 @@ module Mementus
|
|
9
9
|
end
|
10
10
|
|
11
11
|
def create_edge(&block)
|
12
|
-
|
12
|
+
edge = EdgeBuilder.new
|
13
|
+
yield edge
|
14
|
+
@structure.add_edge(edge)
|
13
15
|
end
|
14
16
|
|
15
17
|
def create_node(&block)
|
16
|
-
|
18
|
+
node = NodeBuilder.new
|
19
|
+
yield node
|
20
|
+
@structure.add_node(node)
|
17
21
|
end
|
18
22
|
|
19
23
|
def add_edge(edge)
|
data/lib/mementus/node_proxy.rb
CHANGED
@@ -1,12 +1,12 @@
|
|
1
1
|
module Mementus
|
2
2
|
class NodeProxy
|
3
|
-
def initialize(
|
4
|
-
@
|
3
|
+
def initialize(id, graph)
|
4
|
+
@id = id
|
5
5
|
@graph = graph
|
6
6
|
end
|
7
7
|
|
8
8
|
def id
|
9
|
-
@
|
9
|
+
@id
|
10
10
|
end
|
11
11
|
|
12
12
|
def label
|
@@ -14,7 +14,7 @@ module Mementus
|
|
14
14
|
end
|
15
15
|
|
16
16
|
def each_adjacent(&block)
|
17
|
-
@graph.each_adjacent(@
|
17
|
+
@graph.each_adjacent(@id, &block)
|
18
18
|
end
|
19
19
|
|
20
20
|
def adjacent
|
data/lib/mementus/query/step.rb
CHANGED
data/lib/mementus/structure.rb
CHANGED
@@ -19,58 +19,50 @@ module Mementus
|
|
19
19
|
@is_directed
|
20
20
|
end
|
21
21
|
|
22
|
-
def create_edge(&block)
|
23
|
-
edge = Edge.new
|
24
|
-
yield edge
|
25
|
-
add_edge(edge)
|
26
|
-
end
|
27
|
-
|
28
22
|
def add_node(node)
|
29
|
-
@index[node] ||= Set.new
|
30
|
-
end
|
31
|
-
|
32
|
-
def create_node(&block)
|
33
|
-
node = Node.new
|
34
|
-
yield node
|
35
|
-
add_node(node)
|
23
|
+
@index[node.id] ||= Set.new
|
36
24
|
end
|
37
25
|
|
38
26
|
def add_edge(edge)
|
39
27
|
add_node(edge.from) unless has_node?(edge.from)
|
40
28
|
add_node(edge.to) unless has_node?(edge.to)
|
41
29
|
|
42
|
-
@index[edge.from].add(edge.to)
|
43
|
-
@index[edge.to].add(edge.from) unless directed?
|
30
|
+
@index[edge.from.id].add(edge.to.id)
|
31
|
+
@index[edge.to.id].add(edge.from.id) unless directed?
|
44
32
|
end
|
45
33
|
|
46
34
|
def has_node?(node)
|
47
|
-
@index.key?(node)
|
35
|
+
@index.key?(node.id)
|
48
36
|
end
|
49
37
|
|
50
38
|
def has_edge?(edge)
|
51
|
-
has_node?(edge.from) && @index[edge.from].include?(edge.to)
|
39
|
+
has_node?(edge.from) && @index[edge.from.id].include?(edge.to.id)
|
52
40
|
end
|
53
41
|
|
54
42
|
def node(id)
|
55
|
-
|
43
|
+
NodeProxy.new(id, self)
|
56
44
|
end
|
57
45
|
|
58
46
|
def nodes
|
59
|
-
@index.keys
|
47
|
+
@index.keys.map { |id| NodeProxy.new(id, self) }
|
48
|
+
end
|
49
|
+
|
50
|
+
def adjacent(id)
|
51
|
+
@index[id].to_a
|
60
52
|
end
|
61
53
|
|
62
54
|
def each_node(&blk)
|
63
|
-
|
55
|
+
nodes.each(&blk)
|
64
56
|
end
|
65
57
|
|
66
|
-
def each_adjacent(
|
67
|
-
@index[
|
58
|
+
def each_adjacent(id, &blk)
|
59
|
+
@index[id].each(&blk)
|
68
60
|
end
|
69
61
|
|
70
62
|
def each_edge(&blk)
|
71
63
|
if directed?
|
72
64
|
each_node do |from|
|
73
|
-
each_adjacent(from) do |to|
|
65
|
+
each_adjacent(from.id) do |to|
|
74
66
|
yield Edge.new(from, to)
|
75
67
|
end
|
76
68
|
end
|
data/lib/mementus/version.rb
CHANGED
data/lib/mementus.rb
CHANGED
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Mementus::Direction do
|
4
|
+
specify 'incoming const' do
|
5
|
+
expect(Mementus::Direction::IN).to eq(:in)
|
6
|
+
end
|
7
|
+
|
8
|
+
specify 'outgoing const' do
|
9
|
+
expect(Mementus::Direction::OUT).to eq(:out)
|
10
|
+
end
|
11
|
+
|
12
|
+
specify 'bidirectional const' do
|
13
|
+
expect(Mementus::Direction::BOTH).to eq(:both)
|
14
|
+
end
|
15
|
+
|
16
|
+
specify 'incoming flips to outgoing' do
|
17
|
+
expect(Mementus::Direction.flip(:in)).to eq(:out)
|
18
|
+
end
|
19
|
+
|
20
|
+
specify 'outgoing flips to incoming' do
|
21
|
+
expect(Mementus::Direction.flip(:out)).to eq(:in)
|
22
|
+
end
|
23
|
+
|
24
|
+
specify 'bidirectional does not flip' do
|
25
|
+
expect(Mementus::Direction.flip(:both)).to eq(:both)
|
26
|
+
end
|
27
|
+
end
|
data/spec/graph_spec.rb
CHANGED
@@ -1,10 +1,6 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Mementus::Graph do
|
4
|
-
let(:graph) do
|
5
|
-
|
6
|
-
end
|
7
|
-
|
8
4
|
specify '#new' do
|
9
5
|
graph = Mementus::Graph.new
|
10
6
|
|
@@ -62,19 +58,15 @@ describe Mementus::Graph do
|
|
62
58
|
end
|
63
59
|
|
64
60
|
expect(graph.has_node?(node)).to be true
|
65
|
-
expect(graph.has_node?(node.dup)).to be false
|
66
61
|
end
|
67
62
|
|
68
63
|
specify '#has_edge?' do
|
69
64
|
edge = Mementus::Edge.new(Mementus::Node.new(1, :node), Mementus::Node.new(2, :node))
|
70
|
-
edge2 = Mementus::Edge.new(Mementus::Node.new(1, :node), Mementus::Node.new(2, :node))
|
71
|
-
|
72
65
|
graph = Mementus::Graph.new do
|
73
66
|
add_edge(edge)
|
74
67
|
end
|
75
68
|
|
76
69
|
expect(graph.has_edge?(edge)).to be true
|
77
|
-
expect(graph.has_edge?(edge2)).to be false
|
78
70
|
end
|
79
71
|
|
80
72
|
specify '#node(id)' do
|
@@ -83,7 +75,7 @@ describe Mementus::Graph do
|
|
83
75
|
add_edge(edge)
|
84
76
|
end
|
85
77
|
|
86
|
-
expect(graph.node(1)).to eq(edge.from)
|
78
|
+
expect(graph.node(1).id).to eq(edge.from.id)
|
87
79
|
end
|
88
80
|
|
89
81
|
specify '#nodes(filter)' do
|
@@ -92,6 +84,7 @@ describe Mementus::Graph do
|
|
92
84
|
add_edge(edge)
|
93
85
|
end
|
94
86
|
|
95
|
-
expect(graph.nodes).to eq(
|
87
|
+
expect(graph.nodes.first.id).to eq(edge.from.id)
|
88
|
+
expect(graph.nodes.last.id).to eq(edge.to.id)
|
96
89
|
end
|
97
90
|
end
|
data/spec/node_proxy_spec.rb
CHANGED
@@ -10,7 +10,7 @@ describe Mementus::NodeProxy do
|
|
10
10
|
add_edge(Mementus::Edge.new(node1, node3))
|
11
11
|
end
|
12
12
|
|
13
|
-
node_proxy = Mementus::NodeProxy.new(
|
13
|
+
node_proxy = Mementus::NodeProxy.new(1, graph)
|
14
14
|
expect(node_proxy.adjacent.map { |node| node.id}).to eq([node2.id, node3.id])
|
15
15
|
end
|
16
16
|
end
|
data/spec/structure_spec.rb
CHANGED
@@ -17,16 +17,6 @@ describe Mementus::Structure do
|
|
17
17
|
expect(structure.edges_count).to eq(0)
|
18
18
|
end
|
19
19
|
|
20
|
-
specify '#create_node' do
|
21
|
-
structure.create_node do |node|
|
22
|
-
node.id = 1
|
23
|
-
node.label = :vertex
|
24
|
-
end
|
25
|
-
|
26
|
-
expect(structure.nodes_count).to eq(1)
|
27
|
-
expect(structure.edges_count).to eq(0)
|
28
|
-
end
|
29
|
-
|
30
20
|
specify '#add_edge' do
|
31
21
|
structure.add_edge(Mementus::Edge.new(Mementus::Node.new(1, :node), Mementus::Node.new(2, :node)))
|
32
22
|
|
@@ -34,45 +24,32 @@ describe Mementus::Structure do
|
|
34
24
|
expect(structure.edges_count).to eq(1)
|
35
25
|
end
|
36
26
|
|
37
|
-
specify '#create_edge' do
|
38
|
-
structure.create_edge do |edge|
|
39
|
-
edge.label = :relationship
|
40
|
-
edge.from = "A"
|
41
|
-
edge.to = "B"
|
42
|
-
end
|
43
|
-
|
44
|
-
expect(structure.nodes_count).to eq(2)
|
45
|
-
expect(structure.edges_count).to eq(1)
|
46
|
-
end
|
47
|
-
|
48
27
|
specify '#has_node?' do
|
49
28
|
node = Mementus::Node.new(1, :node)
|
50
29
|
structure.add_node(node)
|
51
30
|
|
52
31
|
expect(structure.has_node?(node)).to be true
|
53
|
-
expect(structure.has_node?(node.dup)).to be false
|
54
32
|
end
|
55
33
|
|
56
34
|
specify '#has_edge?' do
|
57
35
|
edge = Mementus::Edge.new(Mementus::Node.new(1, :node), Mementus::Node.new(2, :node))
|
58
|
-
edge2 = Mementus::Edge.new(Mementus::Node.new(1, :node), Mementus::Node.new(2, :node))
|
59
36
|
structure.add_edge(edge)
|
60
37
|
|
61
38
|
expect(structure.has_edge?(edge)).to be true
|
62
|
-
expect(structure.has_edge?(edge2)).to be false
|
63
39
|
end
|
64
40
|
|
65
41
|
specify '#node(id)' do
|
66
42
|
edge = Mementus::Edge.new(Mementus::Node.new(1, :node), Mementus::Node.new(2, :node))
|
67
43
|
structure.add_edge(edge)
|
68
44
|
|
69
|
-
expect(structure.node(1)).to eq(edge.from)
|
45
|
+
expect(structure.node(1).id).to eq(edge.from.id)
|
70
46
|
end
|
71
47
|
|
72
|
-
specify '#nodes
|
48
|
+
specify '#nodes' do
|
73
49
|
edge = Mementus::Edge.new(Mementus::Node.new(1, :node), Mementus::Node.new(2, :node))
|
74
50
|
structure.add_edge(edge)
|
75
51
|
|
76
|
-
expect(structure.nodes).to eq(
|
52
|
+
expect(structure.nodes.first.id).to eq(edge.from.id)
|
53
|
+
expect(structure.nodes.last.id).to eq(edge.to.id)
|
77
54
|
end
|
78
55
|
end
|
data/spec/traversal_spec.rb
CHANGED
@@ -1,14 +1,9 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe 'Basic graph traversals' do
|
4
|
-
let(:start) do
|
5
|
-
Mementus::Node.new(1, :node)
|
6
|
-
end
|
7
|
-
|
8
4
|
let(:graph) do
|
9
|
-
|
10
|
-
|
11
|
-
add_edge(Mementus::Edge.new(start_node, Mementus::Node.new(2, :node)))
|
5
|
+
Mementus::Graph.new do
|
6
|
+
add_edge(Mementus::Edge.new(Mementus::Node.new(1, :node), Mementus::Node.new(2, :node)))
|
12
7
|
add_edge(Mementus::Edge.new(Mementus::Node.new(2, :node), Mementus::Node.new(3, :node)))
|
13
8
|
add_edge(Mementus::Edge.new(Mementus::Node.new(2, :node), Mementus::Node.new(5, :node)))
|
14
9
|
add_edge(Mementus::Edge.new(Mementus::Node.new(1, :node), Mementus::Node.new(6, :node)))
|
@@ -19,22 +14,23 @@ describe 'Basic graph traversals' do
|
|
19
14
|
end
|
20
15
|
|
21
16
|
specify 'DepthFirstSearch#each' do
|
22
|
-
traversal = Mementus::DepthFirstSearch.new(graph,
|
17
|
+
traversal = Mementus::DepthFirstSearch.new(graph, 1)
|
23
18
|
|
24
|
-
expected = [
|
25
|
-
|
26
|
-
traversal.each
|
27
|
-
|
28
|
-
|
19
|
+
expected = [2,3,5,9,7,8,6]
|
20
|
+
actual = []
|
21
|
+
traversal.each { |n| actual << n.id }
|
22
|
+
|
23
|
+
expect(actual).to eq(expected)
|
29
24
|
end
|
30
25
|
|
31
26
|
specify 'BreadthFirstSearch#each' do
|
32
|
-
traversal = Mementus::
|
27
|
+
traversal = Mementus::BreadthFirstSearch.new(graph, 1)
|
33
28
|
|
34
|
-
expected = [
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
29
|
+
expected = [2,6,3,5,7,9,8]
|
30
|
+
|
31
|
+
actual = []
|
32
|
+
traversal.each { |n| actual << n.id }
|
33
|
+
|
34
|
+
expect(actual).to eq(expected)
|
39
35
|
end
|
40
36
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mementus
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- maetl
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-05-
|
11
|
+
date: 2016-05-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -68,6 +68,7 @@ files:
|
|
68
68
|
- lib/mementus.rb
|
69
69
|
- lib/mementus/breadth_first_search.rb
|
70
70
|
- lib/mementus/depth_first_search.rb
|
71
|
+
- lib/mementus/direction.rb
|
71
72
|
- lib/mementus/edge.rb
|
72
73
|
- lib/mementus/edge_builder.rb
|
73
74
|
- lib/mementus/graph.rb
|
@@ -82,6 +83,7 @@ files:
|
|
82
83
|
- lib/mementus/structure.rb
|
83
84
|
- lib/mementus/version.rb
|
84
85
|
- mementus.gemspec
|
86
|
+
- spec/direction_spec.rb
|
85
87
|
- spec/graph_spec.rb
|
86
88
|
- spec/integer_id_spec.rb
|
87
89
|
- spec/node_proxy_spec.rb
|
@@ -114,6 +116,7 @@ signing_key:
|
|
114
116
|
specification_version: 4
|
115
117
|
summary: In-memory data model
|
116
118
|
test_files:
|
119
|
+
- spec/direction_spec.rb
|
117
120
|
- spec/graph_spec.rb
|
118
121
|
- spec/integer_id_spec.rb
|
119
122
|
- spec/node_proxy_spec.rb
|