pacer 2.0.12-java → 2.0.13-java

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c1d6ed458658599f541aebf48b0858211c9c5a12
4
- data.tar.gz: e8da00bad64ae64ee08e59ed07640b4ba61a8851
3
+ metadata.gz: 13555fbf36509b247945a23559f60d2b5eddb0e4
4
+ data.tar.gz: 258b4dd295d67b91dfbb8aa29969b7bef809fb2b
5
5
  SHA512:
6
- metadata.gz: a6ba6daeb5f72cbafbfe17664c1188089e9a939194c3b5810ebbf38851a473e21b7bf9a95df25215671ce38deca8dd543adfc4334ec70f6dc502a652e13ae606
7
- data.tar.gz: b27450c26b112b401a905ef1b5a889b213c5166615440eb7c1b931bb909891e6972102470d803306c102d67c18cab19008a7fe4c0cbdad69635738f9458a72ef
6
+ metadata.gz: 7ed67f63063e560b02926a116fcace7dd285d7522d2f8165ccc659b34df9a66756c6bb31013e37a540844781a58fad4ebb6a2eb99dbec68ab772ed9d75e341a2
7
+ data.tar.gz: d1b69243930b7906702a5c67f5b2359b2dbf9f3b61bcf26c68a3b8bfe9b2cf51ab0a060277c9a13faee0efc5732279e9f70ba15a647e384f021ada7603bf2bdf
data/README.md CHANGED
@@ -1,9 +1,9 @@
1
1
  # Pacer
