Merge branch 'wbiesing/genomix/VKmers' into nanzhang/hyracks_genomix

Conflicts:
	genomix/genomix-data/src/main/java/edu/uci/ics/genomix/type/KmerListWritable.java
diff --git a/genomix/genomix-data/src/main/java/edu/uci/ics/genomix/type/NodeWritable.java b/genomix/genomix-data/src/main/java/edu/uci/ics/genomix/type/NodeWritable.java
index 15a6cc9..34dfefe 100644
--- a/genomix/genomix-data/src/main/java/edu/uci/ics/genomix/type/NodeWritable.java
+++ b/genomix/genomix-data/src/main/java/edu/uci/ics/genomix/type/NodeWritable.java
@@ -17,10 +17,10 @@
     public static final NodeWritable EMPTY_NODE = new NodeWritable();
     
     private PositionListWritable nodeIdList;
-    private KmerListWritable forwardForwardList;
-    private KmerListWritable forwardReverseList;
-    private KmerListWritable reverseForwardList;
-    private KmerListWritable reverseReverseList;
+    private VKmerListWritable forwardForwardList;
+    private VKmerListWritable forwardReverseList;
+    private VKmerListWritable reverseForwardList;
+    private VKmerListWritable reverseReverseList;
     private VKmerBytesWritable kmer;
     
     // merge/update directions
@@ -34,15 +34,15 @@
     
     public NodeWritable() {
         nodeIdList = new PositionListWritable();
-        forwardForwardList = new KmerListWritable();
-        forwardReverseList = new KmerListWritable();
-        reverseForwardList = new KmerListWritable();
-        reverseReverseList = new KmerListWritable();
+        forwardForwardList = new VKmerListWritable();
+        forwardReverseList = new VKmerListWritable();
+        reverseForwardList = new VKmerListWritable();
+        reverseReverseList = new VKmerListWritable();
         kmer = new VKmerBytesWritable();  // in graph construction - not set kmerlength Optimization: VKmer
     }
     
-    public NodeWritable(PositionListWritable nodeIdList, KmerListWritable FFList, KmerListWritable FRList,
-            KmerListWritable RFList, KmerListWritable RRList, VKmerBytesWritable kmer) {
+    public NodeWritable(PositionListWritable nodeIdList, VKmerListWritable FFList, VKmerListWritable FRList,
+            VKmerListWritable RFList, VKmerListWritable RRList, VKmerBytesWritable kmer) {
         this();
         set(nodeIdList, FFList, FRList, RFList, RRList, kmer);
     }
@@ -52,8 +52,8 @@
                 node.reverseReverseList, node.kmer);
     }
     
