Main Page   Packages   Class Hierarchy   Compound List   File List   Compound Members  

RingMatrix.java

00001 /*
00002  *  Copyright 2006-2007 Columbia University.
00003  *
00004  *  This file is part of MEAPsoft.
00005  *
00006  *  MEAPsoft is free software; you can redistribute it and/or modify
00007  *  it under the terms of the GNU General Public License version 2 as
00008  *  published by the Free Software Foundation.
00009  *
00010  *  MEAPsoft is distributed in the hope that it will be useful, but
00011  *  WITHOUT ANY WARRANTY; without even the implied warranty of
00012  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013  *  General Public License for more details.
00014  *
00015  *  You should have received a copy of the GNU General Public License
00016  *  along with MEAPsoft; if not, write to the Free Software
00017  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
00018  *  02110-1301 USA
00019  *
00020  *  See the file "COPYING" for the text of the license.
00021  */
00022 
00023 package com.meapsoft;
00024 
00025 import java.util.Stack;
00035 public class RingMatrix {
00036   double[][] M;
00037   int writePos;
00038   long nextFrAddr;
00039 
00040   // Keep some extra double[]s around so we don't have to keep
00041   // allocating new ones.  For thread safety, use a semaphore to keep
00042   // track of the number of buffers in use.
00043   Stack doubleBuffers = new Stack();
00044   int dbPoolSize = 4;
00045 
00046   public RingMatrix(int rows, int columns) {
00047     M = new double[columns][rows];
00048 
00049     for(int i=0; i<dbPoolSize; i++)
00050       doubleBuffers.push(new double[rows]);
00051 
00052     for(int i=0; i<columns; i++)
00053       for(int j=0; j<rows; j++)
00054         M[i][j] = 0;
00055 
00056     writePos = 0;
00057     nextFrAddr = 0;
00058   }
00059 
00060   // Get a pre-allocated double[] from a pool.  If one is not
00061   // available, block until it is.  Array is not guaranteed to contain
00062   // anything in particular.
00063   public synchronized double[] checkOutColumn() {
00064 
00065     while(doubleBuffers.empty()) {
00066       try {
00067         wait();
00068       } catch(InterruptedException ie) {
00069         ie.printStackTrace();
00070       }
00071     }
00072     double[] column = (double[]) doubleBuffers.pop();
00073 
00074     return column;
00075   }
00076 
00077   // Check in a previously checked out double buffer.  Inserts the db
00078   // into the matrix, but at the same time puts the double[] it's
00079   // replacing back in the pool of double buffers.
00080   public synchronized long checkInColumn(double[] db) {
00081     // remember the replaced array
00082     double[] replaced = M[writePos];
00083 
00084     // do the replacement
00085     M[writePos++] = db;
00086     writePos %= M.length;
00087     long frAddr = nextFrAddr++;
00088     
00089     // put the replaced array back in the pool as long as it's not the
00090     // same array
00091     if(replaced != db) {
00092       doubleBuffers.push(replaced);
00093       notify();
00094     }
00095 
00096     return frAddr;
00097   }
00098 
00099   // Return a double[] to the pool of double buffers without inserting
00100   // it into the matrix.  Does nothing if the array is the wrong
00101   // length.
00102   public synchronized void returnColumn(double[] db) {
00103     if(db.length != M[0].length)
00104       return;
00105     
00106     doubleBuffers.push(db);
00107     notify();
00108   }
00109   
00110   // Get a column from the matrix.  Throws
00111   // ArrayIndexOutOfBoundsException if the column's address is too
00112   // high (hasn't been written yet) or too low (already overwritten)
00113   public double[] getColumn(long frAddr) {
00114 //     if(frAddr < nextFrAddr-M.length)
00115 //       throw new ArrayIndexOutOfBoundsException("Frame was already overwritten");
00116 //     if(frAddr >= nextFrAddr)
00117 //       throw new ArrayIndexOutOfBoundsException("Frame has not been written yet");
00118 
00119     //if(frAddr < nextFrAddr-M.length || frAddr >= nextFrAddr || frAddr < 0)
00120     // the first condition has an off by 3 (actually a few off by
00121     // one errors from different places that have accumulated -
00122     // M.length is actually bigger than it should be, M.length is
00123     // always off by one compared to nextFrAddr...)  So this fix is
00124     // a hack that ignore a few bugs elsewhere...
00125     if(frAddr < nextFrAddr-M.length-3 || frAddr >= nextFrAddr || frAddr < 0)
00126       return null;
00127 
00128     return M[(int)(frAddr % M.length)];
00129   }
00130 
00131   // Set a column of the matrix. 
00132   public void setColumn(long frAddr, double[] dat) {
00133       M[(int)(frAddr % M.length)] = dat;
00134   }
00135 
00136   public int getRows() { return M[0].length; }
00137   public int getColumns() { return M.length; }
00138   public long getNextFrAddr() { return nextFrAddr; }
00139 }

Generated on Tue Feb 6 19:02:27 2007 for MEAPsoft by doxygen1.2.18