You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@giraph.apache.org by rv...@apache.org on 2014/10/26 02:22:15 UTC
[32/47] GIRAPH-938: Allow fast working with primitives generically
(ikabiljo via pavanka)
http://git-wip-us.apache.org/repos/asf/giraph/blob/18520570/giraph-core/src/main/java/org/apache/giraph/types/ops/collections/BasicArrayList.java
----------------------------------------------------------------------
diff --git a/giraph-core/src/main/java/org/apache/giraph/types/ops/collections/BasicArrayList.java b/giraph-core/src/main/java/org/apache/giraph/types/ops/collections/BasicArrayList.java
new file mode 100644
index 0000000..df5ca24
--- /dev/null
+++ b/giraph-core/src/main/java/org/apache/giraph/types/ops/collections/BasicArrayList.java
@@ -0,0 +1,632 @@
+/*
+ * 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.giraph.types.ops.collections;
+
+import it.unimi.dsi.fastutil.booleans.BooleanArrayList;
+import it.unimi.dsi.fastutil.bytes.ByteArrayList;
+import it.unimi.dsi.fastutil.doubles.DoubleArrayList;
+import it.unimi.dsi.fastutil.floats.FloatArrayList;
+import it.unimi.dsi.fastutil.ints.IntArrayList;
+import it.unimi.dsi.fastutil.longs.LongArrayList;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+import java.util.NoSuchElementException;
+
+import org.apache.giraph.types.ops.BooleanTypeOps;
+import org.apache.giraph.types.ops.ByteTypeOps;
+import org.apache.giraph.types.ops.DoubleTypeOps;
+import org.apache.giraph.types.ops.FloatTypeOps;
+import org.apache.giraph.types.ops.IntTypeOps;
+import org.apache.giraph.types.ops.LongTypeOps;
+import org.apache.giraph.types.ops.PrimitiveTypeOps;
+import org.apache.hadoop.io.BooleanWritable;
+import org.apache.hadoop.io.ByteWritable;
+import org.apache.hadoop.io.DoubleWritable;
+import org.apache.hadoop.io.FloatWritable;
+import org.apache.hadoop.io.IntWritable;
+import org.apache.hadoop.io.LongWritable;
+import org.apache.hadoop.io.Writable;
+
+/**
+ * BasicArrayList with only basic set of operations.
+ *
+ * @param <T> Element type
+ */
+public abstract class BasicArrayList<T> implements Writable {
+ /** Removes all of the elements from this list. */
+ public abstract void clear();
+ /**
+ * Number of elements in this list
+ * @return size
+ */
+ public abstract int size();
+ /**
+ * Capacity of currently allocated memory
+ * @return capacity
+ */
+ public abstract int capacity();
+ /**
+ * Forces allocated memory to hold exactly N values
+ * @param n new capacity
+ */
+ public abstract void setCapacity(int n);
+ /**
+ * Add value to the end of the array
+ * @param value Value
+ */
+ public abstract void add(T value);
+ /**
+ * Pop value from the end of the array, storing it into 'to' argument
+ * @param to Object to store value into
+ */
+ public abstract void popInto(T to);
+ /**
+ * Get element at given index in the array, storing it into 'to' argument
+ * @param index Index
+ * @param to Object to store value into
+ */
+ public abstract void getInto(int index, T to);
+ /**
+ * Set element at given index in the array
+ * @param index Index
+ * @param value Value
+ */
+ public abstract void set(int index, T value);
+
+ /**
+ * TypeOps for type of elements this object holds
+ * @return TypeOps
+ */
+ public abstract PrimitiveTypeOps<T> getElementTypeOps();
+
+ /**
+ * Fast iterator over BasicArrayList object, which doesn't allocate new
+ * element for each returned element, and can be iterated multiple times
+ * using reset().
+ *
+ * Object returned by next() is only valid until next() is called again,
+ * because it is reused.
+ *
+ * @return RessettableIterator
+ */
+ public ResettableIterator<T> fastIterator() {
+ return new ResettableIterator<T>() {
+ private final T value = getElementTypeOps().create();
+ private int pos;
+
+ @Override
+ public boolean hasNext() {
+ return pos < size();
+ }
+
+ @Override
+ public T next() {
+ if (!hasNext()) {
+ throw new NoSuchElementException();
+ }
+ getInto(pos, value);
+ pos++;
+ return value;
+ }
+
+ @Override
+ public void reset() {
+ pos = 0;
+ }
+
+ @Override
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+ };
+ }
+
+ /** BooleanWritable implementation of BasicArrayList */
+ public static final class BasicBooleanArrayList
+ extends BasicArrayList<BooleanWritable> {
+ /** List */
+ private final BooleanArrayList list;
+
+ /**
+ * Constructor
+ * @param capacity Capacity
+ */
+ public BasicBooleanArrayList(int capacity) {
+ list = new BooleanArrayList(capacity);
+ }
+
+ @Override
+ public PrimitiveTypeOps<BooleanWritable> getElementTypeOps() {
+ return BooleanTypeOps.INSTANCE;
+ }
+
+ @Override
+ public void clear() {
+ list.clear();
+ }
+
+ @Override
+ public int size() {
+ return list.size();
+ }
+
+ @Override
+ public int capacity() {
+ return list.elements().length;
+ }
+
+ @Override
+ public void setCapacity(int n) {
+ if (n >= list.elements().length) {
+ list.ensureCapacity(n);
+ } else {
+ list.trim(n);
+ }
+ }
+
+ @Override
+ public void add(BooleanWritable value) {
+ list.add(value.get());
+ }
+
+ @Override
+ public void getInto(int index, BooleanWritable to) {
+ to.set(list.getBoolean(index));
+ }
+
+ @Override
+ public void popInto(BooleanWritable to) {
+ to.set(list.popBoolean());
+ }
+
+ @Override
+ public void set(int index, BooleanWritable value) {
+ list.set(index, value.get());
+ }
+
+ @Override
+ public void write(DataOutput out) throws IOException {
+ out.writeInt(list.size());
+ for (int i = 0; i < list.size(); i++) {
+ out.writeBoolean(list.getBoolean(i));
+ }
+ }
+
+ @Override
+ public void readFields(DataInput in) throws IOException {
+ int size = in.readInt();
+ list.clear();
+ setCapacity(size);
+ for (int i = 0; i < size; ++i) {
+ list.add(in.readBoolean());
+ }
+ }
+ }
+
+ /** ByteWritable implementation of BasicArrayList */
+ public static final class BasicByteArrayList
+ extends BasicArrayList<ByteWritable> {
+ /** List */
+ private final ByteArrayList list;
+
+ /**
+ * Constructor
+ * @param capacity Capacity
+ */
+ public BasicByteArrayList(int capacity) {
+ list = new ByteArrayList(capacity);
+ }
+
+ @Override
+ public PrimitiveTypeOps<ByteWritable> getElementTypeOps() {
+ return ByteTypeOps.INSTANCE;
+ }
+
+ @Override
+ public void clear() {
+ list.clear();
+ }
+
+ @Override
+ public int size() {
+ return list.size();
+ }
+
+ @Override
+ public int capacity() {
+ return list.elements().length;
+ }
+
+ @Override
+ public void setCapacity(int n) {
+ if (n >= list.elements().length) {
+ list.ensureCapacity(n);
+ } else {
+ list.trim(n);
+ }
+ }
+
+ @Override
+ public void add(ByteWritable value) {
+ list.add(value.get());
+ }
+
+ @Override
+ public void getInto(int index, ByteWritable to) {
+ to.set(list.getByte(index));
+ }
+
+ @Override
+ public void popInto(ByteWritable to) {
+ to.set(list.popByte());
+ }
+
+ @Override
+ public void set(int index, ByteWritable value) {
+ list.set(index, value.get());
+ }
+
+ @Override
+ public void write(DataOutput out) throws IOException {
+ out.writeInt(list.size());
+ for (int i = 0; i < list.size(); i++) {
+ out.writeByte(list.getByte(i));
+ }
+ }
+
+ @Override
+ public void readFields(DataInput in) throws IOException {
+ int size = in.readInt();
+ list.clear();
+ setCapacity(size);
+ for (int i = 0; i < size; ++i) {
+ list.add(in.readByte());
+ }
+ }
+ }
+
+ /** IntWritable implementation of BasicArrayList */
+ public static final class BasicIntArrayList
+ extends BasicArrayList<IntWritable> {
+ /** List */
+ private final IntArrayList list;
+
+ /**
+ * Constructor
+ * @param capacity Capacity
+ */
+ public BasicIntArrayList(int capacity) {
+ list = new IntArrayList(capacity);
+ }
+
+ @Override
+ public PrimitiveTypeOps<IntWritable> getElementTypeOps() {
+ return IntTypeOps.INSTANCE;
+ }
+
+ @Override
+ public void clear() {
+ list.clear();
+ }
+
+ @Override
+ public int size() {
+ return list.size();
+ }
+
+ @Override
+ public int capacity() {
+ return list.elements().length;
+ }
+
+ @Override
+ public void setCapacity(int n) {
+ if (n >= list.elements().length) {
+ list.ensureCapacity(n);
+ } else {
+ list.trim(n);
+ }
+ }
+
+ @Override
+ public void add(IntWritable value) {
+ list.add(value.get());
+ }
+
+ @Override
+ public void getInto(int index, IntWritable to) {
+ to.set(list.getInt(index));
+ }
+
+ @Override
+ public void popInto(IntWritable to) {
+ to.set(list.popInt());
+ }
+
+ @Override
+ public void set(int index, IntWritable value) {
+ list.set(index, value.get());
+ }
+
+ @Override
+ public void write(DataOutput out) throws IOException {
+ out.writeInt(list.size());
+ for (int i = 0; i < list.size(); i++) {
+ out.writeInt(list.getInt(i));
+ }
+ }
+
+ @Override
+ public void readFields(DataInput in) throws IOException {
+ int size = in.readInt();
+ list.clear();
+ setCapacity(size);
+ for (int i = 0; i < size; ++i) {
+ list.add(in.readInt());
+ }
+ }
+ }
+
+ /** LongWritable implementation of BasicArrayList */
+ public static final class BasicLongArrayList
+ extends BasicArrayList<LongWritable> {
+ /** List */
+ private final LongArrayList list;
+
+ /**
+ * Constructor
+ * @param capacity Capacity
+ */
+ public BasicLongArrayList(int capacity) {
+ list = new LongArrayList(capacity);
+ }
+
+ @Override
+ public PrimitiveTypeOps<LongWritable> getElementTypeOps() {
+ return LongTypeOps.INSTANCE;
+ }
+
+ @Override
+ public void clear() {
+ list.clear();
+ }
+
+ @Override
+ public int size() {
+ return list.size();
+ }
+
+ @Override
+ public int capacity() {
+ return list.elements().length;
+ }
+
+ @Override
+ public void setCapacity(int n) {
+ if (n >= list.elements().length) {
+ list.ensureCapacity(n);
+ } else {
+ list.trim(n);
+ }
+ }
+
+ @Override
+ public void add(LongWritable value) {
+ list.add(value.get());
+ }
+
+ @Override
+ public void getInto(int index, LongWritable to) {
+ to.set(list.getLong(index));
+ }
+
+ @Override
+ public void popInto(LongWritable to) {
+ to.set(list.popLong());
+ }
+
+ @Override
+ public void set(int index, LongWritable value) {
+ list.set(index, value.get());
+ }
+
+ @Override
+ public void write(DataOutput out) throws IOException {
+ out.writeInt(list.size());
+ for (int i = 0; i < list.size(); i++) {
+ out.writeLong(list.getLong(i));
+ }
+ }
+
+ @Override
+ public void readFields(DataInput in) throws IOException {
+ int size = in.readInt();
+ list.clear();
+ setCapacity(size);
+ for (int i = 0; i < size; ++i) {
+ list.add(in.readLong());
+ }
+ }
+ }
+
+ /** FloatWritable implementation of BasicArrayList */
+ public static final class BasicFloatArrayList
+ extends BasicArrayList<FloatWritable> {
+ /** List */
+ private final FloatArrayList list;
+
+ /**
+ * Constructor
+ * @param capacity Capacity
+ */
+ public BasicFloatArrayList(int capacity) {
+ list = new FloatArrayList(capacity);
+ }
+
+ @Override
+ public PrimitiveTypeOps<FloatWritable> getElementTypeOps() {
+ return FloatTypeOps.INSTANCE;
+ }
+
+ @Override
+ public void clear() {
+ list.clear();
+ }
+
+ @Override
+ public int size() {
+ return list.size();
+ }
+
+ @Override
+ public int capacity() {
+ return list.elements().length;
+ }
+
+ @Override
+ public void setCapacity(int n) {
+ if (n >= list.elements().length) {
+ list.ensureCapacity(n);
+ } else {
+ list.trim(n);
+ }
+ }
+
+ @Override
+ public void add(FloatWritable value) {
+ list.add(value.get());
+ }
+
+ @Override
+ public void getInto(int index, FloatWritable to) {
+ to.set(list.getFloat(index));
+ }
+
+ @Override
+ public void popInto(FloatWritable to) {
+ to.set(list.popFloat());
+ }
+
+ @Override
+ public void set(int index, FloatWritable value) {
+ list.set(index, value.get());
+ }
+
+ @Override
+ public void write(DataOutput out) throws IOException {
+ out.writeInt(list.size());
+ for (int i = 0; i < list.size(); i++) {
+ out.writeFloat(list.getFloat(i));
+ }
+ }
+
+ @Override
+ public void readFields(DataInput in) throws IOException {
+ int size = in.readInt();
+ list.clear();
+ setCapacity(size);
+ for (int i = 0; i < size; ++i) {
+ list.add(in.readFloat());
+ }
+ }
+ }
+
+ /** DoubleWritable implementation of BasicArrayList */
+ public static final class BasicDoubleArrayList
+ extends BasicArrayList<DoubleWritable> {
+ /** List */
+ private final DoubleArrayList list;
+
+ /**
+ * Constructor
+ * @param capacity Capacity
+ */
+ public BasicDoubleArrayList(int capacity) {
+ list = new DoubleArrayList(capacity);
+ }
+
+ @Override
+ public PrimitiveTypeOps<DoubleWritable> getElementTypeOps() {
+ return DoubleTypeOps.INSTANCE;
+ }
+
+ @Override
+ public void clear() {
+ list.clear();
+ }
+
+ @Override
+ public int size() {
+ return list.size();
+ }
+
+ @Override
+ public int capacity() {
+ return list.elements().length;
+ }
+
+ @Override
+ public void setCapacity(int n) {
+ if (n >= list.elements().length) {
+ list.ensureCapacity(n);
+ } else {
+ list.trim(n);
+ }
+ }
+
+ @Override
+ public void add(DoubleWritable value) {
+ list.add(value.get());
+ }
+
+ @Override
+ public void getInto(int index, DoubleWritable to) {
+ to.set(list.getDouble(index));
+ }
+
+ @Override
+ public void popInto(DoubleWritable to) {
+ to.set(list.popDouble());
+ }
+
+ @Override
+ public void set(int index, DoubleWritable value) {
+ list.set(index, value.get());
+ }
+
+ @Override
+ public void write(DataOutput out) throws IOException {
+ out.writeInt(list.size());
+ for (int i = 0; i < list.size(); i++) {
+ out.writeDouble(list.getDouble(i));
+ }
+ }
+
+ @Override
+ public void readFields(DataInput in) throws IOException {
+ int size = in.readInt();
+ list.clear();
+ setCapacity(size);
+ for (int i = 0; i < size; ++i) {
+ list.add(in.readDouble());
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/giraph/blob/18520570/giraph-core/src/main/java/org/apache/giraph/types/ops/collections/BasicSet.java
----------------------------------------------------------------------
diff --git a/giraph-core/src/main/java/org/apache/giraph/types/ops/collections/BasicSet.java b/giraph-core/src/main/java/org/apache/giraph/types/ops/collections/BasicSet.java
new file mode 100644
index 0000000..c8cd72e
--- /dev/null
+++ b/giraph-core/src/main/java/org/apache/giraph/types/ops/collections/BasicSet.java
@@ -0,0 +1,206 @@
+/*
+ * 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.giraph.types.ops.collections;
+
+import it.unimi.dsi.fastutil.ints.IntIterator;
+import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
+import it.unimi.dsi.fastutil.longs.LongIterator;
+import it.unimi.dsi.fastutil.longs.LongOpenHashSet;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+
+import org.apache.giraph.types.ops.IntTypeOps;
+import org.apache.giraph.types.ops.LongTypeOps;
+import org.apache.giraph.types.ops.PrimitiveIdTypeOps;
+import org.apache.hadoop.io.IntWritable;
+import org.apache.hadoop.io.LongWritable;
+import org.apache.hadoop.io.Writable;
+
+/**
+ * BasicSet with only basic set of operations.
+ * All operations that return object T are returning reusable object,
+ * which is modified after calling any other function.
+ *
+ * @param <T> Element type
+ */
+public interface BasicSet<T> extends Writable {
+ /** Removes all of the elements from this list. */
+ void clear();
+ /**
+ * Number of elements in this list
+ * @return size
+ */
+ int size();
+ /**
+ * Makes sure set is not using space with capacity more than
+ * max(n,size()) entries.
+ * @param n the threshold for the trimming.
+ */
+ void trim(int n);
+ /**
+ * Adds value to the set.
+ * Returns <tt>true</tt> if set changed as a
+ * result of the call.
+ *
+ * @param value Value to add
+ * @return true if set was changed.
+ */
+ boolean add(T value);
+ /**
+ * Checks whether set contains given value
+ * @param value Value to check
+ * @return true if value is present in the set
+ */
+ boolean contains(T value);
+
+ /**
+ * TypeOps for type of elements this object holds
+ * @return TypeOps
+ */
+ PrimitiveIdTypeOps<T> getElementTypeOps();
+
+ /** IntWritable implementation of BasicSet */
+ public static final class BasicIntOpenHashSet
+ implements BasicSet<IntWritable> {
+ /** Set */
+ private final IntOpenHashSet set;
+
+ /**
+ * Constructor
+ * @param capacity Capacity
+ */
+ public BasicIntOpenHashSet(int capacity) {
+ set = new IntOpenHashSet(capacity);
+ }
+
+ @Override
+ public void clear() {
+ set.clear();
+ }
+
+ @Override
+ public int size() {
+ return set.size();
+ }
+
+ @Override
+ public void trim(int n) {
+ set.trim(Math.max(set.size(), n));
+ }
+
+ @Override
+ public boolean add(IntWritable value) {
+ return set.add(value.get());
+ }
+
+ @Override
+ public boolean contains(IntWritable value) {
+ return set.contains(value.get());
+ }
+
+ @Override
+ public PrimitiveIdTypeOps<IntWritable> getElementTypeOps() {
+ return IntTypeOps.INSTANCE;
+ }
+
+ @Override
+ public void write(DataOutput out) throws IOException {
+ out.writeInt(set.size());
+ IntIterator iter = set.iterator();
+ while (iter.hasNext()) {
+ out.writeInt(iter.nextInt());
+ }
+ }
+
+ @Override
+ public void readFields(DataInput in) throws IOException {
+ int size = in.readInt();
+ set.clear();
+ set.trim(size);
+ for (int i = 0; i < size; ++i) {
+ set.add(in.readInt());
+ }
+ }
+ }
+
+ /** LongWritable implementation of BasicSet */
+ public static final class BasicLongOpenHashSet
+ implements BasicSet<LongWritable> {
+ /** Set */
+ private final LongOpenHashSet set;
+
+ /**
+ * Constructor
+ * @param capacity Capacity
+ */
+ public BasicLongOpenHashSet(int capacity) {
+ set = new LongOpenHashSet(capacity);
+ }
+
+ @Override
+ public void clear() {
+ set.clear();
+ }
+
+ @Override
+ public int size() {
+ return set.size();
+ }
+
+ @Override
+ public void trim(int n) {
+ set.trim(Math.max(set.size(), n));
+ }
+
+ @Override
+ public boolean add(LongWritable value) {
+ return set.add(value.get());
+ }
+
+ @Override
+ public boolean contains(LongWritable value) {
+ return set.contains(value.get());
+ }
+
+ @Override
+ public PrimitiveIdTypeOps<LongWritable> getElementTypeOps() {
+ return LongTypeOps.INSTANCE;
+ }
+
+ @Override
+ public void write(DataOutput out) throws IOException {
+ out.writeInt(set.size());
+ LongIterator iter = set.iterator();
+ while (iter.hasNext()) {
+ out.writeLong(iter.nextLong());
+ }
+ }
+
+ @Override
+ public void readFields(DataInput in) throws IOException {
+ int size = in.readInt();
+ set.clear();
+ trim(size);
+ for (int i = 0; i < size; ++i) {
+ set.add(in.readLong());
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/giraph/blob/18520570/giraph-core/src/main/java/org/apache/giraph/types/ops/collections/ResettableIterator.java
----------------------------------------------------------------------
diff --git a/giraph-core/src/main/java/org/apache/giraph/types/ops/collections/ResettableIterator.java b/giraph-core/src/main/java/org/apache/giraph/types/ops/collections/ResettableIterator.java
new file mode 100644
index 0000000..30e1b21
--- /dev/null
+++ b/giraph-core/src/main/java/org/apache/giraph/types/ops/collections/ResettableIterator.java
@@ -0,0 +1,32 @@
+/*
+ * 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.giraph.types.ops.collections;
+
+import java.util.Iterator;
+
+/**
+ * Defines an iterator that can iterated over multiple times, by
+ * rewinding it via reset() function.
+ *
+ * @param <T> Element type
+ */
+public interface ResettableIterator<T> extends Iterator<T> {
+ /** Rewinds iterator to the beginning. */
+ void reset();
+}
+
http://git-wip-us.apache.org/repos/asf/giraph/blob/18520570/giraph-core/src/main/java/org/apache/giraph/types/ops/collections/WritableWriter.java
----------------------------------------------------------------------
diff --git a/giraph-core/src/main/java/org/apache/giraph/types/ops/collections/WritableWriter.java b/giraph-core/src/main/java/org/apache/giraph/types/ops/collections/WritableWriter.java
new file mode 100644
index 0000000..cd29a56
--- /dev/null
+++ b/giraph-core/src/main/java/org/apache/giraph/types/ops/collections/WritableWriter.java
@@ -0,0 +1,47 @@
+/*
+ * 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.giraph.types.ops.collections;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+
+/**
+ * Handler for knowing how to serialize/deserialize type T
+ *
+ * @param <T> Type of object to be serialized.
+ */
+public interface WritableWriter<T> {
+ /**
+ * Serialize the fields of <code>value</code> to <code>out</code>.
+ *
+ * @param out <code>DataOuput</code> to serialize object into.
+ * @param value Object to serialize
+ * @throws IOException
+ */
+ void write(DataOutput out, T value) throws IOException;
+
+ /**
+ * Deserialize the fields of object from <code>in</code>.
+ *
+ * @param in <code>DataInput</code> to deseriablize object from.
+ * @return Deserialized object.
+ * @throws IOException
+ */
+ T readFields(DataInput in) throws IOException;
+}
http://git-wip-us.apache.org/repos/asf/giraph/blob/18520570/giraph-core/src/main/java/org/apache/giraph/types/ops/collections/package-info.java
----------------------------------------------------------------------
diff --git a/giraph-core/src/main/java/org/apache/giraph/types/ops/collections/package-info.java b/giraph-core/src/main/java/org/apache/giraph/types/ops/collections/package-info.java
new file mode 100644
index 0000000..ae0231e
--- /dev/null
+++ b/giraph-core/src/main/java/org/apache/giraph/types/ops/collections/package-info.java
@@ -0,0 +1,21 @@
+/*
+ * 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.
+ */
+/**
+ * Collection interfaces and implementations provided by TypeOps classes.
+ */
+package org.apache.giraph.types.ops.collections;
http://git-wip-us.apache.org/repos/asf/giraph/blob/18520570/giraph-core/src/main/java/org/apache/giraph/types/ops/package-info.java
----------------------------------------------------------------------
diff --git a/giraph-core/src/main/java/org/apache/giraph/types/ops/package-info.java b/giraph-core/src/main/java/org/apache/giraph/types/ops/package-info.java
new file mode 100644
index 0000000..f656711
--- /dev/null
+++ b/giraph-core/src/main/java/org/apache/giraph/types/ops/package-info.java
@@ -0,0 +1,21 @@
+/*
+ * 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.
+ */
+/**
+ * Type coercion, inference, and reflection.
+ */
+package org.apache.giraph.types.ops;