/* * The contents of this file are subject to the Mozilla Public License * Version 1.1 (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.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See * the License for the specific language governing rights and limitations * under the License. * * The Original Code is the Kowari Metadata Store. * * The Initial Developer of the Original Code is Plugged In Software Pty * Ltd (http://www.pisoftware.com, mailto:info@pisoftware.com). Portions * created by Plugged In Software Pty Ltd are Copyright (C) 2001,2002 * Plugged In Software Pty Ltd. All Rights Reserved. * * Contributor(s): N/A. * * [NOTE: The text of this Exhibit A may differ slightly from the text * of the notices in the Source Code files of the Original Code. You * should use the text of this Exhibit A rather than the text found in the * Original Code Source Code for Your Modifications.] * */ package org.mulgara.store.tuples; import org.apache.log4j.Logger; import org.mulgara.query.TuplesException; /** * A dense matrix class that stores long values. Uses a single dimension * array for storage to avoid nested allocations for large matrixes. All * access is bounds checked. * * @author <a href="http://staff.pisoftware.com/andrae/">Andrae Muys</a> * @copyright ©2001 <a href="http://www.pisoftware.com/">Plugged In * Software Pty Ltd</a> * @licence <a href="{@docRoot}/../../LICENCE">Mozilla Public License v1.1</a> */ public class DenseLongMatrix { private final static Logger logger = Logger.getLogger(DenseLongMatrix.class); private long[] matrix; private int rows; private int columns; // Used for sort. private long[] pivotRow; private long[] tmpRow; public DenseLongMatrix(int rows, int columns) { this.rows = rows; this.columns = columns; this.matrix = new long[rows * columns]; this.pivotRow = new long[columns]; this.tmpRow = new long[columns]; // logger.warn("Created matrix " + rows + " rows and " + columns + " columns"); } public long get(int row, int column) { // logger.warn("Getting (" + row + ", " + column + ")"); return matrix[getIndex(row, column)]; } public void set(int row, int column, long value) { // logger.warn("Setting (" + row + ", " + column + ") -> " + value); matrix[getIndex(row, column)] = value; } public int getLength() { // logger.warn("getting length -> " + rows); return rows; } public int getWidth() { // logger.warn("getting width -> " + columns); return columns; } public void sort(RowComparator comparator, int size) throws TuplesException { // logger.warn("sorting matrix"); qsort(comparator, 0, size); // logger.warn("sorted matrix"); } private void qsort(RowComparator comparator, int start, int end) throws TuplesException { if (end - start < 2) { return; } int pivot = partition(comparator, start, end); /* If pivot <= start + 1, then (start, pivot) form a sorted pair */ if (pivot > (start + 1)) { qsort(comparator, start, pivot); } /* Last element is end - 1; if pivot <= last - 1, then (pivot, last) form a sorted pair */ if (pivot < (end - 2)) { qsort(comparator, pivot + 1, end); } } public long[] loadRow(long[] line, int row) { // logger.warn("loading row " + row); if (line == null) { line = new long[columns]; } for (int i = 0; i < columns; i++) { line[i] = get(row, i); } return line; } private int partition(RowComparator comparator, int start, int end) throws TuplesException { final int size = end - start; int pivot = (size / 2) + start; int lhs = start; int rhs = end - 1; for (;;) { loadRow(pivotRow, pivot); while ((lhs < pivot) && (comparator.compare(pivotRow, loadRow(tmpRow, lhs)) > 0)) { lhs++; } while ((rhs > pivot) && (comparator.compare(pivotRow, loadRow(tmpRow, rhs)) < 0)) { rhs--; } if (lhs >= rhs) { return pivot; } swap(lhs, rhs); if (lhs == pivot) { lhs++; pivot = rhs; } else if (rhs == pivot) { pivot = lhs; rhs--; } else { lhs++; rhs--; } } } private void swap(int left, int right) { for (int i = 0; i < columns; i++) { long temp = get(left, i); set(left, i, get(right, i)); set(right, i, temp); } } private int getIndex(int row, int column) { if (row >= rows) { throw new ArrayIndexOutOfBoundsException("Matrix row index(" + row + ") requires (0," + rows + "]"); } else if (column >= columns) { throw new ArrayIndexOutOfBoundsException("Matrix row index(" + column + ") requires (0," + columns + "]"); } return row * columns + column; } }