You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pig.apache.org by ga...@apache.org on 2008/03/19 05:45:49 UTC
svn commit: r638706 - in /incubator/pig/branches/types: ./ lib/
src/org/apache/pig/impl/logicalLayer/schema/ src/org/apache/pig/impl/plan/
test/org/apache/pig/test/
Author: gates
Date: Tue Mar 18 21:45:46 2008
New Revision: 638706
URL: http://svn.apache.org/viewvc?rev=638706&view=rev
Log:
Moved OperatorPlan off of Apache Commons MultiValueMap to local implementation of MultiMap. This was necessary so that OperatorPlan could implement Serializable.
Added:
incubator/pig/branches/types/src/org/apache/pig/impl/plan/MultiMap.java
Removed:
incubator/pig/branches/types/lib/commons-collections-3.2.jar
Modified:
incubator/pig/branches/types/build.xml
incubator/pig/branches/types/src/org/apache/pig/impl/logicalLayer/schema/Schema.java
incubator/pig/branches/types/src/org/apache/pig/impl/plan/OperatorPlan.java
incubator/pig/branches/types/test/org/apache/pig/test/TestOperatorPlan.java
Modified: incubator/pig/branches/types/build.xml
URL: http://svn.apache.org/viewvc/incubator/pig/branches/types/build.xml?rev=638706&r1=638705&r2=638706&view=diff
==============================================================================
--- incubator/pig/branches/types/build.xml (original)
+++ incubator/pig/branches/types/build.xml Tue Mar 18 21:45:46 2008
@@ -132,7 +132,7 @@
</target>
<target name="compile-sources">
- <javac encoding="${build.encoding}" srcdir="${sources}" includes="**/plan/*.java, **/logicalLayer/LogicalPlan.java, **/logicalLayer/LOEval.java, **/logicalLayer/LOSort.java, **/logicalLayer/LOGenerate.java, **/logicalLayer/LOVisitor.java " destdir="${dist}" debug="${javac.debug}" optimize="${javac.optimize}" target="${javac.version}" source="${javac.version}" deprecation="${javac.deprecation}">
+ <javac encoding="${build.encoding}" srcdir="${sources}" includes="**/plan/*.java, **/test/TestOperatorPlan.java, **/logicalLayer/LogicalPlan.java, **/logicalLayer/LOEval.java, **/logicalLayer/LOSort.java, **/logicalLayer/LOGenerate.java, **/logicalLayer/LOVisitor.java, **/logicalLayer/schema/Schema.java " destdir="${dist}" debug="${javac.debug}" optimize="${javac.optimize}" target="${javac.version}" source="${javac.version}" deprecation="${javac.deprecation}">
<compilerarg line="${javac.args} ${javac.args.warnings}" />
<classpath refid="${cp}" />
<!--
Modified: incubator/pig/branches/types/src/org/apache/pig/impl/logicalLayer/schema/Schema.java
URL: http://svn.apache.org/viewvc/incubator/pig/branches/types/src/org/apache/pig/impl/logicalLayer/schema/Schema.java?rev=638706&r1=638705&r2=638706&view=diff
==============================================================================
--- incubator/pig/branches/types/src/org/apache/pig/impl/logicalLayer/schema/Schema.java (original)
+++ incubator/pig/branches/types/src/org/apache/pig/impl/logicalLayer/schema/Schema.java Tue Mar 18 21:45:46 2008
@@ -66,6 +66,18 @@
type = DataType.TUPLE;
schema = s;
}
+
+ @Override
+ public boolean equals(Object other) {
+ if (!(other instanceof FieldSchema)) return false;
+ FieldSchema fs = (FieldSchema)other;
+ // Fields can have different names and still be equal. But
+ // types and schemas (if they're a tuple) must match.
+ if (type != fs.type) return false;
+ if (schema != fs.schema) return false;
+
+ return true;
+ }
}
private List<FieldSchema> mFields;
@@ -152,7 +164,22 @@
if (otherFs.type != DataType.UNKNOWN) ourFs.type = otherFs.type;
if (otherFs.schema != null) ourFs.schema = otherFs.schema;
}
+ }
+ @Override
+ public boolean equals(Object other) {
+ if (!(other instanceof Schema)) return false;
+
+ Schema s = (Schema)other;
+
+ if (s.size() != size()) return false;
+
+ Iterator<FieldSchema> i = mFields.iterator();
+ Iterator<FieldSchema> j = s.mFields.iterator();
+ while (i.hasNext()) {
+ if (!(i.next().equals(j.next()))) return false;
+ }
+ return true;
}
}
Added: incubator/pig/branches/types/src/org/apache/pig/impl/plan/MultiMap.java
URL: http://svn.apache.org/viewvc/incubator/pig/branches/types/src/org/apache/pig/impl/plan/MultiMap.java?rev=638706&view=auto
==============================================================================
--- incubator/pig/branches/types/src/org/apache/pig/impl/plan/MultiMap.java (added)
+++ incubator/pig/branches/types/src/org/apache/pig/impl/plan/MultiMap.java Tue Mar 18 21:45:46 2008
@@ -0,0 +1,109 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.pig.impl.plan;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * An implementation of multi-map. We can't use Apache commons
+ * MultiValueMap because it isn't serializable. And we don't want to use
+ * MultiHashMap, as it is marked deprecated.
+ *
+ * This class can't extend Map, because it needs to change the semantics of
+ * put, so that you give it one key and one value, and it either creates a
+ * new entry with the key and a new collection of value (if the is not yet
+ * in the map) or adds the values to the existing collection for the key
+ * (if the key is already in the map).
+ */
+public class MultiMap<K, V> implements Serializable {
+
+ private HashMap<K, ArrayList<V>> mMap = new HashMap<K, ArrayList<V>>();
+
+ /**
+ * Add an element to the map.
+ * @param key The key to store the value under. If the key already
+ * exists the value will be added to the collection for that key, it
+ * will not replace the existing value (as in a standard map).
+ * @param value value to store.
+ */
+ public void put(K key, V value) {
+ ArrayList<V> list = mMap.get(key);
+ if (list == null) {
+ list = new ArrayList<V>();
+ list.add(value);
+ mMap.put(key, list);
+ } else {
+ list.add(value);
+ }
+ }
+
+ /**
+ * Get the collection of values associated with a given key.
+ * @param key Key to fetch values for.
+ * @return collection of values, or null if the key is not in the map.
+ */
+ public Collection<V> get(K key) {
+ return mMap.get(key);
+ }
+
+ /**
+ * Remove one value from an existing key. If that is the last value
+ * for the key, then remove the key too.
+ * @param key Key to remove the value from.
+ * @param value Value to remove.
+ * @return The value being removed, or null if the key or value does
+ * not exist.
+ */
+ public V remove(K key, V value) {
+ ArrayList<V> list = mMap.get(key);
+ if (list == null) return null;
+
+ Iterator<V> i = list.iterator();
+ V keeper = null;
+ while (i.hasNext()) {
+ keeper = i.next();
+ if (keeper.equals(value)) {
+ i.remove();
+ break;
+ }
+ }
+
+ if (list.size() == 0) {
+ mMap.remove(key);
+ }
+
+ return keeper;
+ }
+
+ /**
+ * Get a set of all the keys in this map.
+ * @return Set of keys.
+ */
+ public Set<K> keySet() {
+ return mMap.keySet();
+ }
+
+
+
+}
Modified: incubator/pig/branches/types/src/org/apache/pig/impl/plan/OperatorPlan.java
URL: http://svn.apache.org/viewvc/incubator/pig/branches/types/src/org/apache/pig/impl/plan/OperatorPlan.java?rev=638706&r1=638705&r2=638706&view=diff
==============================================================================
--- incubator/pig/branches/types/src/org/apache/pig/impl/plan/OperatorPlan.java (original)
+++ incubator/pig/branches/types/src/org/apache/pig/impl/plan/OperatorPlan.java Tue Mar 18 21:45:46 2008
@@ -28,16 +28,16 @@
import org.apache.pig.impl.logicalLayer.OperatorKey;
-import org.apache.commons.collections.map.MultiValueMap;
+//import org.apache.commons.collections.map.MultiValueMap;
/**
* A generic graphing class for use by LogicalPlan, PhysicalPlan, etc.
*/
-public abstract class OperatorPlan<E extends Operator> implements Iterable {
+public abstract class OperatorPlan<E extends Operator> implements Iterable, Serializable {
protected Map<E, OperatorKey> mOps;
protected Map<OperatorKey, E> mKeys;
- protected MultiValueMap mFromEdges;
- protected MultiValueMap mToEdges;
+ protected MultiMap<E, E> mFromEdges;
+ protected MultiMap<E, E> mToEdges;
private List<E> mRoots;
private List<E> mLeaves;
@@ -48,8 +48,8 @@
mLeaves = new ArrayList<E>();
mOps = new HashMap<E, OperatorKey>();
mKeys = new HashMap<OperatorKey, E>();
- mFromEdges = new MultiValueMap();
- mToEdges = new MultiValueMap();
+ mFromEdges = new MultiMap<E, E>();
+ mToEdges = new MultiMap<E, E>();
}
/**
@@ -59,7 +59,7 @@
public List<E> getRoots() {
if (mRoots.size() == 0 && mOps.size() > 0) {
for (E op : mOps.keySet()) {
- if (mToEdges.getCollection(op) == null) {
+ if (mToEdges.get(op) == null) {
mRoots.add(op);
}
}
@@ -74,7 +74,7 @@
public List<E> getLeaves() {
if (mLeaves.size() == 0 && mOps.size() > 0) {
for (E op : mOps.keySet()) {
- if (mFromEdges.getCollection(op) == null) {
+ if (mFromEdges.get(op) == null) {
mLeaves.add(op);
}
}
@@ -130,7 +130,7 @@
// Check to see if the from operator already has outputs, and if so
// whether it supports multiple outputs.
- if (mFromEdges.getCollection(from) != null &&
+ if (mFromEdges.get(from) != null &&
!from.supportsMultipleOutputs()) {
throw new IOException("Attempt to give operator of type " +
from.typeName() + " multiple outputs. This operator does "
@@ -139,7 +139,7 @@
// Check to see if the to operator already has inputs, and if so
// whether it supports multiple inputs.
- if (mToEdges.getCollection(to) != null &&
+ if (mToEdges.get(to) != null &&
!to.supportsMultipleInputs()) {
throw new IOException("Attempt to give operator of type " +
from.typeName() + " multiple inputs. This operator does "
@@ -190,7 +190,7 @@
* @return Collection of nodes.
*/
public List<E> getPredecessors(E op) {
- return (List<E>)mToEdges.getCollection(op);
+ return (List<E>)mToEdges.get(op);
}
@@ -201,7 +201,7 @@
* @return Collection of nodes.
*/
public List<E> getSuccessors(E op) {
- return (List<E>)mFromEdges.getCollection(op);
+ return (List<E>)mFromEdges.get(op);
}
public Iterator<E> iterator() {
@@ -214,12 +214,12 @@
}
private void removeEdges(E op,
- MultiValueMap fromMap,
- MultiValueMap toMap) {
+ MultiMap<E, E> fromMap,
+ MultiMap<E, E> toMap) {
// Find all of the from edges, as I have to remove all the associated to
// edges. Need to make a copy so we can delete from the map without
// screwing up our iterator.
- Collection c = fromMap.getCollection(op);
+ Collection c = fromMap.get(op);
if (c == null) return;
ArrayList al = new ArrayList(c);
Modified: incubator/pig/branches/types/test/org/apache/pig/test/TestOperatorPlan.java
URL: http://svn.apache.org/viewvc/incubator/pig/branches/types/test/org/apache/pig/test/TestOperatorPlan.java?rev=638706&r1=638705&r2=638706&view=diff
==============================================================================
--- incubator/pig/branches/types/test/org/apache/pig/test/TestOperatorPlan.java (original)
+++ incubator/pig/branches/types/test/org/apache/pig/test/TestOperatorPlan.java Tue Mar 18 21:45:46 2008
@@ -105,26 +105,26 @@
}
}
- class TPlan extends OperatorPlan {
+ class TPlan extends OperatorPlan<TOperator> {
public String display() {
StringBuilder buf = new StringBuilder();
buf.append("Nodes: ");
- for (Operator op : mOps.keySet()) {
+ for (TOperator op : mOps.keySet()) {
buf.append(op.name());
buf.append(' ');
}
buf.append("FromEdges: ");
- Iterator i = mFromEdges.keySet().iterator();
+ Iterator<TOperator> i = mFromEdges.keySet().iterator();
while (i.hasNext()) {
- Operator from = (Operator)i.next();
- Iterator j = mFromEdges.iterator(from);
+ TOperator from = i.next();
+ Iterator<TOperator> j = mFromEdges.get(from).iterator();
while (j.hasNext()) {
buf.append(from.name());
buf.append("->");
- buf.append(((Operator)j.next()).name());
+ buf.append(j.next().name());
buf.append(' ');
}
}
@@ -132,12 +132,12 @@
buf.append("ToEdges: ");
i = mToEdges.keySet().iterator();
while (i.hasNext()) {
- Operator from = (Operator)i.next();
- Iterator j = mToEdges.iterator(from);
+ TOperator from = i.next();
+ Iterator<TOperator> j = mToEdges.get(from).iterator();
while (j.hasNext()) {
buf.append(from.name());
buf.append("->");
- buf.append(((Operator)j.next()).name());
+ buf.append(j.next().name());
buf.append(' ');
}
}
@@ -198,21 +198,21 @@
// successors.
TPlan plan = new TPlan();
- Operator[] ops = new Operator[3];
+ TOperator[] ops = new TOperator[3];
for (int i = 0; i < 3; i++) {
ops[i] = new SingleOperator(Integer.toString(i));
plan.add(ops[i]);
}
// All should be roots, as none are connected
- List<Operator> roots = plan.getRoots();
+ List<TOperator> roots = plan.getRoots();
for (int i = 0; i < 3; i++) {
assertTrue("Roots should contain operator " + i,
roots.contains(ops[i]));
}
// All should be leaves, as none are connected
- List<Operator> leaves = plan.getLeaves();
+ List<TOperator> leaves = plan.getLeaves();
for (int i = 0; i < 3; i++) {
assertTrue("Leaves should contain operator " + i,
leaves.contains(ops[i]));
@@ -223,8 +223,8 @@
assertNull(plan.getPredecessors(ops[1]));
// Make sure we find them all when we iterate through them.
- Set<Operator> s = new HashSet<Operator>();
- Iterator<Operator> j = plan.iterator();
+ Set<TOperator> s = new HashSet<TOperator>();
+ Iterator<TOperator> j = plan.iterator();
while (j.hasNext()) {
s.add(j.next());
}
@@ -235,7 +235,7 @@
}
// Test that we can find an operator by its key.
- Operator op = plan.getOperator(new OperatorKey("", 1));
+ TOperator op = plan.getOperator(new OperatorKey("", 1));
assertEquals("Expected to get back ops[1]", ops[1], op);
// Test that we can get an operator key by its operator
@@ -272,7 +272,7 @@
@Test
public void testLinearGraph() throws Exception {
TPlan plan = new TPlan();
- Operator[] ops = new Operator[5];
+ TOperator[] ops = new TOperator[5];
for (int i = 0; i < 5; i++) {
ops[i] = new SingleOperator(Integer.toString(i));
plan.add(ops[i]);
@@ -280,7 +280,7 @@
}
// Test that connecting a node not yet in the plan is detected.
- Operator bogus = new SingleOperator("X");
+ TOperator bogus = new SingleOperator("X");
boolean sawError = false;
try {
plan.connect(ops[2], bogus);
@@ -293,12 +293,12 @@
+ "node that was not in the plan", sawError);
// Get roots should just return ops[0]
- List<Operator> roots = plan.getRoots();
+ List<TOperator> roots = plan.getRoots();
assertEquals(1, roots.size());
assertEquals(roots.get(0), ops[0]);
// Get leaves should just return ops[4]
- List<Operator> leaves = plan.getLeaves();
+ List<TOperator> leaves = plan.getLeaves();
assertEquals(1, leaves.size());
assertEquals(leaves.get(0), ops[4]);
@@ -344,7 +344,7 @@
i = p.iterator();
assertEquals(ops[0], i.next());
- assertEquals("Nodes: 2 1 4 0 3 FromEdges: 2->3 1->2 0->1 3->4 ToEdges: 2->1 1->0 4->3 3->2 ", plan.display());
+ assertEquals("Nodes: 2 0 1 3 4 FromEdges: 2->3 0->1 1->2 3->4 ToEdges: 2->1 1->0 3->2 4->3 ", plan.display());
// Visit it depth first
TVisitor visitor = new TDepthVisitor(plan);
@@ -358,17 +358,17 @@
// Test disconnect
plan.disconnect(ops[2], ops[3]);
- assertEquals("Nodes: 2 1 4 0 3 FromEdges: 1->2 0->1 3->4 ToEdges: 2->1 1->0 4->3 ", plan.display());
+ assertEquals("Nodes: 2 0 1 3 4 FromEdges: 0->1 1->2 3->4 ToEdges: 2->1 1->0 4->3 ", plan.display());
// Test remove
plan.remove(ops[1]);
- assertEquals("Nodes: 2 4 0 3 FromEdges: 3->4 ToEdges: 4->3 ", plan.display());
+ assertEquals("Nodes: 2 0 3 4 FromEdges: 3->4 ToEdges: 4->3 ", plan.display());
}
@Test
public void testDAG() throws Exception {
TPlan plan = new TPlan();
- Operator[] ops = new Operator[6];
+ TOperator[] ops = new TOperator[6];
for (int i = 0; i < 6; i++) {
ops[i] = new MultiOperator(Integer.toString(i));
plan.add(ops[i]);
@@ -380,30 +380,30 @@
plan.connect(ops[3], ops[5]);
// Get roots should return ops[0] and ops[1]
- List<Operator> roots = plan.getRoots();
+ List<TOperator> roots = plan.getRoots();
assertEquals(2, roots.size());
assertTrue(roots.contains(ops[0]));
assertTrue(roots.contains(ops[1]));
// Get leaves should return ops[4] and ops[5]
- List<Operator> leaves = plan.getLeaves();
+ List<TOperator> leaves = plan.getLeaves();
assertEquals(2, leaves.size());
assertTrue(leaves.contains(ops[4]));
assertTrue(leaves.contains(ops[5]));
// Successor for ops[3] should be ops[4] and ops[5]
- List<Operator> s = new ArrayList<Operator>(plan.getSuccessors(ops[3]));
+ List<TOperator> s = new ArrayList<TOperator>(plan.getSuccessors(ops[3]));
assertEquals(2, s.size());
assertTrue(s.contains(ops[4]));
assertTrue(s.contains(ops[5]));
// Predecessor for ops[2] should be ops[0] and ops[1]
- s = new ArrayList<Operator>(plan.getPredecessors(ops[2]));
+ s = new ArrayList<TOperator>(plan.getPredecessors(ops[2]));
assertEquals(2, s.size());
assertTrue(s.contains(ops[0]));
assertTrue(s.contains(ops[1]));
- assertEquals("Nodes: 0 3 5 1 4 2 FromEdges: 0->2 3->4 3->5 1->2 2->3 ToEdges: 3->2 5->3 4->3 2->0 2->1 ", plan.display());
+ assertEquals("Nodes: 4 5 0 2 1 3 FromEdges: 0->2 2->3 1->2 3->4 3->5 ToEdges: 4->3 5->3 2->0 2->1 3->2 ", plan.display());
// Visit it depth first
TVisitor visitor = new TDepthVisitor(plan);
@@ -413,15 +413,15 @@
// Visit it dependency order
visitor = new TDependVisitor(plan);
visitor.visit();
- assertEquals("0 1 2 3 5 4 ", visitor.getJournal());
+ assertEquals("0 1 2 3 4 5 ", visitor.getJournal());
// Test disconnect
plan.disconnect(ops[2], ops[3]);
- assertEquals("Nodes: 0 3 5 1 4 2 FromEdges: 0->2 3->4 3->5 1->2 ToEdges: 5->3 4->3 2->0 2->1 ", plan.display());
+ assertEquals("Nodes: 4 5 0 2 1 3 FromEdges: 0->2 1->2 3->4 3->5 ToEdges: 4->3 5->3 2->0 2->1 ", plan.display());
// Test remove
plan.remove(ops[2]);
- assertEquals("Nodes: 0 3 5 1 4 FromEdges: 3->4 3->5 ToEdges: 5->3 4->3 ", plan.display());
+ assertEquals("Nodes: 4 5 0 1 3 FromEdges: 3->4 3->5 ToEdges: 4->3 5->3 ", plan.display());
}