Package edu.cmu.graphchi.engine.auxdata

Source Code of edu.cmu.graphchi.engine.auxdata.DegreeData

package edu.cmu.graphchi.engine.auxdata;

import edu.cmu.graphchi.ChiFilenames;
import edu.cmu.graphchi.ChiLogger;
import ucar.unidata.io.RandomAccessFile;

import java.io.EOFException;
import java.io.File;
import java.io.IOException;
/**
* Copyright [2012] [Aapo Kyrola, Guy Blelloch, Carlos Guestrin / Carnegie Mellon University]
*
* 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 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.
*/


/**
* GraphChi keeps track of the degree of each vertex (count of in- and out-edges). This class
* allows accessing the vertex degrees efficiently by loading a window
* of the edges a time. This supports both sparse and dense representation
* of the degrees. This class should not be needed by application writers, and
* is only used internally by GraphChi.
* @author Aapo Kyrola
*/
public class DegreeData {

    private RandomAccessFile degreeFile;

    private byte[] degreeData;
    private int vertexSt, vertexEn;

    private boolean sparse = false;
    private int lastQuery = 0, lastId = -1;

    public DegreeData(String baseFilename) throws IOException {
        File sparseFile = new File(ChiFilenames.getFilenameOfDegreeData(baseFilename, true));
        File denseFile = new File(ChiFilenames.getFilenameOfDegreeData(baseFilename, false));

        if (sparseFile.exists()) {
            sparse = true;
            degreeFile = new RandomAccessFile(sparseFile.getAbsolutePath(), "r");
        } else {
            sparse = false;
            degreeFile = new RandomAccessFile(denseFile.getAbsolutePath(), "r");
        }
        vertexEn = vertexSt = 0;
    }

    /**
     * Load degrees for an interval of vertices
     * @param _vertexSt first vertex
     * @param _vertexEn last vertex (inclusive)
     * @throws IOException
     */
    public void load(int _vertexSt, int _vertexEn) throws IOException {

        int prevVertexEn = vertexEn;
        int prevVertexSt = vertexSt;

        vertexSt = _vertexSt;
        vertexEn = _vertexEn;

        long dataSize =  (long)  (vertexEn - vertexSt + 1) * 4 * 2;

        byte[] prevData = degreeData;
        degreeData = new byte[(int)dataSize];
        int len = 0;

        // Little bit cmoplicated book keeping to avoid redundant reads
        if (prevVertexEn > _vertexSt && prevVertexSt <= _vertexSt) {
            // Copy previous
            len = (int) ((prevVertexEn - vertexSt + 1) * 8);
            System.arraycopy(prevData, prevData.length - len, degreeData, 0, len);
        }


        if (!sparse) {
            int adjLen = (int) (dataSize - len);

            if (adjLen == 0) return;
            long dataStart =  (longvertexSt * 4l * 2l + len;

            try {
                degreeFile.seek(dataStart);
                degreeFile.readFully(degreeData, (int)(dataSize - adjLen), adjLen);
            } catch (EOFException eof) {
              ChiLogger.getLogger("engine").info("Error: Tried to read past file: " + dataStart + " --- " + (dataStart + dataSize));
                // But continue
            }
        } else {
            if (lastQuery > _vertexSt) {
                lastId = -1;
                degreeFile.seek(0);
            }

            try {
                while(true) {
                    int vertexId = (lastId < 0 ? degreeFile.readInt() : lastId);
                    if (vertexId >= _vertexSt && vertexId <= _vertexEn) {
                        degreeFile.readFully(degreeData, (vertexId - vertexSt) * 8, 8);
                        VertexDegree deg = getDegree(vertexId);
                        lastId = -1;
                    } else if (vertexId > vertexEn){
                        lastId = vertexId; // Remember last one read
                        break;
                    } else {
                        degreeFile.skipBytes(8);
                    }
                }
            } catch (EOFException eof) {
                degreeFile.seek(0);
            }
            lastQuery = _vertexEn;
        }
    }

    /**
     * Returns degree of a vertex. The vertex must be in the previous
     * interval loaded using load().
     * @param vertexId id of the vertex
     * @return  VertexDegree object
     */
    public VertexDegree getDegree(int vertexId) {
        assert(vertexId >= vertexSt && vertexId <= vertexEn);

        byte[] tmp = new byte[4];
        int idx = vertexId - vertexSt;
        System.arraycopy(degreeData, idx * 8, tmp, 0, 4);

        int indeg = ((tmp[3& 0xff) << 24) + ((tmp[2] & 0xff) << 16) + ((tmp[1] & 0xff) << 8) + (tmp[0] & 0xff);

        System.arraycopy(degreeData, idx * 8 + 4, tmp, 0, 4);
        int outdeg = ((tmp[3& 0xff) << 24) + ((tmp[2] & 0xff) << 16) + ((tmp[1] & 0xff) << 8) + (tmp[0] & 0xff);

        return new VertexDegree(indeg, outdeg);
    }
}
TOP

Related Classes of edu.cmu.graphchi.engine.auxdata.DegreeData

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.