Merge branch 'genomix/fullstack_genomix' of https://code.google.com/p/hyracks into genomix/fullstack_genomix
diff --git a/genomix/genomix-data/src/main/java/edu/uci/ics/genomix/experiment/KmerVertexID.java b/genomix/genomix-data/src/main/java/edu/uci/ics/genomix/experiment/KmerVertexID.java
new file mode 100644
index 0000000..9a01e36
--- /dev/null
+++ b/genomix/genomix-data/src/main/java/edu/uci/ics/genomix/experiment/KmerVertexID.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2009-2012 by The Regents of the University of California
+ * Licensed 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 from
+ *
+ *     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 edu.uci.ics.genomix.experiment;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+
+import org.apache.hadoop.io.Writable;
+
+public class KmerVertexID implements Writable {
+    private int readID;
+    private byte posInRead;
+
+    public KmerVertexID(int readID, byte posInRead) {
+        set(readID, posInRead);
+    }
+
+    public KmerVertexID() {
+        readID = -1;
+        posInRead = -1;
+    }
+
+    @Override
+    public void readFields(DataInput arg0) throws IOException {
+        readID = arg0.readInt();
+        posInRead = arg0.readByte();
+    }
+
+    @Override
+    public void write(DataOutput arg0) throws IOException {
+        arg0.writeInt(readID);
+        arg0.writeByte(posInRead);
+    }
+
+    @Override
+    public String toString() {
+        return String.valueOf(readID) + '\t' + String.valueOf(posInRead);
+    }
+
+    public void set(int readID, byte posInRead) {
+        this.readID = readID;
+        this.posInRead = posInRead;
+    }
+
+    public int getReadID() {
+        return readID;
+    }
+
+    public void setReadID(int readID) {
+        this.readID = readID;
+    }
+
+    public byte getPosInRead() {
+        return posInRead;
+    }
+}
\ No newline at end of file
diff --git a/genomix/genomix-data/src/main/java/edu/uci/ics/genomix/experiment/VertexAdjacentWritable.java b/genomix/genomix-data/src/main/java/edu/uci/ics/genomix/experiment/VertexAdjacentWritable.java
new file mode 100644
index 0000000..191aacf
--- /dev/null
+++ b/genomix/genomix-data/src/main/java/edu/uci/ics/genomix/experiment/VertexAdjacentWritable.java
@@ -0,0 +1,66 @@
+package edu.uci.ics.genomix.experiment;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+
+import org.apache.hadoop.io.Writable;
+
+import edu.uci.ics.genomix.type.KmerBytesWritable;
+import edu.uci.ics.genomix.type.VKmerBytesWritable;
+
+public class VertexAdjacentWritable implements Writable {
+
+    private static final byte[] EMPTY_BYTES = {};
+    private VertexIDListWritable adjVertexList;
+    private VKmerBytesWritable kmer;
+
+    public VertexAdjacentWritable() {
+        this(null, 0, EMPTY_BYTES);
+    }
+
+    public VertexAdjacentWritable(VertexIDList right, int kmerSize, byte[] bytes) {
+        if (right != null)
+            this.adjVertexList = new VertexIDListWritable(right);
+        else
+            this.adjVertexList = new VertexIDListWritable();
+        this.kmer = new VKmerBytesWritable(kmerSize, bytes);
+        kmer.set(bytes, 0, bytes.length);
+    }
+
+    public void set(VertexAdjacentWritable right) {
+        set(right.getAdjVertexList(), right.getVkmer());
+    }
+
+    public void set(VertexIDListWritable vIDList, KmerBytesWritable kmer) {
+        this.adjVertexList.set(vIDList);
+        this.kmer.set(kmer);
+    }
+    
+    public void set(VertexIDListWritable vIDList, VKmerBytesWritable kmer) {
+        this.adjVertexList.set(vIDList);
+        this.kmer.set(kmer);
+    }
+    
+    @Override
+    public void readFields(DataInput arg0) throws IOException {
+        // TODO Auto-generated method stub
+        adjVertexList.readFields(arg0);
+        kmer.readFields(arg0);
+    }
+
+    @Override
+    public void write(DataOutput arg0) throws IOException {
+        // TODO Auto-generated method stub
+        adjVertexList.write(arg0);
+        kmer.write(arg0);
+    }
+    
+    public VertexIDListWritable getAdjVertexList() {
+        return this.adjVertexList;
+    }
+    
+    public VKmerBytesWritable getVkmer() {
+        return this.kmer;
+    }
+}
diff --git a/genomix/genomix-data/src/main/java/edu/uci/ics/genomix/experiment/VertexIDList.java b/genomix/genomix-data/src/main/java/edu/uci/ics/genomix/experiment/VertexIDList.java
new file mode 100644
index 0000000..f799b00
--- /dev/null
+++ b/genomix/genomix-data/src/main/java/edu/uci/ics/genomix/experiment/VertexIDList.java
@@ -0,0 +1,183 @@
+package edu.uci.ics.genomix.experiment;
+
+public class VertexIDList {
+
+    private int[] readIDList;
+    private byte[] posInReadList;
+    private static final int[] EMPTY_INTS = {};
+    private static final byte[] EMPTY_BYTES = {};
+
+    private int usedSize;
+    private int arraySize;
+
+    public VertexIDList() {
+        this(0, 0, EMPTY_INTS, EMPTY_BYTES);
+    }
+
+    public VertexIDList(int usedSize, int arraySize, int[] rList, byte[] pList) {
+        this.usedSize = usedSize;
+        this.arraySize = arraySize;
+        if (arraySize > 0) {
+            this.readIDList = rList;
+            this.posInReadList = pList;
+            if (this.readIDList.length != arraySize | this.posInReadList.length != arraySize) {
+                throw new ArrayIndexOutOfBoundsException("the arraySize doesn't corespond to the array");
+            }
+            if (this.readIDList.length < usedSize | this.posInReadList.length < usedSize) {
+                throw new ArrayIndexOutOfBoundsException("the usedSize doesn't corespond to the array");
+            }
+        } else {
+            this.readIDList = rList;
+            this.posInReadList = pList;
+            this.arraySize = 0;
+            this.usedSize = 0;
+        }
+    }
+
+    public VertexIDList(int arraySize) {
+        this.arraySize = arraySize;
+        this.usedSize = 0;
+        if (arraySize > 0) {
+            this.readIDList = new int[this.arraySize];
+            this.posInReadList = new byte[this.arraySize];
+        } else {
+            this.readIDList = EMPTY_INTS;
+            this.posInReadList = EMPTY_BYTES;
+        }
+    }
+
+    public VertexIDList(VertexIDList right) {
+        if (right != null) {
+            this.usedSize = right.usedSize;
+            this.arraySize = right.arraySize;
+            this.readIDList = new int[right.arraySize];
+            this.posInReadList = new byte[right.arraySize];
+            if (this.readIDList.length != arraySize | this.posInReadList.length != arraySize) {
+                throw new ArrayIndexOutOfBoundsException("the arraySize doesn't corespond to the array");
+            }
+            if (this.readIDList.length < usedSize | this.posInReadList.length < usedSize) {
+                throw new ArrayIndexOutOfBoundsException("the usedSize doesn't corespond to the array");
+            }
+            set(right);
+        } else {
+            this.arraySize = 0;
+            this.usedSize = 0;
+            this.readIDList = EMPTY_INTS;
+            this.posInReadList = EMPTY_BYTES;
+        }
+    }
+
+    public void set(VertexIDList newData) {
+        set(newData.readIDList, 0, newData.posInReadList, 0, newData.usedSize);
+    }
+
+    public void set(int[] rIDList, int rOffset, byte[] pReadList, int pOffset, int copySize) {
+        setArraySize(0);
+        setArraySize(copySize);
+        System.arraycopy(rIDList, rOffset, this.readIDList, 0, copySize);
+        System.arraycopy(pReadList, pOffset, this.posInReadList, 0, copySize);
+        this.usedSize = copySize;
+    }
+
+    public void setArraySize(int arraySize) {
+        if (arraySize > getCapacity()) {
+            setCapacity((arraySize * 2));
+        }
+        this.arraySize = arraySize;
+    }
+
+    public int getCapacity() {
+        return this.arraySize;
+    }
+
+    public void setCapacity(int new_cap) {
+        if (new_cap != getCapacity()) {
+            int[] newRList = new int[new_cap];
+            byte[] newPList = new byte[new_cap];
+            if (new_cap < this.arraySize) {
+                this.arraySize = new_cap;
+            }
+            if (this.arraySize != 0) {
+                System.arraycopy(this.readIDList, 0, newRList, 0, this.usedSize);
+                System.arraycopy(this.posInReadList, 0, newPList, 0, this.usedSize);
+            }
+            this.readIDList = newRList;
+            this.posInReadList = newPList;
+        }
+    }
+
+    public int getReadListElement(int position) {
+        if (position < this.usedSize) {
+            return this.readIDList[position];
+        } else {
+            throw new ArrayIndexOutOfBoundsException("position exceed for the usedSize");
+        }
+    }
+
+    public byte getPosinReadListElement(int position) {
+        if (position < this.usedSize) {
+            return this.posInReadList[position];
+        } else {
+            throw new ArrayIndexOutOfBoundsException("position exceed for the usedSize");
+        }
+    }
+
+    public int findReadListElement(int rContent) {
+        for (int i = 0; i < this.usedSize; i++) {
+            if (this.readIDList[i] == rContent)
+                return i;
+        }
+        return -1;
+    }
+
+    public int findPosinReadListElement(int pContent) {
+        for (int i = 0; i < this.usedSize; i++) {
+            if (this.usedSize == pContent)
+                return i;
+        }
+        return -1;
+    }
+
+    public void addELementToList(int rContent, byte pContent) {
+        if (this.usedSize < this.arraySize) {
+            this.readIDList[this.usedSize] = rContent;
+            this.posInReadList[this.usedSize] = pContent;
+            this.usedSize++;
+        } else {
+            setCapacity((this.arraySize * 2));
+            this.readIDList[this.usedSize] = rContent;
+            this.posInReadList[this.usedSize] = pContent;
+            this.usedSize++;
+        }
+    }
+
+    public void deleteElementFromTwoList(int position) {
+        if (position < this.usedSize) {
+            for (int i = position; i < this.usedSize; i++) {
+                this.readIDList[i] = this.readIDList[i + 1];
+                this.posInReadList[i] = this.posInReadList[i + 1];
+            }
+            this.readIDList[this.usedSize - 1] = -1;
+            this.posInReadList[this.usedSize - 1] = (byte) -1;
+            this.usedSize--;
+        } else {
+            throw new ArrayIndexOutOfBoundsException("position exceed for the usedSize");
+        }
+    }
+    
+    public int[] getReadIDList() {
+        return this.readIDList;
+    }
+    
+    public byte[] getPosInReadList() {
+        return this.posInReadList;
+    }
+    
+    public int getUsedSize() {
+        return this.usedSize;
+    }
+    
+    public int getArraySize() {
+        return this.arraySize;
+    }
+}
diff --git a/genomix/genomix-data/src/main/java/edu/uci/ics/genomix/experiment/VertexIDListWritable.java b/genomix/genomix-data/src/main/java/edu/uci/ics/genomix/experiment/VertexIDListWritable.java
new file mode 100644
index 0000000..f7d917a
--- /dev/null
+++ b/genomix/genomix-data/src/main/java/edu/uci/ics/genomix/experiment/VertexIDListWritable.java
@@ -0,0 +1,66 @@
+package edu.uci.ics.genomix.experiment;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+import org.apache.hadoop.io.Writable;
+
+public class VertexIDListWritable implements Writable {
+
+    private VertexIDList vertexIDList;
+    private int[] tempReadIDList = null;
+    private byte[] tempPosInReadList = null;
+    
+    public VertexIDListWritable() {
+        this.vertexIDList = new VertexIDList();
+    }
+    
+    public VertexIDListWritable(VertexIDList right) {
+        this.vertexIDList = new VertexIDList(right);
+    }
+
+    public VertexIDListWritable(int length) {
+        this.vertexIDList = new VertexIDList(length);
+    }
+    
+    public void set(VertexIDListWritable right) {
+        set(right.get());
+    }
+    public void set(VertexIDList right) {
+        this.vertexIDList.set(right);
+    }
+
+    @Override
+    public void readFields(DataInput in) throws IOException {
+        // TODO Auto-generated method stub
+        int arraySize = in.readInt();
+        int usedSize = in.readInt();
+        if(usedSize > 0) {
+            this.tempReadIDList = new int[arraySize];
+            this.tempPosInReadList = new byte[arraySize];
+            for(int i = 0; i < arraySize; i++){
+                this.tempReadIDList[i] = in.readInt();
+            }
+            in.readFully(this.tempPosInReadList, 0, arraySize);
+            this.vertexIDList.set(this.tempReadIDList, 0, this.tempPosInReadList, 0, usedSize);
+        }
+    }
+
+    @Override
+    public void write(DataOutput out) throws IOException {
+        // TODO Auto-generated method stub
+        out.writeInt(vertexIDList.getArraySize());
+        out.writeInt(vertexIDList.getUsedSize());
+        if(vertexIDList.getUsedSize() > 0) {
+            int[] readIDList = vertexIDList.getReadIDList();
+            for(int i = 0 ; i < vertexIDList.getArraySize(); i ++ ){
+                out.writeInt(readIDList[i]);
+            }
+            out.write(vertexIDList.getPosInReadList(), 0, vertexIDList.getArraySize());
+        }
+    }
+    
+    public VertexIDList get() {
+        return vertexIDList;
+    }
+}
diff --git a/genomix/genomix-hadoop/src/main/java/edu/uci/ics/genomix/graphbuilding/GenomixMapper.java b/genomix/genomix-hadoop/src/main/java/edu/uci/ics/genomix/graphbuilding/GenomixMapper.java
index b9b9aec..70d1f7a 100755
--- a/genomix/genomix-hadoop/src/main/java/edu/uci/ics/genomix/graphbuilding/GenomixMapper.java
+++ b/genomix/genomix-hadoop/src/main/java/edu/uci/ics/genomix/graphbuilding/GenomixMapper.java
@@ -38,14 +38,9 @@
 public class GenomixMapper extends MapReduceBase implements
         Mapper<LongWritable, Text, KmerBytesWritable, KmerCountValue> {
 
-    public class CurrenByte {
-        public byte curByte;
-        public byte preMarker;
-    }
-
     public static int KMER_SIZE;
-    public KmerCountValue outputAdjList; 
-    public KmerBytesWritable outputKmer; 
+    public KmerCountValue outputAdjList;
+    public KmerBytesWritable outputKmer;
 
     @Override
     public void configure(JobConf job) {
diff --git a/genomix/genomix-hadoop/src/main/java/edu/uci/ics/genomix/hadoop/experiments/DeepGraphBuildingMapper.java b/genomix/genomix-hadoop/src/main/java/edu/uci/ics/genomix/hadoop/experiments/DeepGraphBuildingMapper.java
new file mode 100644
index 0000000..d2aa96e
--- /dev/null
+++ b/genomix/genomix-hadoop/src/main/java/edu/uci/ics/genomix/hadoop/experiments/DeepGraphBuildingMapper.java
@@ -0,0 +1,29 @@
+package edu.uci.ics.genomix.hadoop.experiments;
+
+import java.io.IOException;
+import org.apache.hadoop.io.IntWritable;
+import org.apache.hadoop.mapred.MapReduceBase;
+import org.apache.hadoop.mapred.Mapper;
+import org.apache.hadoop.mapred.OutputCollector;
+import org.apache.hadoop.mapred.Reporter;
+import edu.uci.ics.genomix.experiment.VertexIDList;
+import edu.uci.ics.genomix.experiment.VertexIDListWritable;
+import edu.uci.ics.genomix.type.KmerBytesWritable;
+
+@SuppressWarnings("deprecation")
+public class DeepGraphBuildingMapper extends MapReduceBase implements
+        Mapper<KmerBytesWritable, VertexIDListWritable, IntWritable, LineBasedmappingWritable> {
+    IntWritable  numLine = new IntWritable();
+    VertexIDList vertexList = new VertexIDList(1);
+    LineBasedmappingWritable lineBasedWriter = new LineBasedmappingWritable();
+    @Override
+    public void map(KmerBytesWritable key, VertexIDListWritable value, OutputCollector<IntWritable, LineBasedmappingWritable> output,
+            Reporter reporter) throws IOException {
+        vertexList.set(value.get());
+        for(int i = 0; i < vertexList.getUsedSize(); i++) {
+            numLine.set(vertexList.getReadListElement(i));
+            lineBasedWriter.set(i, value, key);
+            output.collect(numLine, lineBasedWriter);
+        }
+    }
+}
diff --git a/genomix/genomix-hadoop/src/main/java/edu/uci/ics/genomix/hadoop/experiments/DeepGraphBuildingReducer.java b/genomix/genomix-hadoop/src/main/java/edu/uci/ics/genomix/hadoop/experiments/DeepGraphBuildingReducer.java
new file mode 100644
index 0000000..0a3270e
--- /dev/null
+++ b/genomix/genomix-hadoop/src/main/java/edu/uci/ics/genomix/hadoop/experiments/DeepGraphBuildingReducer.java
@@ -0,0 +1,92 @@
+package edu.uci.ics.genomix.hadoop.experiments;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Iterator;
+
+import org.apache.hadoop.io.IntWritable;
+import org.apache.hadoop.mapred.MapReduceBase;
+import org.apache.hadoop.mapred.OutputCollector;
+import org.apache.hadoop.mapred.Reducer;
+import org.apache.hadoop.mapred.Reporter;
+import edu.uci.ics.genomix.experiment.KmerVertexID;
+import edu.uci.ics.genomix.experiment.VertexAdjacentWritable;
+import edu.uci.ics.genomix.experiment.VertexIDList;
+import edu.uci.ics.genomix.experiment.VertexIDListWritable;
+import edu.uci.ics.genomix.type.KmerBytesWritable;
+import edu.uci.ics.genomix.type.VKmerBytesWritable;
+import edu.uci.ics.genomix.type.VKmerBytesWritableFactory;
+
+@SuppressWarnings("deprecation")
+public class DeepGraphBuildingReducer extends MapReduceBase implements
+        Reducer<IntWritable, LineBasedmappingWritable, KmerVertexID, VertexAdjacentWritable> {
+
+    public ArrayList<LineBasedmappingWritable> lineElementsSet = new ArrayList<LineBasedmappingWritable>();
+    public KmerVertexID outputVerID = new KmerVertexID();
+    public VertexAdjacentWritable outputAdjacentList = new VertexAdjacentWritable();
+    public VertexIDList srcVtexAdjList = new VertexIDList();
+    public VertexIDList desVtexAdjList = new VertexIDList();
+    public VertexIDListWritable srcAdjListWritable = new VertexIDListWritable();
+    public VKmerBytesWritable desKmer = new VKmerBytesWritable(1);
+    public VKmerBytesWritableFactory kmerFactory = new VKmerBytesWritableFactory(1);
+    public VKmerBytesWritable srcKmer = new VKmerBytesWritable(1);
+    @Override
+    public void reduce(IntWritable key, Iterator<LineBasedmappingWritable> values,
+            OutputCollector<KmerVertexID, VertexAdjacentWritable> output, Reporter reporter) throws IOException {
+        while (values.hasNext()) {
+            lineElementsSet.add(values.next());
+        }
+        int[] orderLineTable = new int[lineElementsSet.size()];
+        for (int i = 0; i < lineElementsSet.size(); i++) {
+            int posInInvertedIndex = lineElementsSet.get(i).getPosInInvertedIndex();
+            orderLineTable[lineElementsSet.get(i).getAdjVertexList().get().getPosinReadListElement(posInInvertedIndex)] = i;
+        }
+        //the first node in this read
+        int posInInvertedIndex = lineElementsSet.get(orderLineTable[0]).getPosInInvertedIndex();
+        outputVerID.set(
+                lineElementsSet.get(orderLineTable[0]).getAdjVertexList().get().getReadListElement(posInInvertedIndex),
+                (byte) 0);
+        desVtexAdjList.set(lineElementsSet.get(orderLineTable[1]).getAdjVertexList().get());
+        for (int i = 0; i < desVtexAdjList.getUsedSize(); i++) {
+            if (desVtexAdjList.getPosinReadListElement(i) == (byte) 0) {
+                srcVtexAdjList.addELementToList(desVtexAdjList.getReadListElement(i), (byte) 0);
+            }
+        }
+        srcVtexAdjList.addELementToList(key.get(), (byte) 1);
+        outputVerID.set(
+                lineElementsSet.get(orderLineTable[0]).getAdjVertexList().get().getReadListElement(posInInvertedIndex),
+                (byte) 0);
+        srcAdjListWritable.set(srcVtexAdjList);
+        outputAdjacentList.set(srcAdjListWritable, lineElementsSet.get(orderLineTable[0]).getVkmer());
+        output.collect(outputVerID, outputAdjacentList);
+        //srcVtexAdjList reset!!!!
+
+        for (int i = 1; i < lineElementsSet.size(); i++) {
+            desVtexAdjList.set(lineElementsSet.get(orderLineTable[i + 1]).getAdjVertexList().get());
+            boolean flag = false;
+            for (int j = 0; j < desVtexAdjList.getUsedSize(); j++) {
+                if (desVtexAdjList.getPosinReadListElement(j) == (byte) 0) {
+                    srcVtexAdjList.addELementToList(desVtexAdjList.getReadListElement(i), (byte) 0);
+                    flag = true;
+                }
+            }
+            if (flag = true) {
+                //doesm't merge
+                srcVtexAdjList.addELementToList(key.get(), (byte) (i + 1));
+                outputVerID.set(
+                        lineElementsSet.get(orderLineTable[i]).getAdjVertexList().get()
+                                .getReadListElement(posInInvertedIndex), lineElementsSet.get(orderLineTable[i])
+                                .getAdjVertexList().get().getPosinReadListElement(posInInvertedIndex));
+                srcAdjListWritable.set(srcVtexAdjList);
+                outputAdjacentList.set(srcAdjListWritable, lineElementsSet.get(orderLineTable[i]).getVkmer());
+            }
+            else {
+                //merge
+                desKmer.set(kmerFactory.getFirstKmerFromChain(1, lineElementsSet.get(orderLineTable[i+1]).getVkmer()));
+                srcKmer.set(lineElementsSet.get(orderLineTable[i]).getVkmer());
+                lineElementsSet.get(orderLineTable[i+1]).getVkmer().set(kmerFactory.mergeTwoKmer(srcKmer, desKmer));
+                orderLineTable[i+1] = orderLineTable[i];
+            }
+        }
+    }
+}
diff --git a/genomix/genomix-hadoop/src/main/java/edu/uci/ics/genomix/hadoop/experiments/GraphKmerInvertedIndexMapper.java b/genomix/genomix-hadoop/src/main/java/edu/uci/ics/genomix/hadoop/experiments/GraphKmerInvertedIndexMapper.java
new file mode 100644
index 0000000..fe63012
--- /dev/null
+++ b/genomix/genomix-hadoop/src/main/java/edu/uci/ics/genomix/hadoop/experiments/GraphKmerInvertedIndexMapper.java
@@ -0,0 +1,60 @@
+package edu.uci.ics.genomix.hadoop.experiments;
+
+import java.io.IOException;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import org.apache.hadoop.io.LongWritable;
+import org.apache.hadoop.io.Text;
+import org.apache.hadoop.mapred.JobConf;
+import org.apache.hadoop.mapred.MapReduceBase;
+import org.apache.hadoop.mapred.Mapper;
+import org.apache.hadoop.mapred.OutputCollector;
+import org.apache.hadoop.mapred.Reporter;
+import edu.uci.ics.genomix.experiment.KmerVertexID;
+import edu.uci.ics.genomix.type.GeneCode;
+import edu.uci.ics.genomix.type.KmerBytesWritable;
+import edu.uci.ics.genomix.type.KmerCountValue;
+
+public class GraphKmerInvertedIndexMapper extends MapReduceBase implements
+        Mapper<LongWritable, Text, KmerBytesWritable, KmerVertexID> {
+    
+    public static int KMER_SIZE;
+    public KmerVertexID outputVertexID;
+    public KmerBytesWritable outputKmer;
+
+    @Override
+    public void configure(JobConf job) {
+        KMER_SIZE = Integer.parseInt(job.get("sizeKmer"));
+        outputVertexID = new KmerVertexID();
+        outputKmer = new KmerBytesWritable(KMER_SIZE);
+    }
+    @Override
+    public void map(LongWritable key, Text value, OutputCollector<KmerBytesWritable, KmerVertexID> output,
+            Reporter reporter) throws IOException {
+        
+        String geneLine = value.toString();
+        /** first kmer */
+//        byte count = 1;
+        byte[] array = geneLine.getBytes();
+        outputKmer.setByRead(array, 0);
+        byte pre = 0;
+        //byte next = GeneCode.getAdjBit(array[KMER_SIZE]);
+        //byte adj = GeneCode.mergePreNextAdj(pre, next);
+        outputVertexID.set((int)key.get(), (byte)0);
+        output.collect(outputKmer, outputVertexID);
+        /** middle kmer */
+        for (int i = KMER_SIZE; i < array.length - 1; i++) {
+            pre = GeneCode.getBitMapFromGeneCode(outputKmer.shiftKmerWithNextChar(array[i]));
+//            next = GeneCode.getAdjBit(array[i + 1]);
+//            adj = GeneCode.mergePreNextAdj(pre, next);
+            outputVertexID.set((int)key.get(), (byte)(i - KMER_SIZE + 1));
+            output.collect(outputKmer, outputVertexID);
+        }
+        /** last kmer */
+        pre = GeneCode.getBitMapFromGeneCode(outputKmer.shiftKmerWithNextChar(array[array.length - 1]));
+//        next = 0;
+//        adj = GeneCode.mergePreNextAdj(pre, next);
+        outputVertexID.set((int)key.get(), (byte)(array.length - 1 + 1));
+        output.collect(outputKmer, outputVertexID);
+    }
+}
diff --git a/genomix/genomix-hadoop/src/main/java/edu/uci/ics/genomix/hadoop/experiments/GraphKmerInvertedIndexReducer.java b/genomix/genomix-hadoop/src/main/java/edu/uci/ics/genomix/hadoop/experiments/GraphKmerInvertedIndexReducer.java
new file mode 100644
index 0000000..a228a3c
--- /dev/null
+++ b/genomix/genomix-hadoop/src/main/java/edu/uci/ics/genomix/hadoop/experiments/GraphKmerInvertedIndexReducer.java
@@ -0,0 +1,31 @@
+package edu.uci.ics.genomix.hadoop.experiments;
+
+import java.io.IOException;
+import java.util.Iterator;
+import org.apache.hadoop.mapred.MapReduceBase;
+import org.apache.hadoop.mapred.Mapper;
+import org.apache.hadoop.mapred.OutputCollector;
+import org.apache.hadoop.mapred.Reducer;
+import org.apache.hadoop.mapred.Reporter;
+import edu.uci.ics.genomix.experiment.KmerVertexID;
+import edu.uci.ics.genomix.experiment.VertexIDList;
+import edu.uci.ics.genomix.experiment.VertexIDListWritable;
+import edu.uci.ics.genomix.type.KmerBytesWritable;
+import edu.uci.ics.genomix.type.VKmerBytesWritable;
+
+@SuppressWarnings({ "deprecation", "unused" })
+public class GraphKmerInvertedIndexReducer extends MapReduceBase implements
+        Reducer<KmerBytesWritable, KmerVertexID, KmerBytesWritable, VertexIDListWritable> {
+    VertexIDList vertexList = new VertexIDList(1);
+    VertexIDListWritable listWritable = new VertexIDListWritable();
+    @Override
+    public void reduce(KmerBytesWritable key, Iterator<KmerVertexID> values,
+            OutputCollector<KmerBytesWritable, VertexIDListWritable> output, Reporter reporter) throws IOException {
+        while (values.hasNext()) {
+            KmerVertexID vertexID = values.next();
+            vertexList.addELementToList(vertexID.getReadID(), vertexID.getPosInRead());
+        }
+        listWritable.set(vertexList);
+        output.collect(key, listWritable);
+    }
+}
diff --git a/genomix/genomix-hadoop/src/main/java/edu/uci/ics/genomix/hadoop/experiments/LineBasedmappingWritable.java b/genomix/genomix-hadoop/src/main/java/edu/uci/ics/genomix/hadoop/experiments/LineBasedmappingWritable.java
new file mode 100644
index 0000000..658d56d
--- /dev/null
+++ b/genomix/genomix-hadoop/src/main/java/edu/uci/ics/genomix/hadoop/experiments/LineBasedmappingWritable.java
@@ -0,0 +1,56 @@
+package edu.uci.ics.genomix.hadoop.experiments;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+
+import edu.uci.ics.genomix.experiment.VertexAdjacentWritable;
+import edu.uci.ics.genomix.experiment.VertexIDList;
+import edu.uci.ics.genomix.experiment.VertexIDListWritable;
+import edu.uci.ics.genomix.type.KmerBytesWritable;
+import edu.uci.ics.genomix.type.VKmerBytesWritable;
+
+public class LineBasedmappingWritable extends VertexAdjacentWritable{
+    int posInInvertedIndex;
+    
+    public LineBasedmappingWritable() {
+        super();
+        this.posInInvertedIndex = -1;        
+    }
+
+    public LineBasedmappingWritable(int posInInvertedIndex, VertexIDList right, int kmerSize, byte[] bytes) {       
+        super(right, kmerSize, bytes);
+        this.posInInvertedIndex = posInInvertedIndex;
+    }
+    
+    public void set(int posInInvertedIndex, VertexAdjacentWritable right) {
+        super.set(right.getAdjVertexList(), right.getVkmer());
+        this.posInInvertedIndex = posInInvertedIndex;
+    }
+
+    public void set(int posInInvertedIndex, VertexIDListWritable vIDList, VKmerBytesWritable kmer) {
+        super.set(vIDList, kmer);
+        this.posInInvertedIndex = posInInvertedIndex;
+    }
+    
+    public void set(int posInInvertedIndex, VertexIDListWritable vIDList, KmerBytesWritable kmer) {
+        super.set(vIDList, kmer);
+        this.posInInvertedIndex = posInInvertedIndex;
+    }
+    
+    @Override
+    public void readFields(DataInput in) throws IOException {
+        super.readFields(in);
+        this.posInInvertedIndex = in.readInt();
+    }
+
+    @Override
+    public void write(DataOutput out) throws IOException {
+        super.write(out);
+        out.writeInt(this.posInInvertedIndex);
+    }
+    
+    public int getPosInInvertedIndex() {
+        return this.posInInvertedIndex;
+    }
+}