/** * free method declaration * <P>This method marks space in the database file as free. * <P><B>Note: </B>If more than MAX_FREE_COUNT free positios then * they are probably all are too small anyway; so we start a new list * <P>todo: This is wrong when deleting lots of records * * @param r (Row object to be marked free) * @param pos (Offset in the file this Row was stored at) * @param length (Size of the Row object to free) * * @throws Exception */ public void free(Row r, int pos, int length) { iFreeCount++; CacheFree n = new CacheFree(); n.iPos = pos; n.iLength = length; if (iFreeCount > MAX_FREE_COUNT) { iFreeCount = 0; } else { n.fNext = fRoot; } fRoot = n; // it's possible to remove roots to remove(r); }
/** * add method declaration * <P>This method adds a Row to the Cache. It walks the * list of CacheFree objects to see if there is available space * to store the new Row, reusing space if it exists, otherwise * we grow the file. * * @param r (Row to be added to Cache) * * @throws Exception */ public void add(Row r) { int size = r.iSize; CacheFree f = fRoot; CacheFree last = null; int i = iFreePos; while (f != null) { if (Trace.TRACE) { Trace.stop(); } // first that is long enough if (f.iLength >= size) { i = f.iPos; size = f.iLength - size; if (size < 8) { // remove almost empty blocks if (last == null) { fRoot = f.fNext; } else { last.fNext = f.fNext; } iFreeCount--; } else { f.iLength = size; f.iPos += r.iSize; } break; } last = f; f = f.fNext; } r.iPos = i; if (i == iFreePos) { iFreePos += size; } int k = i & MASK; Row before = rData[k]; if (before == null) { before = rFirst; } r.insert(before); iCacheSize++; rData[k] = r; rFirst = r; }