com.placeiq.piqconnect.BlockWritable.java Source code

Java tutorial

Introduction

Here is the source code for com.placeiq.piqconnect.BlockWritable.java

Source

/**
 * PIQConnect: Connected-component analysis for Big Graph
 *
 * __________.___________  _________                                     __
 * \______   \   \_____  \ \_   ___ \  ____   ____   ____   ____   _____/  |_
 *  |     ___/   |/  / \  \/    \  \/ /  _ \ /    \ /    \_/ __ \_/ ___\   __\
 *  |    |   |   /   \_/.  \     \___(  <_> )   |  \   |  \  ___/\  \___|  |
 *  |____|   |___\_____\ \_/\______  /\____/|___|  /___|  /\___  >\___  >__|
 *                      \__>       \/            \/     \/     \/     \/
 *
 * Copyright (c) 2014 PlaceIQ, Inc
 *
 * This software is licensed under 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.
 *
 * ----------------------------------------------------------------------------
 * Author: Jerome Serrano <jerome.serrano@placeiq.com>
 * Date: 2015-01-09
 * ---------------------------------------------------------------------------*/

package com.placeiq.piqconnect;

import com.google.common.base.Objects;
import gnu.trove.list.array.TIntArrayList;
import gnu.trove.list.array.TLongArrayList;
import org.apache.hadoop.io.Writable;
import org.apache.hadoop.io.WritableUtils;

import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;

public class BlockWritable implements Writable {

    private static final int END_OF_LIST = -1;

    public static enum TYPE {
        MATRIX(0), VECTOR_INITIAL(1), VECTOR_FINAL(2), VECTOR_INCOMPLETE(3);
        private final short value;

        private TYPE(int v) {
            value = (short) v;
        }

        private short getValue() {
            return value;
        }

        public static TYPE get(int code) {
            switch (code) {
            case 0:
                return MATRIX;
            case 1:
                return VECTOR_INITIAL;
            case 2:
                return VECTOR_FINAL;
            case 3:
                return VECTOR_INCOMPLETE;
            }
            return null;
        }
    };

    private TYPE type = TYPE.MATRIX;

    private TIntArrayList matrixElemIndexes = null; // (col, rows)
    private long blockRow = -1;

    private TLongArrayList vectorElemValues = null;

    public BlockWritable() {
        init(1);
    }

    public BlockWritable(int blockSize, TYPE type) {
        this(blockSize);
        this.type = type;
        if (!TYPE.MATRIX.equals(type)) {
            setVectorInitialValue(blockSize);
        }
    }

    public BlockWritable(int blockSize) {
        init(blockSize);
    }

    private void init(int blockSize) {
        this.matrixElemIndexes = new TIntArrayList(blockSize);
        this.vectorElemValues = new TLongArrayList(blockSize);
    }

    public void setVectorInitialValue(int blockSize) {
        for (int i = 0; i < blockSize; i++) {
            vectorElemValues.add(-1);
        }
    }

    @Override
    public void write(DataOutput dataOutput) throws IOException {
        if (!TYPE.MATRIX.equals(type)) {
            int v = (vectorElemValues.size() << 2) | (type.getValue() & 0x03);
            WritableUtils.writeVInt(dataOutput, v);
            for (int i = 0; i < vectorElemValues.size(); i++) {
                if (vectorElemValues.getQuick(i) != -1) {
                    WritableUtils.writeVInt(dataOutput, i);
                    WritableUtils.writeVLong(dataOutput, vectorElemValues.getQuick(i));
                }
            }
            WritableUtils.writeVInt(dataOutput, END_OF_LIST);
        } else {
            int v = (matrixElemIndexes.size() << 2) | (type.getValue() & 0x03);
            WritableUtils.writeVInt(dataOutput, v);
            WritableUtils.writeVLong(dataOutput, blockRow);
            for (int i = 0; i < matrixElemIndexes.size(); i++) {
                WritableUtils.writeVInt(dataOutput, matrixElemIndexes.get(i));
            }
        }
    }

    @Override
    public void readFields(DataInput dataInput) throws IOException {
        reset();
        int v = WritableUtils.readVInt(dataInput);
        type = TYPE.get(v & 0x03);
        if (!TYPE.MATRIX.equals(type)) {
            int n = v >> 2;
            vectorElemValues.ensureCapacity(n);
            vectorElemValues.fill(0, n, -1);
            while (true) {
                int idx = WritableUtils.readVInt(dataInput);
                if (idx == END_OF_LIST) {
                    break;
                }
                long value = WritableUtils.readVLong(dataInput);
                vectorElemValues.setQuick(idx, value);
            }
        } else {
            long n = v >> 2;
            blockRow = WritableUtils.readVLong(dataInput);
            for (int i = 0; i < n; i++) {
                matrixElemIndexes.add(WritableUtils.readVInt(dataInput));
            }
        }
    }

    @Override
    public String toString() {
        return Objects.toStringHelper(this).add("type", type).add("blockRow", blockRow)
                .add("matrixElemIndexes", matrixElemIndexes).add("vectorElemValues", vectorElemValues).toString();
    }

    public void setVectorElem(int i, long l) {
        vectorElemValues.set(i, l);
    }

    public void addMatrixElem(int i, int j) {
        matrixElemIndexes.add(i);
        matrixElemIndexes.add(j);
    }

    public void reset() {
        resetMatrix();
        resetVector();
        blockRow = -1;
    }

    public void resetVector() {
        vectorElemValues.resetQuick();
    }

    public void resetMatrix() {
        matrixElemIndexes.resetQuick();
    }

    public boolean isTypeVector() {
        return !TYPE.MATRIX.equals(type);
    }

    public TIntArrayList getMatrixElemIndexes() {
        return matrixElemIndexes;
    }

    public TLongArrayList getVectorElemValues() {
        return vectorElemValues;
    }

    public void setBlockRow(long blockRow) {
        this.blockRow = blockRow;
    }

    public long getBlockRow() {
        return blockRow;
    }

    public void set(TYPE type, BlockWritable b) {
        set(b);
        this.type = type;
    }

    public void set(BlockWritable b) {
        type = b.type;
        blockRow = b.blockRow;
        matrixElemIndexes.resetQuick();
        matrixElemIndexes.addAll(b.matrixElemIndexes);
        vectorElemValues.resetQuick();
        vectorElemValues.addAll(b.vectorElemValues);
    }

    public void setVector(TYPE type, TLongArrayList values) {
        this.type = type;
        vectorElemValues.resetQuick();
        vectorElemValues.addAll(values);
    }

    public TYPE getType() {
        return type;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o)
            return true;
        if (o == null || getClass() != o.getClass())
            return false;

        BlockWritable that = (BlockWritable) o;

        if (blockRow != that.blockRow)
            return false;
        if (type != that.type)
            return false;
        if (!matrixElemIndexes.equals(that.matrixElemIndexes))
            return false;
        if (!vectorElemValues.equals(that.vectorElemValues))
            return false;

        return true;
    }

    @Override
    public int hashCode() {
        int result = type.hashCode();
        result = 31 * result + matrixElemIndexes.hashCode();
        result = 31 * result + vectorElemValues.hashCode();
        result = 31 * result + (int) (blockRow ^ (blockRow >>> 32));
        return result;
    }
}