-    public void set(PositionListWritable nodeIdList, KmerListWritable FFList, KmerListWritable FRList,
-            KmerListWritable RFList, KmerListWritable RRList, VKmerBytesWritable kmer2) {
+    public void set(PositionListWritable nodeIdList, VKmerListWritable FFList, VKmerListWritable FRList,
+            VKmerListWritable RFList, VKmerListWritable RRList, VKmerBytesWritable kmer2) {
         this.nodeIdList.set(nodeIdList);
         this.forwardForwardList.setCopy(FFList);
         this.forwardReverseList.setCopy(FRList);
@@ -91,39 +91,39 @@
         return kmer.getKmerLetterLength();
     }
     
-    public KmerListWritable getFFList() {
+    public VKmerListWritable getFFList() {
         return forwardForwardList;
     }
 
-    public KmerListWritable getFRList() {
+    public VKmerListWritable getFRList() {
         return forwardReverseList;
     }
 
-    public KmerListWritable getRFList() {
+    public VKmerListWritable getRFList() {
         return reverseForwardList;
     }
 
-    public KmerListWritable getRRList() {
+    public VKmerListWritable getRRList() {
         return reverseReverseList;
     }
     
-	public void setFFList(KmerListWritable forwardForwardList) {
+	public void setFFList(VKmerListWritable forwardForwardList) {
 		this.forwardForwardList.setCopy(forwardForwardList);
 	}
 
-	public void setFRList(KmerListWritable forwardReverseList) {
+	public void setFRList(VKmerListWritable forwardReverseList) {
 		this.forwardReverseList.setCopy(forwardReverseList);
 	}
 
-	public void setRFList(KmerListWritable reverseForwardList) {
+	public void setRFList(VKmerListWritable reverseForwardList) {
 		this.reverseForwardList.setCopy(reverseForwardList);
 	}
 
-	public void setRRList(KmerListWritable reverseReverseList) {
+	public void setRRList(VKmerListWritable reverseReverseList) {
 		this.reverseReverseList.setCopy(reverseReverseList);
 	}
 
-	public KmerListWritable getListFromDir(byte dir) {
+	public VKmerListWritable getListFromDir(byte dir) {
         switch (dir & DirectionFlag.DIR_MASK) {
             case DirectionFlag.DIR_FF:
                 return getFFList();
diff --git a/genomix/genomix-data/src/main/java/edu/uci/ics/genomix/type/VKmerListWritable.java b/genomix/genomix-data/src/main/java/edu/uci/ics/genomix/type/VKmerListWritable.java
new file mode 100644
index 0000000..620e8ad
--- /dev/null
+++ b/genomix/genomix-data/src/main/java/edu/uci/ics/genomix/type/VKmerListWritable.java
@@ -0,0 +1,310 @@
+package edu.uci.ics.genomix.type;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+import java.io.Serializable;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.hadoop.io.Writable;
+
+import edu.uci.ics.genomix.data.KmerUtil;
+import edu.uci.ics.genomix.data.Marshal;
+
+/**
+ * A list of fixed-length kmers. The length of this list is stored internally.
+ */
+public class VKmerListWritable implements Writable, Iterable<VKmerBytesWritable>, Serializable {
+    private static final long serialVersionUID = 1L;
+    protected static final byte[] EMPTY_BYTES = { 0, 0, 0, 0 };
+    protected static final int HEADER_SIZE = 4;
+
+    protected byte[] storage;
+    protected int offset;
+    protected int valueCount;
+    protected int storageMaxSize;  // since we may be a reference inside a larger datablock, we must track our maximum size
+
+    private VKmerBytesWritable posIter = new VKmerBytesWritable();
+
+    public VKmerListWritable() {
+        storage = EMPTY_BYTES;
+        valueCount = 0;
+        offset = 0;
+        storageMaxSize = storage.length; 
+    }
+
+    public VKmerListWritable(byte[] data, int offset) {
+        setNewReference(data, offset);
+    }
+
+    public VKmerListWritable(List<VKmerBytesWritable> kmers) {
+        this();
+        for (VKmerBytesWritable kmer : kmers) {
+            append(kmer);
+        }
+    }
+
+    public void setNewReference(byte[] data, int offset) {
+        valueCount = Marshal.getInt(data, offset);
+        this.storage = data;
+        this.offset = offset;
+        this.storageMaxSize = getLength();
+    }
+
+    public void append(VKmerBytesWritable kmer) {
+        setSize(getLength() + kmer.getLength());
+        System.arraycopy(kmer.getBytes(), kmer.kmerStartOffset - VKmerBytesWritable.HEADER_SIZE,
+                storage, offset + getLength(), 
+                kmer.getLength());
+        valueCount += 1;
+        Marshal.putInt(valueCount, storage, offset);
+    }
+
+    /*
+     * Append the otherList to the end of myList
+     */
+    public void appendList(VKmerListWritable otherList) {
+        if (otherList.valueCount > 0) {
+            setSize(getLength() + otherList.getLength() - HEADER_SIZE); // one of the headers is redundant
+            
+            // copy contents of otherList into the end of my storage
+            System.arraycopy(otherList.storage, otherList.offset + HEADER_SIZE, // skip other header
+                    storage, offset + getLength(), // add to end
+                    otherList.getLength() - HEADER_SIZE);
+            valueCount += otherList.valueCount;
+            Marshal.putInt(valueCount, storage, offset);
+        }
+    }
+
+    /**
+     * Save the union of my list and otherList. Uses a temporary HashSet for
+     * uniquefication
+     */
+    public void unionUpdate(VKmerListWritable otherList) {
+        int newSize = valueCount + otherList.valueCount;
+        HashSet<VKmerBytesWritable> uniqueElements = new HashSet<VKmerBytesWritable>(newSize);
+        for (VKmerBytesWritable kmer : this) {
+            // have to make copies of my own kmers since I may overwrite them
+            uniqueElements.add(new VKmerBytesWritable(kmer));
+        }
+        for (VKmerBytesWritable kmer : otherList) {
+            uniqueElements.add(kmer); // references okay
+        }
+        setSize(getLength() + otherList.getLength());  // upper bound on memory usage
+        valueCount = 0;
+        for (VKmerBytesWritable kmer : uniqueElements) {
+            append(kmer);
+        }
+        Marshal.putInt(valueCount, storage, offset);
+    }
+
+    protected void setSize(int size) {
+        if (size > getCapacity()) {
+            setCapacity((size * 3 / 2));
+        }
+    }
+
+    protected int getCapacity() {
+        return storageMaxSize - offset;
+    }
+
+    protected void setCapacity(int new_cap) {
+        if (new_cap > getCapacity()) {
+            byte[] new_data = new byte[new_cap];
+            if (valueCount > 0) {
+                System.arraycopy(storage, offset, new_data, 0, getLength());
+            }
+            storage = new_data;
+            offset = 0;
+            storageMaxSize = storage.length;
+        }
+    }
+
+    public void reset() {
+        valueCount = 0;
+        Marshal.putInt(valueCount, storage, offset);
+    }
+
+    public VKmerBytesWritable getPosition(int i) {
+        posIter.setAsReference(storage, getOffsetOfKmer(i));
+        return posIter;
+    }
+    
+    /**
+     * Return the offset of the kmer at the i'th position 
+     */
+    public int getOffsetOfKmer(int i) {
+        if (i >= valueCount) {
+            throw new ArrayIndexOutOfBoundsException("No such position " + i + " in list " + toString());
+        }
+        // seek to the given position
+        int posOffset = offset + HEADER_SIZE;
+        for (int curIndex = 0; curIndex < i; curIndex++) {
+            posOffset += KmerUtil.getByteNumFromK(Marshal.getInt(storage, posOffset)) + VKmerBytesWritable.HEADER_SIZE;
+        }
+        return posOffset;
+    }
+
+    public void setCopy(VKmerListWritable otherList) {
+        setCopy(otherList.storage, otherList.offset);
+    }
+
+    /**
+     * read a KmerListWritable from newData, which should include the header
+     */
+    public void setCopy(byte[] newData, int newOffset) {
+        int newValueCount = Marshal.getInt(newData, newOffset);
+        int newLength = getLength(newData, newOffset);
+        setSize(newLength);
+        if (newValueCount > 0) {
+            System.arraycopy(newData, newOffset + HEADER_SIZE, 
+                    storage, this.offset + HEADER_SIZE,
+                    newLength - HEADER_SIZE);
+        }
+        valueCount = newValueCount;
+        Marshal.putInt(valueCount, storage, this.offset);
+    }
+
+    @Override
+    public Iterator<VKmerBytesWritable> iterator() {
+        Iterator<VKmerBytesWritable> it = new Iterator<VKmerBytesWritable>() {
+
+            private int currentIndex = 0;
+            private int currentOffset = HEADER_SIZE; // init as offset of first kmer
+
+            @Override
+            public boolean hasNext() {
+                return currentIndex < valueCount;
+            }
+
+            @Override
+            public VKmerBytesWritable next() {
+                posIter.setAsReference(storage, currentOffset);
+                currentOffset += KmerUtil.getByteNumFromK(Marshal.getInt(storage, currentOffset)) + VKmerBytesWritable.HEADER_SIZE;
+                currentIndex++;
+                return posIter;
+            }
+
+            @Override
+            public void remove() {
+                if (currentOffset <= 0) {
+                    throw new IllegalStateException("You must advance the iterator using .next() before calling remove()!");
+                }
+                // we're removing the element at prevIndex
+                int prevIndex = currentIndex - 1;
+                int prevOffset = getOffsetOfKmer(prevIndex);
+                
+                if (currentIndex < valueCount) { // if it's the last element, don't have to do any copying
+                    System.arraycopy(storage, currentOffset, // from the "next" element
+                            storage, prevOffset, // to the one just returned (overwriting it)
+                            getLength() - currentOffset + offset);  // remaining bytes except current element
+                }
+                valueCount--;
+                currentIndex--;
+                Marshal.putInt(valueCount, storage, offset);
+                currentOffset = prevOffset;
+            }
+        };
+        return it;
+    }
+
+    /*
+     * remove the first instance of `toRemove`. Uses a linear scan. Throws an
+     * exception if not in this list.
+     */
+    public void remove(KmerBytesWritable toRemove, boolean ignoreMissing) {
+        Iterator<VKmerBytesWritable> posIterator = this.iterator();
+        while (posIterator.hasNext()) {
+            if (toRemove.equals(posIterator.next())) {
+                posIterator.remove();
+                return;  // break as soon as the element is found 
+            }
+        }
+        // element was not found
+        if (!ignoreMissing) {
+            throw new ArrayIndexOutOfBoundsException("the KmerBytesWritable `" + toRemove.toString()
+                    + "` was not found in this list.");
+        }
+    }
+
+    public void remove(KmerBytesWritable toRemove) {
+        remove(toRemove, false);
+    }
+
+    @Override
+    public void readFields(DataInput in) throws IOException {
+        reset();
+        valueCount = in.readInt();
+        Marshal.putInt(valueCount, storage, offset);
+        int curOffset = offset + HEADER_SIZE;
+        int elemBytes = 0;
+        int elemLetters = 0;
+        int curLength = getLength();
+        for (int i = 0; i < valueCount; i++) {
+            elemLetters = in.readInt();
+            elemBytes = KmerUtil.getByteNumFromK(elemLetters) + VKmerBytesWritable.HEADER_SIZE;
+            setSize(curLength + elemBytes); // make sure we have room for the new element
+            Marshal.putInt(elemLetters, storage, curOffset); // write header
+            in.readFully(storage, curOffset + VKmerBytesWritable.HEADER_SIZE, elemBytes - VKmerBytesWritable.HEADER_SIZE); // write kmer
+            curOffset += elemBytes;
+            curLength += elemBytes;
+        }
+    }
+
+    @Override
+    public void write(DataOutput out) throws IOException {
+        out.write(storage, offset, getLength());
+    }
+
+    public int getCountOfPosition() {
+        return valueCount;
+    }
+
+    public byte[] getByteArray() {
+        return storage;
+    }
+
+    public int getStartOffset() {
+        return offset;
+    }
+
+    public int getLength() {
+        int totalSize = HEADER_SIZE;
+        for (int curCount = 0; curCount < valueCount; curCount++) {
+            totalSize += KmerUtil.getByteNumFromK(Marshal.getInt(storage, offset + totalSize)) + VKmerBytesWritable.HEADER_SIZE;
+        }
+        return totalSize;
+    }
+    
+    public static int getLength(byte[] listStorage, int listOffset) {
+      int totalSize = HEADER_SIZE;
+      int listValueCount = Marshal.getInt(listStorage, listOffset);
+      for (int curCount = 0; curCount < listValueCount; curCount++) {
+          totalSize += KmerUtil.getByteNumFromK(Marshal.getInt(listStorage, listOffset + totalSize)) + VKmerBytesWritable.HEADER_SIZE;
+      }
+      return totalSize;
+  }
+
+    @Override
+    public String toString() {
+        StringBuilder sbuilder = new StringBuilder();
+        sbuilder.append('[');
+        for (int i = 0; i < valueCount; i++) {
+            sbuilder.append(getPosition(i).toString());
+            sbuilder.append(',');
+        }
+        if (valueCount > 0) {
+            sbuilder.setCharAt(sbuilder.length() - 1, ']');
+        } else {
+            sbuilder.append(']');
+        }
+        return sbuilder.toString();
+    }
+
+    @Override
+    public int hashCode() {
+        return Marshal.hashBytes(getByteArray(), getStartOffset(), getLength());
+    }
+}
diff --git a/genomix/genomix-data/src/test/java/edu/uci/ics/genomix/data/test/KmerListWritableTest.java b/genomix/genomix-data/src/test/java/edu/uci/ics/genomix/data/test/KmerListWritableTest.java
index 2f7bba8..9ca4488 100644
--- a/genomix/genomix-data/src/test/java/edu/uci/ics/genomix/data/test/KmerListWritableTest.java
+++ b/genomix/genomix-data/src/test/java/edu/uci/ics/genomix/data/test/KmerListWritableTest.java
@@ -7,21 +7,20 @@
 
 import org.junit.Test;
 
-import edu.uci.ics.genomix.type.KmerBytesWritable;
-import edu.uci.ics.genomix.type.KmerListWritable;
+import edu.uci.ics.genomix.type.VKmerBytesWritable;
+import edu.uci.ics.genomix.type.VKmerListWritable;
 
 public class KmerListWritableTest {
 
     @Test
     public void TestInitial() {
-        KmerListWritable kmerList = new KmerListWritable();
+        VKmerListWritable kmerList = new VKmerListWritable();
         Assert.assertEquals(kmerList.getCountOfPosition(), 0);
         
         //one kmer in list and reset each time
-        KmerBytesWritable kmer;
+        VKmerBytesWritable kmer;
         for (int i = 1; i < 200; i++) {
-            KmerBytesWritable.setGlobalKmerLength(i);
-            kmer = new KmerBytesWritable();
+            kmer = new VKmerBytesWritable(i);
             String randomString = generaterRandomString(i);
             byte[] array = randomString.getBytes();
             kmer.setByRead(array, 0);
@@ -32,10 +31,9 @@
         }
         
         kmerList.reset();
-        KmerBytesWritable.setGlobalKmerLength(5);
         //add one more kmer each time and fix kmerSize
         for (int i = 0; i < 200; i++) {
-            kmer = new KmerBytesWritable();
+            kmer = new VKmerBytesWritable(5);
             String randomString = generaterRandomString(5);
             byte[] array = randomString.getBytes();
             kmer.setByRead(array, 0);
@@ -47,7 +45,7 @@
         byte [] another = new byte [kmerList.getLength()*2];
         int start = 20;
         System.arraycopy(kmerList.getByteArray(), kmerList.getStartOffset(), another, start, kmerList.getLength());
-        KmerListWritable plist2 = new KmerListWritable(another, start);
+        VKmerListWritable plist2 = new VKmerListWritable(another, start);
         for(int i = 0; i < plist2.getCountOfPosition(); i++){
             Assert.assertEquals(kmerList.getPosition(i).toString(), plist2.getPosition(i).toString());
         }
@@ -55,14 +53,13 @@
     
     @Test
     public void TestRemove() {
-        KmerListWritable kmerList = new KmerListWritable();
+        VKmerListWritable kmerList = new VKmerListWritable();
         Assert.assertEquals(kmerList.getCountOfPosition(), 0);
         
         int i;
-        KmerBytesWritable kmer;
+        VKmerBytesWritable kmer;
         for (i = 0; i < 200; i++) {
-            KmerBytesWritable.setGlobalKmerLength(5);
-            kmer = new KmerBytesWritable();
+            kmer = new VKmerBytesWritable(5);
             String randomString = generaterRandomString(5);
             byte[] array = randomString.getBytes();
             kmer.setByRead(array, 0);
@@ -72,23 +69,26 @@
         }
         
         //delete one element each time
-        KmerBytesWritable tmpKmer = new KmerBytesWritable();
+        VKmerBytesWritable tmpKmer = new VKmerBytesWritable(5);
         i = 0;
-        KmerListWritable copyList = new KmerListWritable();
+        VKmerListWritable copyList = new VKmerListWritable();
         copyList.setCopy(kmerList);
-        Iterator<KmerBytesWritable> iterator;
+        Iterator<VKmerBytesWritable> iterator;
         for(int j = 0; j < 5; j++){
             iterator = copyList.iterator();
             byte[] array = kmerList.getPosition(j).toString().getBytes();
-            KmerBytesWritable deletePos = new KmerBytesWritable();
+            VKmerBytesWritable deletePos = new VKmerBytesWritable(5);
             deletePos.setByRead(array, 0);
+            boolean removed = false;
             while(iterator.hasNext()){
                 tmpKmer = iterator.next();
                 if(tmpKmer.equals(deletePos)){
                     iterator.remove();
+                    removed = true;
                     break;
                 }
             }
+            Assert.assertTrue(removed);
             Assert.assertEquals(200 - 1 - j, copyList.getCountOfPosition());
             while(iterator.hasNext()){
                 tmpKmer = iterator.next();
@@ -107,14 +107,13 @@
         
         Assert.assertEquals(0, kmerList.getCountOfPosition());
         
-        KmerBytesWritable.setGlobalKmerLength(3);
-        KmerListWritable edgeList = new KmerListWritable();
-        KmerBytesWritable k = new KmerBytesWritable();
+        VKmerListWritable edgeList = new VKmerListWritable();
+        VKmerBytesWritable k = new VKmerBytesWritable(3);
         k.setByRead(("AAA").getBytes(), 0);
         edgeList.append(k);
         k.setByRead(("CCC").getBytes(), 0);
         edgeList.append(k);
-        for(KmerBytesWritable edge : edgeList){
+        for(VKmerBytesWritable edge : edgeList){
         	System.out.println(edge.toString());
         }
     }
diff --git a/genomix/genomix-hadoop/src/main/java/edu/uci/ics/genomix/hadoop/contrailgraphbuilding/GenomixMapper.java b/genomix/genomix-hadoop/src/main/java/edu/uci/ics/genomix/hadoop/contrailgraphbuilding/GenomixMapper.java
index 833462c..0c7cc20 100644
--- a/genomix/genomix-hadoop/src/main/java/edu/uci/ics/genomix/hadoop/contrailgraphbuilding/GenomixMapper.java
+++ b/genomix/genomix-hadoop/src/main/java/edu/uci/ics/genomix/hadoop/contrailgraphbuilding/GenomixMapper.java
@@ -13,7 +13,7 @@
 import org.apache.hadoop.mapred.Reporter;
 
 import edu.uci.ics.genomix.type.KmerBytesWritable;
-import edu.uci.ics.genomix.type.KmerListWritable;
+import edu.uci.ics.genomix.type.VKmerListWritable;
 import edu.uci.ics.genomix.type.NodeWritable;
 import edu.uci.ics.genomix.type.PositionListWritable;
 import edu.uci.ics.genomix.type.PositionWritable;
@@ -37,8 +37,8 @@
     private KmerBytesWritable nextReverseKmer;
     private PositionWritable nodeId;
     private PositionListWritable nodeIdList;
-    private KmerListWritable edgeListForPreKmer;
-    private KmerListWritable edgeListForNextKmer;
+    private VKmerListWritable edgeListForPreKmer;
+    private VKmerListWritable edgeListForNextKmer;
     private NodeWritable outputNode;
     
     private KmerDir preKmerDir;
@@ -59,8 +59,8 @@
         nextReverseKmer = new KmerBytesWritable();
         nodeId = new PositionWritable();
         nodeIdList = new PositionListWritable();
-        edgeListForPreKmer = new KmerListWritable();
-        edgeListForNextKmer = new KmerListWritable();
+        edgeListForPreKmer = new VKmerListWritable();
+        edgeListForNextKmer = new VKmerListWritable();
         outputNode = new NodeWritable();
         preKmerDir = KmerDir.FORWARD;
         curKmerDir = KmerDir.FORWARD;
diff --git a/genomix/genomix-hyracks/src/main/java/edu/uci/ics/genomix/hyracks/newgraph/dataflow/ReadsKeyValueParserFactory.java b/genomix/genomix-hyracks/src/main/java/edu/uci/ics/genomix/hyracks/newgraph/dataflow/ReadsKeyValueParserFactory.java
index fc5ca34..bda4ea9 100644
--- a/genomix/genomix-hyracks/src/main/java/edu/uci/ics/genomix/hyracks/newgraph/dataflow/ReadsKeyValueParserFactory.java
+++ b/genomix/genomix-hyracks/src/main/java/edu/uci/ics/genomix/hyracks/newgraph/dataflow/ReadsKeyValueParserFactory.java
@@ -25,7 +25,7 @@
 import org.apache.hadoop.io.Text;
 
 import edu.uci.ics.genomix.type.KmerBytesWritable;
-import edu.uci.ics.genomix.type.KmerListWritable;
+import edu.uci.ics.genomix.type.VKmerListWritable;
 import edu.uci.ics.genomix.type.NodeWritable;
 import edu.uci.ics.genomix.type.PositionListWritable;
 import edu.uci.ics.genomix.type.PositionWritable;
@@ -76,8 +76,8 @@
             
             private PositionWritable nodeId = new PositionWritable();
             private PositionListWritable nodeIdList = new PositionListWritable();
-            private KmerListWritable edgeListForPreKmer = new KmerListWritable();
-            private KmerListWritable edgeListForNextKmer = new KmerListWritable();
+            private VKmerListWritable edgeListForPreKmer = new VKmerListWritable();
+            private VKmerListWritable edgeListForNextKmer = new VKmerListWritable();
             private NodeWritable outputNode = new NodeWritable();
 //            private NodeWritable outputNode2 = new NodeWritable();
 
diff --git a/genomix/genomix-pregelix/src/main/java/edu/uci/ics/genomix/pregelix/io/AdjacencyListWritable.java b/genomix/genomix-pregelix/src/main/java/edu/uci/ics/genomix/pregelix/io/AdjacencyListWritable.java
index b19a0cf..09e98fa 100644
--- a/genomix/genomix-pregelix/src/main/java/edu/uci/ics/genomix/pregelix/io/AdjacencyListWritable.java
+++ b/genomix/genomix-pregelix/src/main/java/edu/uci/ics/genomix/pregelix/io/AdjacencyListWritable.java
@@ -7,20 +7,20 @@
 import org.apache.hadoop.io.WritableComparable;
 
 import edu.uci.ics.genomix.oldtype.PositionListWritable;
-import edu.uci.ics.genomix.type.KmerListWritable;
+import edu.uci.ics.genomix.type.VKmerListWritable;
 
 public class AdjacencyListWritable implements WritableComparable<AdjacencyListWritable>{
-    private KmerListWritable forwardList;
-    private KmerListWritable reverseList;
+    private VKmerListWritable forwardList;
+    private VKmerListWritable reverseList;
     
     public AdjacencyListWritable(){
-        forwardList = new KmerListWritable();
-        reverseList = new KmerListWritable();
+        forwardList = new VKmerListWritable();
+        reverseList = new VKmerListWritable();
     }
     
     public AdjacencyListWritable(int kmerSize){
-        forwardList = new KmerListWritable();
-        reverseList = new KmerListWritable();
+        forwardList = new VKmerListWritable();
+        reverseList = new VKmerListWritable();
     }
 
     public void set(AdjacencyListWritable adjacencyList){
@@ -42,19 +42,19 @@
     	return forwardList.getCountOfPosition() + reverseList.getCountOfPosition();
     }
 
-    public KmerListWritable getForwardList() {
+    public VKmerListWritable getForwardList() {
         return forwardList;
     }
 
-    public void setForwardList(KmerListWritable forwardList) {
+    public void setForwardList(VKmerListWritable forwardList) {
         this.forwardList = forwardList;
     }
 
-    public KmerListWritable getReverseList() {
+    public VKmerListWritable getReverseList() {
         return reverseList;
     }
 
-    public void setReverseList(KmerListWritable reverseList) {
+    public void setReverseList(VKmerListWritable reverseList) {
         this.reverseList = reverseList;
     }
 
diff --git a/genomix/genomix-pregelix/src/main/java/edu/uci/ics/genomix/pregelix/io/VertexValueWritable.java b/genomix/genomix-pregelix/src/main/java/edu/uci/ics/genomix/pregelix/io/VertexValueWritable.java
index e0b21bc..5e7a856 100644
--- a/genomix/genomix-pregelix/src/main/java/edu/uci/ics/genomix/pregelix/io/VertexValueWritable.java
+++ b/genomix/genomix-pregelix/src/main/java/edu/uci/ics/genomix/pregelix/io/VertexValueWritable.java
@@ -8,7 +8,7 @@
 import edu.uci.ics.genomix.pregelix.type.MessageFlag;
 import edu.uci.ics.genomix.type.KmerBytesWritable;
 import edu.uci.ics.genomix.type.VKmerBytesWritable;
-import edu.uci.ics.genomix.type.KmerListWritable;
+import edu.uci.ics.genomix.type.VKmerListWritable;
 
 public class VertexValueWritable implements WritableComparable<VertexValueWritable> {
 
@@ -66,16 +66,16 @@
         kmer = new VKmerBytesWritable();
     }
 
-    public VertexValueWritable(PositionListWritable nodeIdList, KmerListWritable forwardForwardList, KmerListWritable forwardReverseList,
-            KmerListWritable reverseForwardList, KmerListWritable reverseReverseList,
+    public VertexValueWritable(PositionListWritable nodeIdList, VKmerListWritable forwardForwardList, VKmerListWritable forwardReverseList,
+            VKmerListWritable reverseForwardList, VKmerListWritable reverseReverseList,
             byte state, VKmerBytesWritable kmer) {
         set(nodeIdList, forwardForwardList, forwardReverseList, 
                 reverseForwardList, reverseReverseList,
                 state, kmer);
     }
     
-    public void set(PositionListWritable nodeIdList, KmerListWritable forwardForwardList, KmerListWritable forwardReverseList,
-            KmerListWritable reverseForwardList, KmerListWritable reverseReverseList, 
+    public void set(PositionListWritable nodeIdList, VKmerListWritable forwardForwardList, VKmerListWritable forwardReverseList,
+            VKmerListWritable reverseForwardList, VKmerListWritable reverseReverseList, 
             byte state, VKmerBytesWritable kmer) {
         this.kmerlength = kmer.getKmerLetterLength();
         this.incomingList.setForwardList(reverseForwardList);
@@ -101,35 +101,35 @@
         this.nodeIdList.set(nodeIdList);
     }
 
-    public KmerListWritable getFFList() {
+    public VKmerListWritable getFFList() {
         return outgoingList.getForwardList();
     }
 
-    public KmerListWritable getFRList() {
+    public VKmerListWritable getFRList() {
         return outgoingList.getReverseList();
     }
 
-    public KmerListWritable getRFList() {
+    public VKmerListWritable getRFList() {
         return incomingList.getForwardList();
     }
 
-    public KmerListWritable getRRList() {
+    public VKmerListWritable getRRList() {
         return incomingList.getReverseList();
     }
     
-    public void setFFList(KmerListWritable forwardForwardList){
+    public void setFFList(VKmerListWritable forwardForwardList){
         outgoingList.setForwardList(forwardForwardList);
     }
     
-    public void setFRList(KmerListWritable forwardReverseList){
+    public void setFRList(VKmerListWritable forwardReverseList){
         outgoingList.setReverseList(forwardReverseList);
     }
     
-    public void setRFList(KmerListWritable reverseForwardList){
+    public void setRFList(VKmerListWritable reverseForwardList){
         incomingList.setForwardList(reverseForwardList);
     }
 
-    public void setRRList(KmerListWritable reverseReverseList){
+    public void setRRList(VKmerListWritable reverseReverseList){
         incomingList.setReverseList(reverseReverseList);
     }
     
diff --git a/genomix/genomix-pregelix/src/main/java/edu/uci/ics/genomix/pregelix/operator/pathmerge/MapReduceVertex.java b/genomix/genomix-pregelix/src/main/java/edu/uci/ics/genomix/pregelix/operator/pathmerge/MapReduceVertex.java
index 186fa4c..c1b1dda 100644
--- a/genomix/genomix-pregelix/src/main/java/edu/uci/ics/genomix/pregelix/operator/pathmerge/MapReduceVertex.java
+++ b/genomix/genomix-pregelix/src/main/java/edu/uci/ics/genomix/pregelix/operator/pathmerge/MapReduceVertex.java
@@ -13,7 +13,7 @@
 import edu.uci.ics.genomix.pregelix.io.VertexValueWritable.State;
 import edu.uci.ics.genomix.pregelix.type.MessageFlag;
 //import edu.uci.ics.genomix.type.KmerBytesWritable;
-import edu.uci.ics.genomix.type.KmerListWritable;
+import edu.uci.ics.genomix.type.VKmerListWritable;
 import edu.uci.ics.genomix.type.VKmerBytesWritable;
 import edu.uci.ics.pregelix.api.graph.Vertex;
 import edu.uci.ics.pregelix.api.job.PregelixJob;
@@ -26,8 +26,8 @@
     protected static VKmerBytesWritable fakeVertex = null;
     
     protected VKmerBytesWritable reverseKmer;
-    protected KmerListWritable kmerList = null;
-    protected Map<VKmerBytesWritable, KmerListWritable> kmerMapper = new HashMap<VKmerBytesWritable, KmerListWritable>();
+    protected VKmerListWritable kmerList = null;
+    protected Map<VKmerBytesWritable, VKmerListWritable> kmerMapper = new HashMap<VKmerBytesWritable, VKmerListWritable>();
 
     /**
      * initiate kmerSize, maxIteration
@@ -46,7 +46,7 @@
         if(reverseKmer == null)
             reverseKmer = new VKmerBytesWritable();
         if(kmerList == null)
-            kmerList = new KmerListWritable();
+            kmerList = new VKmerListWritable();
         else
             kmerList.reset();
         if(fakeVertex == null){
diff --git a/genomix/genomix-pregelix/src/main/java/edu/uci/ics/genomix/pregelix/operator/pathmerge/P2ForPathMergeVertex.java b/genomix/genomix-pregelix/src/main/java/edu/uci/ics/genomix/pregelix/operator/pathmerge/P2ForPathMergeVertex.java
index ef39a23..c9942a2 100644
--- a/genomix/genomix-pregelix/src/main/java/edu/uci/ics/genomix/pregelix/operator/pathmerge/P2ForPathMergeVertex.java
+++ b/genomix/genomix-pregelix/src/main/java/edu/uci/ics/genomix/pregelix/operator/pathmerge/P2ForPathMergeVertex.java
@@ -13,7 +13,7 @@
 import edu.uci.ics.genomix.pregelix.type.MessageFlag;
 import edu.uci.ics.genomix.pregelix.type.MessageFromHead;
 import edu.uci.ics.genomix.type.KmerBytesWritable;
-import edu.uci.ics.genomix.type.KmerListWritable;
+import edu.uci.ics.genomix.type.VKmerListWritable;
 import edu.uci.ics.genomix.type.VKmerBytesWritable;
 /*
  * vertexId: BytesWritable
@@ -70,7 +70,7 @@
         if(reverseKmer == null)
             reverseKmer = new VKmerBytesWritable();
         if(kmerList == null)
-            kmerList = new KmerListWritable();
+            kmerList = new VKmerListWritable();
         else
             kmerList.reset();
         if(fakeVertex == null){
diff --git a/genomix/genomix-pregelix/src/main/java/edu/uci/ics/genomix/pregelix/operator/splitrepeat/SplitRepeatVertex.java b/genomix/genomix-pregelix/src/main/java/edu/uci/ics/genomix/pregelix/operator/splitrepeat/SplitRepeatVertex.java
index 8546bb6..33b62c3 100644
--- a/genomix/genomix-pregelix/src/main/java/edu/uci/ics/genomix/pregelix/operator/splitrepeat/SplitRepeatVertex.java
+++ b/genomix/genomix-pregelix/src/main/java/edu/uci/ics/genomix/pregelix/operator/splitrepeat/SplitRepeatVertex.java
@@ -12,7 +12,7 @@
 import edu.uci.ics.genomix.pregelix.operator.pathmerge.BasicGraphCleanVertex;
 import edu.uci.ics.genomix.pregelix.type.MessageFlag;
 import edu.uci.ics.genomix.type.KmerBytesWritable;
-import edu.uci.ics.genomix.type.KmerListWritable;
+import edu.uci.ics.genomix.type.VKmerListWritable;
 import edu.uci.ics.genomix.type.PositionWritable;
 import edu.uci.ics.genomix.type.VKmerBytesWritable;
 import edu.uci.ics.pregelix.api.graph.Vertex;