2
- [![Coverage Status](https://img.shields.io/coveralls/pangloss/pacer.svg)](https://coveralls.io/r/pangloss/pacer) [![Build Status](https://travis-ci.org/pangloss/pacer.svg)](https://travis-ci.org/pangloss/pacer)
2
+ [![Coverage Status](https://img.shields.io/coveralls/pangloss/pacer.svg)](https://coveralls.io/r/pangloss/pacer) [![Build Status](https://travis-ci.org/pangloss/pacer.svg)](https://travis-ci.org/pangloss/pacer) [![Code Climate](https://codeclimate.com/github/pangloss/pacer/badges/gpa.svg)](https://codeclimate.com/github/pangloss/pacer)
3
3
 
4
4
  Pacer is a JRuby library that enables very expressive graph traversals.
5
5
 
6
- It currently supports all of the major graph databases including [OrientDB][http://orientdb.com], [Neo4j](http://neo4j.org)
6
+ It currently supports all of the major graph databases including [OrientDB](http://orientdb.com), [Neo4j](http://neo4j.org)
7
7
  and [Dex](http://www.sparsity-technologies.com/dex) thanks to the
8
8
  [Tinkerpop](http://tinkerpop.com) graphdb stack. Plus there's a very
9
9
  convenient in-memory graph called TinkerGraph which is part of
@@ -25,7 +25,7 @@ Pacer has a [google group](http://groups.google.com/group/pacer-users?lnk=gcimv)
25
25
  Check out the [wiki](https://github.com/pangloss/pacer/wiki) for detailed explanations of many of Pacer's features. Please contribute to it or open issues against it if there is anything missing that you want to see.
26
26
 
27
27
  Pacer is also documented with a comprehensive RSpec test suite and with a
28
- thorough YARD documentation. [Dig in!](http://rubydoc.info/github/pangloss/pacer/develop/frames)
28
+ thorough YARD documentation. [Dig in!](http://www.rubydoc.info/github/pangloss/pacer/master)
29
29
 
30
30
  If you like, you can also use the documentation locally via
31
31
 
data/ext/pom.xml CHANGED
@@ -72,5 +72,8 @@
72
72
  <version>4.11</version>
73
73
  </dependency>
74
74
  </dependencies>
75
+ <properties>
76
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
77
+ </properties>
75
78
  </project>
76
79
 
@@ -2,6 +2,9 @@ package com.xnlogic.pacer.pipes;
2
2
 
3
3
  import com.tinkerpop.pipes.AbstractPipe;
4
4
  import com.tinkerpop.pipes.Pipe;
5
+
6
+ import java.util.Iterator;
7
+ import java.util.NoSuchElementException;
5
8
  import java.util.Queue;
6
9
  import java.util.LinkedList;
7
10
  import java.util.List;
@@ -12,14 +15,21 @@ public class ExpandablePipe<T> extends AbstractPipe<T, T> {
12
15
  private Object metadata;
13
16
  private Object nextMetadata;
14
17
 
15
- private List path;
16
- private List nextPath;
18
+ private List<Object> path;
19
+ private List<Object> nextPath;
17
20
 
18
21
  public ExpandablePipe() {
19
22
  this.queue = new LinkedList<EPTriple>();
23
+
24
+ // By default, initialize this pipe with an empty iterator
25
+ setStarts(new Iterator<T>() {
26
+ public boolean hasNext() {return false;}
27
+ public T next() {throw new NoSuchElementException();}
28
+ public void remove() {}
29
+ });
20
30
  }
21
31
 
22
- public void add(T element, Object metadata, List path) {
32
+ public void add(T element, Object metadata, List<Object> path) {
23
33
  this.queue.add(new EPTriple(element, metadata, path));
24
34
  }
25
35
 
@@ -48,15 +58,16 @@ public class ExpandablePipe<T> extends AbstractPipe<T, T> {
48
58
  return toReturn;
49
59
  }
50
60
 
51
- protected T processNextStart() {
61
+ @SuppressWarnings("unchecked")
62
+ protected T processNextStart() {
52
63
  if (this.queue.isEmpty()) {
53
64
  this.nextMetadata = null;
54
65
  T r = this.starts.next();
55
66
 
56
67
  if (this.pathEnabled && this.starts instanceof Pipe) {
57
- this.nextPath = ((Pipe)this.starts).getCurrentPath();
68
+ this.nextPath = ((Pipe<T, T>)this.starts).getCurrentPath();
58
69
  } else {
59
- this.nextPath = new ArrayList();
70
+ this.nextPath = new ArrayList<Object>();
60
71
  }
61
72
  return r;
62
73
  } else {
@@ -67,8 +78,8 @@ public class ExpandablePipe<T> extends AbstractPipe<T, T> {
67
78
  }
68
79
  }
69
80
 
70
- public List getPathToHere() {
71
- List path = new ArrayList();
81
+ public List<Object> getPathToHere() {
82
+ List<Object> path = new ArrayList<Object>();
72
83
 
73
84
  if (this.path != null) {
74
85
  for (Object p : this.path) {
@@ -82,9 +93,9 @@ public class ExpandablePipe<T> extends AbstractPipe<T, T> {
82
93
  private class EPTriple {
83
94
  public T element;
84
95
  public Object metadata;
85
- public List path;
96
+ public List<Object> path;
86
97
 
87
- public EPTriple(T element, Object metadata, List path) {
98
+ public EPTriple(T element, Object metadata, List<Object> path) {
88
99
  this.element = element;
89
100
  this.metadata = metadata;
90
101
  this.path = path;
@@ -9,19 +9,20 @@ import com.tinkerpop.blueprints.Element;
9
9
  import com.tinkerpop.pipes.AbstractPipe;
10
10
 
11
11
  public class IdCollectionFilterPipe<E extends Element> extends AbstractPipe<E, E> {
12
- private Set ids;
12
+ private Set<Object> ids;
13
13
  private boolean containsIn;
14
14
 
15
15
  // TODO: Consider making this a derived exception. Also, this constructor is the reverse of the Ruby one. Is this ok?
16
16
  // Also also, is an Object array the way to go? Can we nail down the type further?
17
- public IdCollectionFilterPipe(final Collection ids, final Contains comparison) throws RuntimeException {
17
+ @SuppressWarnings("unchecked")
18
+ public IdCollectionFilterPipe(final Collection<?> ids, final Contains comparison) throws RuntimeException {
18
19
  super();
19
20
  if (ids instanceof Set) {
20
- this.ids = (Set)ids;
21
+ this.ids = (Set<Object>)ids;
21
22
  } else if (ids == null) {
22
- this.ids = new HashSet();
23
+ this.ids = new HashSet<Object>();
23
24
  } else {
24
- this.ids = new HashSet();
25
+ this.ids = new HashSet<Object>();
25
26
  this.ids.addAll(ids);
26
27
  }
27
28
  if (comparison == Contains.IN)
@@ -1,15 +1,13 @@
1
1
  package com.xnlogic.pacer.pipes;
2
2
 
3
- import java.util.NoSuchElementException;
3
+ import java.util.LinkedHashSet;
4
+ import java.util.Set;
4
5
 
5
6
  import com.tinkerpop.pipes.AbstractPipe;
6
- import com.tinkerpop.pipes.filter.DuplicateFilterPipe;
7
- import com.tinkerpop.pipes.util.iterators.ExpandableIterator;
8
7
 
9
8
  public class IsUniquePipe<T> extends AbstractPipe<T, T> {
10
9
  private boolean unique;
11
- private ExpandableIterator<T> expando;
12
- private DuplicateFilterPipe<T> uniquePipe;
10
+ private Set<T> historySet;
13
11
 
14
12
  public IsUniquePipe() {
15
13
  super();
@@ -18,10 +16,8 @@ public class IsUniquePipe<T> extends AbstractPipe<T, T> {
18
16
 
19
17
  protected T processNextStart() {
20
18
  T value = this.starts.next();
21
-
22
19
  if (this.unique)
23
20
  this.checkUniqueness(value);
24
-
25
21
  return value;
26
22
  }
27
23
 
@@ -39,20 +35,14 @@ public class IsUniquePipe<T> extends AbstractPipe<T, T> {
39
35
  }
40
36
 
41
37
  protected void checkUniqueness(T value) {
42
- try {
43
- this.expando.add(value);
44
- this.uniquePipe.next();
45
- } catch (NoSuchElementException nsee) {
38
+ if (!this.historySet.add(value)) {
46
39
  this.unique = false;
47
- this.uniquePipe = null;
48
- this.expando = null;
40
+ this.historySet = null;
49
41
  }
50
42
  }
51
43
 
52
44
  protected void prepareState() {
45
+ this.historySet = new LinkedHashSet<T>();
53
46
  this.unique = true;
54
- this.expando = new ExpandableIterator<T>();
55
- this.uniquePipe = new DuplicateFilterPipe<T>();
56
- this.uniquePipe.setStarts(this.expando);
57
47
  }
58
48
  }
@@ -1,29 +1,26 @@
1
1
  package com.xnlogic.pacer.pipes;
2
2
 
3
- import static org.junit.Assert.*;
4
- import org.junit.Test;
5
- import java.util.Arrays;
3
+ import static org.junit.Assert.assertNull;
4
+ import static org.junit.Assert.assertTrue;
5
+
6
6
  import java.util.ArrayList;
7
- import com.tinkerpop.pipes.Pipe;
8
- import com.tinkerpop.pipes.IdentityPipe;
9
- import com.tinkerpop.pipes.AbstractPipe;
10
- import java.util.Iterator;
11
- import com.xnlogic.pacer.pipes.ExpandablePipe;
7
+
8
+ import org.junit.Test;
12
9
 
13
10
  public class ExpandablePipeTest {
14
11
 
15
12
  @Test
16
13
  public void queueWithElementsTest() {
17
- ExpandablePipe expandablePipe = new ExpandablePipe();
14
+ ExpandablePipe<String> expandablePipe = new ExpandablePipe<String>();
18
15
 
19
- ArrayList input = new ArrayList();
16
+ ArrayList<String> input = new ArrayList<String>();
20
17
  input.add("X");
21
18
 
22
19
  expandablePipe.setStarts(input.iterator());
23
20
 
24
- expandablePipe.add("a", 1, new ArrayList());
25
- expandablePipe.add("b", 2, new ArrayList());
26
- expandablePipe.add("c", 3, new ArrayList());
21
+ expandablePipe.add("a", 1, new ArrayList<Object>());
22
+ expandablePipe.add("b", 2, new ArrayList<Object>());
23
+ expandablePipe.add("c", 3, new ArrayList<Object>());
27
24
 
28
25
  Object result = expandablePipe.next();
29
26
  assertTrue(result.equals("a"));
@@ -20,6 +20,7 @@ public class LabelCollectionFilterPipeTest {
20
20
  @Before
21
21
  public void setup() throws Exception {
22
22
  this.graph = new TinkerGraph();
23
+ createEdges();
23
24
  }
24
25
 
25
26
  @After
@@ -42,53 +43,67 @@ public class LabelCollectionFilterPipeTest {
42
43
  this.edges = Arrays.asList(e1, e2, e3, e4);
43
44
  }
44
45
 
45
- @Test(expected=NoSuchElementException.class)
46
- public void hasSomeMatchingEdgesTest() {
47
- this.createEdges();
48
- Collection<String> edgeLabels = Arrays.asList("edge2", "edge3");
46
+
47
+
48
+ private LabelCollectionFilterPipe initPipeAndConsumeSomeItems(Collection<String> edgeLabels, int itemsToConsume) {
49
49
  LabelCollectionFilterPipe labelCollectionFilterPipe = new LabelCollectionFilterPipe(edgeLabels);
50
-
51
50
  labelCollectionFilterPipe.setStarts(this.edges);
52
- Edge e = labelCollectionFilterPipe.next();
53
- assertEquals("E2", e.getId());
54
51
 
55
- e = labelCollectionFilterPipe.next();
56
- assertEquals("E3", e.getId());
57
-
58
- labelCollectionFilterPipe.next();
52
+ for (int i = 0; i < itemsToConsume; i++) {
53
+ labelCollectionFilterPipe.next();
54
+ }
55
+
56
+ return labelCollectionFilterPipe;
59
57
  }
60
58
 
61
59
 
60
+
61
+ @Test
62
+ public void hasSomeMatchingEdgesTest() {
63
+ LabelCollectionFilterPipe pipe = initPipeAndConsumeSomeItems(Arrays.asList("edge2", "edge3"), 0);
64
+ assertEquals("E2", pipe.next().getId());
65
+ }
66
+
67
+ @Test
68
+ public void hasSomeMatchingEdgesTest2() {
69
+ LabelCollectionFilterPipe pipe = initPipeAndConsumeSomeItems(Arrays.asList("edge2", "edge3"), 1);
70
+ assertEquals("E3", pipe.next().getId());
71
+ }
72
+
62
73
  @Test(expected=NoSuchElementException.class)
74
+ public void hasSomeMatchingEdgesTest3() {
75
+ LabelCollectionFilterPipe pipe = initPipeAndConsumeSomeItems(Arrays.asList("edge2", "edge3"), 2);
76
+ pipe.next();
77
+ }
78
+
79
+
80
+ @Test
63
81
  public void hasSomeMatchingEdgesWithSetTest() {
64
- this.createEdges();
65
- HashSet<String> edgeLabels = new HashSet<String>(Arrays.asList("edge2", "edge3"));
66
- LabelCollectionFilterPipe labelCollectionFilterPipe = new LabelCollectionFilterPipe(edgeLabels);
67
-
68
- labelCollectionFilterPipe.setStarts(this.edges);
69
- Edge e = labelCollectionFilterPipe.next();
70
- assertEquals("E2", e.getId());
71
-
72
- e = labelCollectionFilterPipe.next();
73
- assertEquals("E3", e.getId());
74
-
75
- labelCollectionFilterPipe.next();
82
+ LabelCollectionFilterPipe pipe = initPipeAndConsumeSomeItems(new HashSet<String>(Arrays.asList("edge2", "edge3")), 0);
83
+ assertEquals("E2", pipe.next().getId());
84
+ }
85
+
86
+ @Test
87
+ public void hasSomeMatchingEdgesWithSetTest2() {
88
+ LabelCollectionFilterPipe pipe = initPipeAndConsumeSomeItems(new HashSet<String>(Arrays.asList("edge2", "edge3")), 1);
89
+ assertEquals("E3", pipe.next().getId());
90
+ }
91
+
92
+ @Test(expected=NoSuchElementException.class)
93
+ public void hasSomeMatchingEdgesWithSetTest3() {
94
+ LabelCollectionFilterPipe pipe = initPipeAndConsumeSomeItems(new HashSet<String>(Arrays.asList("edge2", "edge3")), 2);
95
+ pipe.next();
76
96
  }
77
97
 
78
98
  @Test(expected=NoSuchElementException.class)
79
99
  public void hasNoMatchingEdgesTest() {
80
- this.createEdges();
81
- Collection<String> edgeLabels = Arrays.asList("edge5", "edge6");
82
- LabelCollectionFilterPipe labelCollectionFilterPipe = new LabelCollectionFilterPipe(edgeLabels);
83
-
84
- labelCollectionFilterPipe.setStarts(this.edges);
85
- labelCollectionFilterPipe.next();
100
+ LabelCollectionFilterPipe pipe = initPipeAndConsumeSomeItems(new HashSet<String>(Arrays.asList("edge5", "edge6")), 0);
101
+ pipe.next();
86
102
  }
87
103
 
88
104
 
89
105
  @Test(expected=NoSuchElementException.class)
90
106
  public void noEdgesToMatchTest() {
91
- this.createEdges();
92
107
  LabelCollectionFilterPipe labelCollectionFilterPipe = new LabelCollectionFilterPipe(null);
93
108
 
94
109
  labelCollectionFilterPipe.setStarts(this.edges);
@@ -656,7 +656,6 @@ HELP
656
656
  end
657
657
  expando = Pacer::Pipes::ExpandablePipe.new
658
658
  expando.enablePath true
659
- expando.setStarts(Pacer::Pipes::EmptyIterator::INSTANCE)
660
659
  pipe.setStarts expando
661
660
  if preconfig
662
661
  pipe = preconfig.instance pipe, graph
@@ -8,7 +8,7 @@ module Pacer
8
8
  def all(opts = {}, &block)
9
9
  if opts[:include_self]
10
10
  branch do |this|
11
- this
11
+ this.identity
12
12
  end.branch do |this|
13
13
  this.java_loop(opts, &block)
14
14
  end.merge_exhaustive
@@ -24,6 +24,7 @@ module Pacer
24
24
  import com.tinkerpop.pipes.branch.LoopPipe
25
25
 
26
26
  attr_reader :looping_route
27
+ attr_accessor :include_self
27
28
 
28
29
  def looping_route=(route)
29
30
  if route.is_a? Proc
@@ -212,8 +212,6 @@ HELP
212
212
 
213
213
  def expandable(route = nil)
214
214
  expando = Pacer::Pipes::ExpandablePipe.new
215
- empty = java.util.ArrayList.new
216
- expando.setStarts empty.iterator
217
215
  if route
218
216
  control_pipe = Pacer::Route.pipeline route
219
217
  control_pipe.setStarts expando
@@ -156,21 +156,6 @@ module Pacer
156
156
  end
157
157
  end
158
158
 
159
- def visitAndNode(node)
160
- a = comparable_pipe node.first_node.accept(self)
161
- b = comparable_pipe node.second_node.accept(self)
162
-
163
- if a.pipe == AndFilterPipe and b.pipe == AndFilterPipe
164
- Pipe.new AndFilterPipe, *a.args, *b.args
165
- elsif a.pipe == AndFilterPipe
166
- Pipe.new AndFilterPipe, *a.args, b
167
- elsif b.pipe == AndFilterPipe
168
- Pipe.new AndFilterPipe, a, *b.args
169
- else
170
- Pipe.new AndFilterPipe, a, b
171
- end
172
- end
173
-
174
159
  def visitArrayNode(node)
175
160
  Value.new Value.new(node.child_nodes.map { |n| n.accept self }).values!
176
161
  end
@@ -246,19 +231,12 @@ module Pacer
246
231
  Value.new nil
247
232
  end
248
233
 
249
- def visitOrNode(node)
250
- a = comparable_pipe node.first_node.accept(self)
251
- b = comparable_pipe node.second_node.accept(self)
234
+ def visitAndNode(node)
235
+ visit_and_or(AndFilterPipe, node)
236
+ end
252
237
 
253
- if a.pipe == OrFilterPipe and b.pipe == OrFilterPipe
254
- Pipe.new OrFilterPipe, *a.args, *b.args
255
- elsif a.pipe == OrFilterPipe
256
- Pipe.new OrFilterPipe, *a.args, b
257
- elsif b.pipe == OrFilterPipe
258
- Pipe.new OrFilterPipe, a, *b.args
259
- else
260
- Pipe.new OrFilterPipe, a, b
261
- end
238
+ def visitOrNode(node)
239
+ visit_and_or(OrFilterPipe, node)
262
240
  end
263
241
 
264
242
  def visitRootNode(node)
@@ -308,6 +286,22 @@ module Pacer
308
286
  def visitZArrayNode(node)
309
287
  Value.new []
310
288
  end
289
+
290
+ private
291
+
292
+ def visit_and_or(pipe_class, node)
293
+ a = comparable_pipe node.first_node.accept(self)
294
+ b = comparable_pipe node.second_node.accept(self)
295
+ if a.pipe == pipe_class and b.pipe == pipe_class
296
+ Pipe.new pipe_class, *a.args, *b.args
297
+ elsif a.pipe == pipe_class
298
+ Pipe.new pipe_class, *a.args, b
299
+ elsif b.pipe == pipe_class
300
+ Pipe.new pipe_class, a, *b.args
301
+ else
302
+ Pipe.new pipe_class, a, b
303
+ end
304
+ end
311
305
  end
312
306
  end
313
307
  end
@@ -39,7 +39,13 @@ module Pacer
39
39
  # nesting: false -- (default) raise an exception instead of starting a nested transaction
40
40
  def transaction(opts = {})
41
41
  commit, rollback = start_transaction! opts
42
+ tx_depth = nil
42
43
  begin
44
+ if Pacer.verbose == :very
45
+ tx_depth = threadlocal_graph_info[:dx_depth]
46
+ puts "--#{self.class.name} transaction #{ tx_depth } --> "
47
+ puts caller[0,3]
48
+ end
43
49
  r = yield commit, rollback
44
50
  commit.call(false)
45
51
  r
@@ -47,6 +53,7 @@ module Pacer
47
53
  rollback.call e.message
48
54
  raise
49
55
  ensure
56
+ puts "--#{self.class.name} #{ tx_depth } <-- " if Pacer.verbose == :very
50
57
  finish_transaction!
51
58
  end
52
59
  end
@@ -156,6 +163,8 @@ module Pacer
156
163
  end
157
164
 
158
165
  # NOTE pacer-orient reimplements this
166
+ # A better name for this would be "create_real_transaction", vs. the other finalizers which are all mock transactions in the default
167
+ # implementation.
159
168
  def base_tx_finalizers
160
169
  tx_id = threadlocal_graph_info[:tx_id] = rand
161
170
  commit = ->(reopen = true) do
@@ -10,8 +10,6 @@ module Pacer::Pipes
10
10
  @wrapper = Pacer::Wrappers::WrapperSelector.build graph
11
11
 
12
12
  @expando = ExpandablePipe.new
13
- empty = ArrayList.new
14
- @expando.setStarts empty.iterator
15
13
  looping_pipe.setStarts(@expando)
16
14
  if control_block.arity < 0 or control_block.arity > 2
17
15
  @yield_paths = true
@@ -43,8 +41,7 @@ module Pacer::Pipes
43
41
 
44
42
  def processNextStart
45
43
  while true
46
- has_next = looping_pipe.hasNext
47
- if has_next
44
+ if looping_pipe.hasNext
48
45
  element = looping_pipe.next
49
46
  depth = (expando.metadata || 0) + 1
50
47
  self.next_path = looping_pipe.getCurrentPath if pathEnabled
@@ -1,18 +1,53 @@
1
1
  module Pacer
2
2
  module Routes
3
3
  module RouteOperations
4
+ # Set operations on sections like intersect_sections, difference_sections, etc. allow a route to do things like produce a stream of the set of
5
+ # employees who worked in multiple groups within a compnay, in a single traversal. To take that example further, imagine that we define the
6
+ # following traversals:
7
+ #
8
+ # company.groups.employees
9
+ #
10
+ # Give me all of the employees who have worked in every group in the company:
11
+ #
12
+ # company.groups.as(:g).employees.intersect_sections(:g)
13
+ #
14
+ # To understand how this works, we can think about the underlying structure of the graph, with a company with 2 groups which share employee e2
15
+ # and also have their own employees:
16
+ #
17
+ # (c)--->(g1)=--->(e1)
18
+ # | '-->(e2)
19
+ # | /
20
+ # | .---`
21
+ # '---(g2)=--->(e3)
22
+ #
23
+ # The simple route company.groups.employees.paths will produce:
24
+ # [c, g1, e1]
25
+ # [c, g1, e2]
26
+ # [c, g2, e2]
27
+ # [c, g2, e3]
28
+ #
29
+ # By adding a section to the groups with groups.as(:section_name), we set up the mechanism allowing us to respond to the event when the group in
30
+ # the path changes in subsequent stages of the route. That is what .intersect_sections(:section_name) does. It can conceptually keep a set of
31
+ # employees from each group and then when the source data has been exhausted, it can do a set intersection on those groups, then use the
32
+ # resulting set as its source of resulting data.
33
+ #
4
34
  def intersect_sections(section)
5
35
  chain_route transform: Pacer::Transform::IntersectSections, section: section, operation: :intersection
6
36
  end
7
37
 
38
+ # See details on intersect_section. Emits only elements that are not in other sections.
8
39
  def difference_sections(section)
9
40
  chain_route transform: Pacer::Transform::IntersectSections, section: section, operation: :difference
10
41
  end
11
42
 
43
+ # See details on intersect_section. Emits only elements that are in the first section and not in any subsequent ones.
12
44
  def left_difference_sections(section)
13
45
  chain_route transform: Pacer::Transform::IntersectSections, section: section, operation: :left_difference
14
46
  end
15
47
 
48
+ # See details on intersect_section. Emits only elements that are in the last section and not in the right difference of the previous section.
49
+ #
50
+ # This one can be confusing if you've got more than 2 sections...
16
51
  def right_difference_sections(section)
17
52
  chain_route transform: Pacer::Transform::IntersectSections, section: section, operation: :right_difference
18
53
  end
data/lib/pacer/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  module Pacer
2
- VERSION = "2.0.12"
2
+ VERSION = "2.0.13"
3
3
  # Clients may optionally define the following constants in the Pacer namespace:
4
4
  # - LOAD_JARS : set to false to manage jar loading in the client. Be sure to load the jars defined in JARFILES.
5
5
  # - LOCKJAR_LOCK_OPTS : set some options to be passed to LockJar.lock (ie. :lockfile, :download_artifacts, :local_repo)
@@ -102,7 +102,7 @@ module Pacer::Wrappers
102
102
  end
103
103
 
104
104
  def as?(*exts)
105
- has_exts = extensions_missing(exts).all? do |ext|
105
+ extensions_missing(exts).all? do |ext|
106
106
  rc = if ext.respond_to? :route_conditions
107
107
  ext.route_conditions(graph)
108
108
  elsif ext.respond_to? :lookup
data/lib/pacer-ext.jar CHANGED
Binary file
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pacer
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.12
4
+ version: 2.0.13
5
5
  platform: java
6
6
  authors:
7
7
  - Darrick Wiebe
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-01-09 00:00:00.000000000 Z
11
+ date: 2015-03-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: lock_jar