IntArrayGrid.java |
/* Copyright (C) 2009 CSE,IIT Bombay http://www.cse.iitb.ac.in This file is part of the ConStore open source storage facility for concept-nets. ConStore is free software and distributed under the Creative Commons Attribution-Noncommercial-No Derivative Works 3.0 Unported License; you can copy, distribute and transmit the work with the work attribution in the manner specified by the author or licensor. You may not use this work for commercial purposes and may not alter, transform, or build upon this work. Please refer the legal code of the license, available at http://creativecommons.org/licenses/by-nc-nd/3.0/legalcode ConStore is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. */ package iitb.con.util; import iitb.con.util.Int2DBinarySearch; import iitb.con.util.Int2DHeapSort; import java.nio.ByteBuffer; /** * IntArrayGrid is a unbound grid structure for integer values. * The number of columns in the grid is fixed at creation time, * while the rows are unbound. ArrayGrid is limited with the size of * 4KB (by default), since it is useful to store in the disk. * * @author Prathab K * */ public class IntArrayGrid { /** Size of the BLOCK */ public static final int BLOCK_SIZE = 4096; /** Integer size */ private static final int INT_SIZE = 4; /** Id for the array grid */ public int id; /** Maximum entries in the grid based on number of rows and cols*/ private int maxEntries; /** Number of entries present in the grid */ public int length; /** Number of columns */ private int colNum; /** Array declaration for grid */ private int[][] grid; /** * Initializes with id and number of columns * @param id id for the array grid; will be useful if a program uses multiple grids * @param cols number of columns */ public IntArrayGrid(int id, int cols) { this.id = id; maxEntries = (BLOCK_SIZE / (cols * INT_SIZE)) - 1; grid = new int[maxEntries + 1][cols]; grid[0][0] = 0; // grid[0][0] stores the number of entries colNum = cols; } /** * Initializes with id and number of columns and the byte buffer is used * to initial the values in the grid; will be useful if user is reading * the data from the disk and constructing the array grid * @param id id for the array grid; will be useful if a program uses multiple grids * @param cols number of columns * @param buf array grid's bytebuffer */ public IntArrayGrid(int id, int cols, ByteBuffer buf) { this.id = id; buf.rewind(); int numEntries = buf.getInt(); maxEntries = (BLOCK_SIZE / (cols * INT_SIZE)) - 1; grid = new int[maxEntries + 1][cols]; buf.rewind(); for(int i = 0; i < numEntries; i++) for(int j = 0 ; j < cols ;j++) grid[i][j] = buf.getInt(); colNum = cols; length = numEntries; } /** * Sorts the grid based on the first column value */ public void sort() { Int2DHeapSort.sort(grid); } /** * Adds the values for a row to the grid * @param values variable number of values based on the column size * @return row location on success, else return -1 */ public int add(int ... values) { if(length <= maxEntries) { for(int i = 0; i < values.length ; i++) grid[length][i] = values[i]; length++; grid[0][0] = length; return (length - 1); } return -1; } /** * Returns the row as integer array based on the given key * match with first column.<br> * Returns first match in case of duplicate keys. * @param key key value to be searched * @return the row as integer array on match, else <tt>NULL</tt> */ public int[] getRowByBinarySearch(int key) { int index = Int2DBinarySearch.locate(grid, key, 0); if(index >= 0) return grid[index]; return null; } /** * Returns the rows as 2d integer array based on the given key * match with the specified column.<br> * @param key key value to be searched * @param col the column to be searched * @return the row as 2d integer array on match, else <tt>NULL</tt> */ public int[][] getRows(int key, int col) { int count = 0; int[][] r = null; for(int i = 0; i < length; i++) if(key == grid[i][col]) count++; if(count == 0) return r; r = new int[count][colNum]; count = 0; for(int i = 0; i < length; i++) if(key == grid[i][col]) { r[count++] = grid[i]; } return r; } /** * Sets the row value based on the matching value in the grid * @param key key to be matched * @param matchCol column used for matching * @param values values to be set * @return <tt>true</tt> on success */ public boolean setRow(int key, int matchCol, int ... values) { for(int i = 0; i < length; i++) if(key == grid[i][matchCol]) return setRowByIndex(i, values); return false; } /** * Sets the row value for the specified row index * @param index row index * @param values values to set * @return <tt>true</tt> on success */ private boolean setRowByIndex(int index, int ... values) { for(int i = 0; i < values.length ; i++) grid[index][i] = values[i]; return true; } /** * Returns the array grid contents as bytes * @return array grid contents as {@link ByteBuffer} */ public ByteBuffer toBuffer() { ByteBuffer buffer = ByteBuffer.allocate(BLOCK_SIZE); int numEntries = grid[0][0]; for(int i = 0; i < numEntries; i++) for(int j = 0 ; j < colNum ;j++) buffer.putInt(grid[i][j]); return buffer; } /** * Returns the column for the specified index * @param index column index * @return column as integer array */ public int[] getCol(int index) { if(index >= colNum) return null; int[] a = new int[length]; for(int i = 0; i < length; i++) { a[i] = grid[i][index]; } return a; } /** * Prints the contents of array grid */ public void dump() { for(int i = 0; i < length; i++) { System.out.print("[ "); for(int j = 0; j < colNum; j++) System.out.print( grid[i][j] + ","); System.out.print(" ]\n"); } } }