bradford 2002/06/09 12:49:03
Modified: java/src/org/apache/xindice/core/filer BTree.java BTreeFiler.java FSFiler.java HashFiler.java MemFiler.java Paged.java java/src/org/apache/xindice/core/fulltext FullTextIndexer.java java/src/org/apache/xindice/core/indexer NameIndexer.java ValueIndexer.java Log: Some modifications to support better concurrent access and multiple file descriptors accessing the same filer. This is groundwork for a true transaction system. Revision Changes Path 1.5 +127 -100 xml-xindice/java/src/org/apache/xindice/core/filer/BTree.java Index: BTree.java =================================================================== RCS file: /home/cvs/xml-xindice/java/src/org/apache/xindice/core/filer/BTree.java,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- BTree.java 23 Feb 2002 02:33:41 -0000 1.4 +++ BTree.java 9 Jun 2002 19:49:02 -0000 1.5 @@ -56,14 +56,12 @@ * information on the Apache Software Foundation, please see * <http://www.apache.org/>. * - * $Id: BTree.java,v 1.4 2002/02/23 02:33:41 kstaken Exp $ + * $Id: BTree.java,v 1.5 2002/06/09 19:49:02 bradford Exp $ */ import org.apache.xindice.core.*; import org.apache.xindice.core.data.*; import org.apache.xindice.core.indexer.*; -import org.apache.xindice.core.indexer.helpers.*; -import org.apache.xindice.util.*; import java.io.*; import java.util.*; @@ -100,11 +98,11 @@ protected static final byte STREAM = 3; private Map cache = new WeakHashMap(); - + private BTreeFileHeader fileHeader; private BTreeRootInfo rootInfo; private BTreeNode rootNode; - + public BTree() { super(); fileHeader = (BTreeFileHeader)getFileHeader(); @@ -139,12 +137,11 @@ rootNode.setValues(new Value[0]); rootNode.setPointers(new long[0]); rootNode.write(); - flush(); close(); return true; } catch ( Exception e ) { -org.apache.xindice.Debug.printStackTrace(e); + org.apache.xindice.Debug.printStackTrace(e); } } return false; @@ -178,7 +175,7 @@ public long addValue(BTreeRootInfo root, Value value, long pointer) throws IOException, BTreeException { return getRootNode(root).addValue(value, pointer); } - + /** * removeValue removes a Value from the BTree and returns the * associated pointer for it. @@ -201,7 +198,7 @@ public long removeValue(BTreeRootInfo root, Value value) throws IOException, BTreeException { return getRootNode(root).removeValue(value); } - + /** * findValue finds a Value in the BTree and returns the associated * pointer for it. @@ -224,7 +221,7 @@ public long findValue(BTreeRootInfo root, Value value) throws IOException, BTreeException { return getRootNode(root).findValue(value); } - + /** * query performs a query against the BTree and performs callback * operations to report the search results. @@ -258,7 +255,7 @@ protected final BTreeRootInfo createBTreeRoot(Value v) throws IOException, BTreeException { BTreeNode n = createBTreeNode(rootInfo, BTree.LEAF, null); n.write(); - + long position = n.page.getPageNum(); addValue(v, position); return new BTreeRootInfo(v, position); @@ -275,7 +272,7 @@ protected final BTreeRootInfo createBTreeRoot(BTreeRootInfo root, Value v) throws IOException, BTreeException { BTreeNode n = createBTreeNode(root, BTree.LEAF, null); n.write(); - + long position = n.page.getPageNum(); addValue(v, position); return new BTreeRootInfo(root, v, position); @@ -306,7 +303,7 @@ long position = findValue(root, v); return new BTreeRootInfo(root, v, position); } - + /** * setRootNode resets the root for the specified root object to the * provided BTreeNode's page number. @@ -361,19 +358,27 @@ protected final BTreeNode getRootNode() { return rootNode; } - + private BTreeNode getBTreeNode(BTreeRootInfo root, long page, BTreeNode parent) { try { - Long pNum = new Long(page); - BTreeNode node = (BTreeNode)cache.get(pNum); - if ( node == null ) { - Page p = getPage(pNum); - node = new BTreeNode(root, p, parent); - node.read(); + BTreeNode node; + synchronized ( this ) { + Long pNum = new Long(page); + node = (BTreeNode)cache.get(pNum); + if ( node == null ) { + Page p = getPage(pNum); + node = new BTreeNode(root, p, parent); + } + else { + node.root = root; + node.parent = parent; + } } - else { - node.root = root; - node.parent = parent; + synchronized ( node ) { + if ( !node.isLoaded() ) { + node.read(); + node.setLoaded(true); + } } return node; } @@ -395,8 +400,8 @@ return null; } } - - + + /** * BTreeRootInfo */ @@ -417,7 +422,7 @@ this.name = name; this.page = page; } - + public BTreeRootInfo(String name, long page) { this.parent = rootInfo; this.name = new Value(name); @@ -429,31 +434,31 @@ this.name = name; this.page = page; } - + private BTreeRootInfo(long page) { parent = null; name = null; this.page = page; } - public BTreeRootInfo getParent() { + public synchronized BTreeRootInfo getParent() { return parent; } - - public Value getName() { + + public synchronized Value getName() { return name; } - - public long getPage() { + + public synchronized long getPage() { return page; } - - public void setPage(long page) { + + public synchronized void setPage(long page) { this.page = page; } } - + /** * BTreeNode */ @@ -465,6 +470,7 @@ private Value[] values; private long[] ptrs; private BTreeNode parent; + private boolean loaded; public BTreeNode(BTreeRootInfo root, Page page, BTreeNode parent) { this.root = root; @@ -472,31 +478,39 @@ this.parent = parent; ph = (BTreePageHeader)page.getPageHeader(); } - + public BTreeNode(BTreeRootInfo root, Page page) { this.root = root; this.page = page; ph = (BTreePageHeader)page.getPageHeader(); } - public void setValues(Value[] values) { + public synchronized void setValues(Value[] values) { this.values = values; ph.setValueCount((short)values.length); } - public Value[] getValues() { + public synchronized Value[] getValues() { return values; } - public void setPointers(long[] ptrs) { + public synchronized void setPointers(long[] ptrs) { this.ptrs = ptrs; } - public long[] getPointers() { + public synchronized long[] getPointers() { return ptrs; } - public void read() throws IOException { + public synchronized boolean isLoaded() { + return loaded; + } + + public synchronized void setLoaded(boolean loaded) { + this.loaded = loaded; + } + + public synchronized void read() throws IOException { Value v = readValue(page); DataInputStream is = new DataInputStream(v.getInputStream()); @@ -514,11 +528,11 @@ ptrs = new long[ph.getPointerCount()]; for ( int i = 0; i < ptrs.length; i++ ) ptrs[i] = is.readLong(); - + cache.put(new Long(page.getPageNum()), this); } - public void write() throws IOException { + public synchronized void write() throws IOException { ByteArrayOutputStream bos = new ByteArrayOutputStream((int)fileHeader.getWorkSize()); DataOutputStream os = new DataOutputStream(bos); @@ -531,20 +545,35 @@ // Write out the pointers for ( int i = 0; i < ptrs.length; i++ ) os.writeLong(ptrs[i]); - + writeValue(page, new Value(bos.toByteArray())); - + cache.put(new Long(page.getPageNum()), this); } public BTreeNode getChildNode(int idx) throws IOException { - if ( ph.getStatus() == BRANCH && idx >= 0 && idx < ptrs.length ) - return getBTreeNode(root, ptrs[idx], this); + boolean load; + BTreeRootInfo loadNode; + long loadPtr; + synchronized ( this ) { + if ( ph.getStatus() == BRANCH && idx >= 0 && idx < ptrs.length ) { + load = true; + loadNode = root; + loadPtr = ptrs[idx]; + } + else { + load = false; + loadNode = null; + loadPtr = 0; + } + } + if ( load ) + return getBTreeNode(loadNode, loadPtr, this); else return null; } - public void getChildStream(int idx, Streamable stream) throws IOException { + public synchronized void getChildStream(int idx, Streamable stream) throws IOException { if ( ph.getStatus() == LEAF && idx >= 0 && idx < ptrs.length ) { Value v = readValue(ptrs[idx]); DataInputStream dis = new DataInputStream(v.getInputStream()); @@ -552,16 +581,16 @@ } } - public long removeValue(Value value) throws IOException, BTreeException { + public synchronized long removeValue(Value value) throws IOException, BTreeException { int idx = Arrays.binarySearch(values, value); switch ( ph.getStatus() ) { case BRANCH: - idx = idx < 0 ? -(idx+1) : idx+1; + idx = idx < 0 ? -(idx + 1) : idx + 1; return getChildNode(idx).removeValue(value); case LEAF: if ( idx < 0 ) - throw new BTreeNotFoundException("Value '"+value.toString()+"' doesn't exist"); + throw new BTreeNotFoundException("Value '" + value.toString() + "' doesn't exist"); else { long oldPtr = ptrs[idx]; @@ -577,12 +606,12 @@ } } - public long addValue(Value value, long pointer) throws IOException, BTreeException { + public synchronized long addValue(Value value, long pointer) throws IOException, BTreeException { int idx = Arrays.binarySearch(values, value); switch ( ph.getStatus() ) { case BRANCH: - idx = idx < 0 ? -(idx+1) : idx+1; + idx = idx < 0 ? -(idx + 1) : idx + 1; return getChildNode(idx).addValue(value, pointer); case LEAF: @@ -590,19 +619,19 @@ // Value was found... Overwrite long oldPtr = ptrs[idx]; ptrs[idx] = pointer; - + setValues(values); setPointers(ptrs); - + write(); return oldPtr; } else { // Value was not found - idx = -(idx+1); + idx = -(idx + 1); // Check to see if we've exhausted the block - boolean split = ph.getDataLen()+6+value.getLength() > fileHeader.getWorkSize(); + boolean split = ph.getDataLen() + 6 + value.getLength() > fileHeader.getWorkSize(); setValues(insertArrayValue(values, value, idx)); setPointers(insertArrayLong(ptrs, pointer, idx)); @@ -619,15 +648,15 @@ } } - public void promoteValue(Value value, long rightPointer) throws IOException, BTreeException { + public synchronized void promoteValue(Value value, long rightPointer) throws IOException, BTreeException { // Check to see if we've exhausted the block - boolean split = ph.getDataLen()+6+value.getLength() > fileHeader.getWorkSize(); + boolean split = ph.getDataLen() + 6 + value.getLength() > fileHeader.getWorkSize(); int idx = Arrays.binarySearch(values, value); - idx = idx < 0 ? -(idx+1) : idx+1; + idx = idx < 0 ? -(idx + 1) : idx + 1; setValues(insertArrayValue(values, value, idx)); - setPointers(insertArrayLong(ptrs, rightPointer, idx+1)); + setPointers(insertArrayLong(ptrs, rightPointer, idx + 1)); if ( split ) split(); @@ -642,7 +671,7 @@ return new Value(b); } - public void split() throws IOException, BTreeException { + public synchronized void split() throws IOException, BTreeException { Value[] leftVals; Value[] rightVals; long[] leftPtrs; @@ -656,13 +685,13 @@ switch ( ph.getStatus() ) { case BRANCH: leftVals = new Value[pivot]; - leftPtrs = new long[leftVals.length+1]; - rightVals = new Value[vc-(pivot+1)]; - rightPtrs = new long[rightVals.length+1]; + leftPtrs = new long[leftVals.length + 1]; + rightVals = new Value[vc - (pivot + 1)]; + rightPtrs = new long[rightVals.length + 1]; System.arraycopy(values, 0, leftVals, 0, leftVals.length); System.arraycopy(ptrs, 0, leftPtrs, 0, leftPtrs.length); - System.arraycopy(values, leftVals.length+1, rightVals, 0, rightVals.length); + System.arraycopy(values, leftVals.length + 1, rightVals, 0, rightVals.length); System.arraycopy(ptrs, leftPtrs.length, rightPtrs, 0, rightPtrs.length); separator = values[leftVals.length]; @@ -671,7 +700,7 @@ case LEAF: leftVals = new Value[pivot]; leftPtrs = new long[leftVals.length]; - rightVals = new Value[vc-pivot]; + rightVals = new Value[vc - pivot]; rightPtrs = new long[rightVals.length]; System.arraycopy(values, 0, leftVals, 0, leftVals.length); @@ -679,7 +708,7 @@ System.arraycopy(values, leftVals.length, rightVals, 0, rightVals.length); System.arraycopy(ptrs, leftPtrs.length, rightPtrs, 0, rightPtrs.length); - separator = getSeparator(leftVals[leftVals.length-1], rightVals[0]); + separator = getSeparator(leftVals[leftVals.length - 1], rightVals[0]); break; default: @@ -698,13 +727,13 @@ rNode.setValues(rightVals); rNode.setPointers(rightPtrs); - np.setValues(new Value[] { separator }); - np.setPointers(new long[] { page.getPageNum(), rNode.page.getPageNum()}); + np.setValues(new Value[]{separator}); + np.setPointers(new long[]{page.getPageNum(), rNode.page.getPageNum()}); parent = np; - + setRootNode(root, np); - + write(); rNode.write(); np.write(); @@ -722,17 +751,17 @@ ///////////////////////////////////////////////////////////////// - public long findValue(Value value) throws IOException, BTreeException { + public synchronized long findValue(Value value) throws IOException, BTreeException { int idx = Arrays.binarySearch(values, value); switch ( ph.getStatus() ) { case BRANCH: - idx = idx < 0 ? -(idx+1) : idx+1; + idx = idx < 0 ? -(idx + 1) : idx + 1; return getChildNode(idx).findValue(value); case LEAF: if ( idx < 0 ) - throw new BTreeNotFoundException("Value '"+value.toString()+"' doesn't exist"); + throw new BTreeNotFoundException("Value '" + value.toString() + "' doesn't exist"); else return ptrs[idx]; @@ -742,18 +771,18 @@ } // query is a BEAST of a method - public void query(IndexQuery query, BTreeCallback callback) throws IOException, BTreeException { + public synchronized void query(IndexQuery query, BTreeCallback callback) throws IOException, BTreeException { if ( query != null && query.getOperator() != IndexQuery.ANY ) { Value[] qvals = query.getValues(); int leftIdx = Arrays.binarySearch(values, qvals[0]); - int rightIdx = qvals.length > 1 ? Arrays.binarySearch(values, qvals[qvals.length-1]) - : leftIdx; + int rightIdx = qvals.length > 1 ? Arrays.binarySearch(values, qvals[qvals.length - 1]) + : leftIdx; int op = query.getOperator(); - + switch ( ph.getStatus() ) { case BRANCH: - leftIdx = leftIdx < 0 ? -(leftIdx+1) : leftIdx+1; - rightIdx = rightIdx < 0 ? -(rightIdx+1) : rightIdx+1; + leftIdx = leftIdx < 0 ? -(leftIdx + 1) : leftIdx + 1; + rightIdx = rightIdx < 0 ? -(rightIdx + 1) : rightIdx + 1; switch ( query.getOperator() ) { case IndexQuery.BWX: @@ -818,30 +847,30 @@ case IndexQuery.SW: case IndexQuery.IN: if ( leftIdx < 0 ) - leftIdx = -(leftIdx+1); + leftIdx = -(leftIdx + 1); if ( rightIdx < 0 ) - rightIdx = -(rightIdx+1); + rightIdx = -(rightIdx + 1); for ( int i = 0; i < ptrs.length; i++ ) if ( i >= leftIdx && i <= rightIdx && query.testValue(values[i]) ) - callback.indexInfo(values[i], ptrs[i]); + callback.indexInfo(values[i], ptrs[i]); break; case IndexQuery.NBWX: case IndexQuery.NBW: case IndexQuery.NSW: if ( leftIdx < 0 ) - leftIdx = -(leftIdx+1); + leftIdx = -(leftIdx + 1); if ( rightIdx < 0 ) - rightIdx = -(rightIdx+1); + rightIdx = -(rightIdx + 1); for ( int i = 0; i < ptrs.length; i++ ) if ( (i <= leftIdx || i >= rightIdx) && query.testValue(values[i]) ) - callback.indexInfo(values[i], ptrs[i]); + callback.indexInfo(values[i], ptrs[i]); break; case IndexQuery.LT: case IndexQuery.LEQ: if ( leftIdx < 0 ) - leftIdx = -(leftIdx+1); + leftIdx = -(leftIdx + 1); for ( int i = 0; i < ptrs.length; i++ ) if ( i <= leftIdx && query.testValue(values[i]) ) callback.indexInfo(values[i], ptrs[i]); @@ -850,7 +879,7 @@ case IndexQuery.GT: case IndexQuery.GEQ: if ( rightIdx < 0 ) - rightIdx = -(rightIdx+1); + rightIdx = -(rightIdx + 1); for ( int i = 0; i < ptrs.length; i++ ) if ( i >= rightIdx && query.testValue(values[i]) ) callback.indexInfo(values[i], ptrs[i]); @@ -935,24 +964,24 @@ super(read); } - public void read(RandomAccessFile raf) throws IOException { + public synchronized void read(RandomAccessFile raf) throws IOException { super.read(raf); rootPage = raf.readLong(); } - public void write(RandomAccessFile raf) throws IOException { + public synchronized void write(RandomAccessFile raf) throws IOException { super.write(raf); raf.writeLong(rootPage); } /** The root page of the storage tree */ - public final void setRootPage(long rootPage) { + public synchronized final void setRootPage(long rootPage) { this.rootPage = rootPage; setDirty(); } /** The root page of the storage tree */ - public final long getRootPage() { + public synchronized final long getRootPage() { return rootPage; } } @@ -972,7 +1001,7 @@ super(dis); } - public void read(DataInputStream dis) throws IOException { + public synchronized void read(DataInputStream dis) throws IOException { super.read(dis); if ( getStatus() == UNUSED ) @@ -981,24 +1010,24 @@ valueCount = dis.readShort(); } - public void write(DataOutputStream dos) throws IOException { + public synchronized void write(DataOutputStream dos) throws IOException { super.write(dos); dos.writeShort(valueCount); } /** The number of values stored by this page */ - public final void setValueCount(short valueCount) { + public synchronized final void setValueCount(short valueCount) { this.valueCount = valueCount; setDirty(); } /** The number of values stored by this page */ - public final short getValueCount() { + public synchronized final short getValueCount() { return valueCount; } /** The number of pointers stored by this page */ - public final short getPointerCount() { + public synchronized final short getPointerCount() { if ( getStatus() == BRANCH ) return (short)(valueCount + 1); else @@ -1006,5 +1035,3 @@ } } } - - 1.2 +35 -37 xml-xindice/java/src/org/apache/xindice/core/filer/BTreeFiler.java Index: BTreeFiler.java =================================================================== RCS file: /home/cvs/xml-xindice/java/src/org/apache/xindice/core/filer/BTreeFiler.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- BTreeFiler.java 6 Dec 2001 21:00:12 -0000 1.1 +++ BTreeFiler.java 9 Jun 2002 19:49:02 -0000 1.2 @@ -56,13 +56,13 @@ * information on the Apache Software Foundation, please see * <http://www.apache.org/>. * - * $Id: BTreeFiler.java,v 1.1 2001/12/06 21:00:12 bradford Exp $ + * $Id: BTreeFiler.java,v 1.2 2002/06/09 19:49:02 bradford Exp $ */ -import org.apache.xindice.util.*; -import org.apache.xindice.core.*; import org.apache.xindice.core.Collection; +import org.apache.xindice.core.*; import org.apache.xindice.core.data.*; +import org.apache.xindice.util.*; import java.io.*; import java.util.*; @@ -95,7 +95,7 @@ } public void setLocation(String location) { - setFile(new File(collection.getCollectionRoot(), location+".tbl")); + setFile(new File(collection.getCollectionRoot(), location + ".tbl")); } public String getName() { @@ -123,18 +123,18 @@ setLocation(collection.getName()); } - public synchronized Record readRecord(Key key) throws DBException { + public Record readRecord(Key key) throws DBException { checkOpened(); try { long pos = findValue(key); Page startPage = getPage(pos); Value v = readValue(startPage); BTreeFilerPageHeader sph = (BTreeFilerPageHeader)startPage.getPageHeader(); - + HashMap meta = new HashMap(2); meta.put(Record.CREATED, new Long(sph.getCreated())); meta.put(Record.MODIFIED, new Long(sph.getModified())); - + return new Record(key, v, meta); } catch ( BTreeNotFoundException b ) { @@ -148,7 +148,7 @@ return null; } - public synchronized boolean writeRecord(Key key, Value value) throws DBException { + public boolean writeRecord(Key key, Value value) throws DBException { checkOpened(); try { Page p; @@ -166,12 +166,12 @@ long t = System.currentTimeMillis(); if ( ph.getStatus() == UNUSED ) ph.setCreated(t); - + ph.setModified(t); ph.setStatus(RECORD); writeValue(p, value); - + flush(); } catch ( DBException d ) { @@ -183,7 +183,7 @@ return true; } - public synchronized boolean deleteRecord(Key key) throws DBException { + public boolean deleteRecord(Key key) throws DBException { checkOpened(); try { long pos = findValue(key); @@ -191,11 +191,11 @@ removeValue(key); unlinkPages(p.getPageNum()); - + fileHeader.decRecordCount(); flush(); - + return true; } catch ( BTreeNotFoundException b ) { @@ -209,21 +209,21 @@ return false; } - public synchronized long getRecordCount() throws DBException { + public long getRecordCount() throws DBException { checkOpened(); return fileHeader.getRecordCount(); } - public synchronized RecordSet getRecordSet() throws DBException { + public RecordSet getRecordSet() throws DBException { checkOpened(); return new BTreeFilerRecordSet(); } - public synchronized void flush() throws DBException { + public void flush() throws DBException { super.flush(); } - - + + /** * BTreeFilerRecordSet */ @@ -242,24 +242,24 @@ } } - public boolean indexInfo(Value value, long pointer) { + public synchronized boolean indexInfo(Value value, long pointer) { keys.add(new Key(value)); return true; } - public Key getNextKey() { + public synchronized Key getNextKey() { return (Key)enum.next(); } - public Record getNextRecord() throws DBException { + public synchronized Record getNextRecord() throws DBException { return readRecord((Key)enum.next()); } - public Value getNextValue() throws DBException { + public synchronized Value getNextValue() throws DBException { return getNextRecord().getValue(); } - public boolean hasMoreRecords() { + public synchronized boolean hasMoreRecords() { return enum.hasNext(); } } @@ -309,24 +309,24 @@ super(read); } - public void read(RandomAccessFile raf) throws IOException { + public synchronized void read(RandomAccessFile raf) throws IOException { super.read(raf); totalBytes = raf.readLong(); } - public void write(RandomAccessFile raf) throws IOException { + public synchronized void write(RandomAccessFile raf) throws IOException { super.write(raf); raf.writeLong(totalBytes); } /** The total number of bytes in use by the file */ - public void setTotalBytes(long totalBytes) { + public synchronized void setTotalBytes(long totalBytes) { this.totalBytes = totalBytes; setDirty(); } /** The total number of bytes in use by the file */ - public long getTotalBytes() { + public synchronized long getTotalBytes() { return totalBytes; } } @@ -346,7 +346,7 @@ super(dis); } - public void read(DataInputStream dis) throws IOException { + public synchronized void read(DataInputStream dis) throws IOException { super.read(dis); if ( getStatus() == UNUSED ) @@ -356,38 +356,36 @@ modified = dis.readLong(); } - public void write(DataOutputStream dos) throws IOException { + public synchronized void write(DataOutputStream dos) throws IOException { super.write(dos); dos.writeLong(created); dos.writeLong(modified); } - public void setRecordLen(int recordLen) { - synchronized(fileHeader) { - fileHeader.setTotalBytes((fileHeader.totalBytes - getRecordLen()) + recordLen); - } + public synchronized void setRecordLen(int recordLen) { + fileHeader.setTotalBytes((fileHeader.totalBytes - getRecordLen()) + recordLen); super.setRecordLen(recordLen); } /** UNIX-time when this record was created */ - public void setCreated(long created) { + public synchronized void setCreated(long created) { this.created = created; setDirty(); } /** UNIX-time when this record was created */ - public long getCreated() { + public synchronized long getCreated() { return created; } /** UNIX-time when this record was last modified */ - public void setModified(long modified) { + public synchronized void setModified(long modified) { this.modified = modified; setDirty(); } /** UNIX-time when this record was last modified */ - public long getModified() { + public synchronized long getModified() { return modified; } } 1.2 +24 -23 xml-xindice/java/src/org/apache/xindice/core/filer/FSFiler.java Index: FSFiler.java =================================================================== RCS file: /home/cvs/xml-xindice/java/src/org/apache/xindice/core/filer/FSFiler.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- FSFiler.java 6 Dec 2001 21:00:12 -0000 1.1 +++ FSFiler.java 9 Jun 2002 19:49:02 -0000 1.2 @@ -56,13 +56,14 @@ * information on the Apache Software Foundation, please see * <http://www.apache.org/>. * - * $Id: FSFiler.java,v 1.1 2001/12/06 21:00:12 bradford Exp $ + * $Id: FSFiler.java,v 1.2 2002/06/09 19:49:02 bradford Exp $ */ -import org.apache.xindice.core.*; import org.apache.xindice.core.Collection; +import org.apache.xindice.core.*; import org.apache.xindice.core.data.*; import org.apache.xindice.util.*; + import java.io.*; import java.util.*; @@ -79,7 +80,7 @@ private LockManager locks = new LockManager(16); private Set extensions = null; - + private String location; private Collection collection; private File dir; @@ -121,14 +122,14 @@ if ( readOnly ) throw new FilerException(FaultCodes.COL_COLLECTION_READ_ONLY, "Filer is read-only"); } - + public boolean close() { opened = false; return true; } public boolean open() { - opened = ( dir.exists() && dir.isDirectory() ); + opened = (dir.exists() && dir.isDirectory()); return opened; } @@ -151,24 +152,24 @@ else return true; } - + public void flush() { } public Record readRecord(Key key) throws DBException { checkOpened(); - + String fname = key.toString(); if ( !isExtensionValid(fname) ) return null; - + File file = new File(dir, fname); try { locks.acquireSharedLock(file); - + HashMap meta = new HashMap(1); meta.put(Record.MODIFIED, new Long(file.lastModified())); - + byte[] valueData = cache.getFile(file); if ( valueData != null ) return new Record(key, new Value(valueData), meta); @@ -185,11 +186,11 @@ public boolean writeRecord(Key key, Value value) throws DBException { checkOpened(); checkReadOnly(); - + String fname = key.toString(); if ( !isExtensionValid(fname) ) return false; - + File file = new File(dir, fname); try { locks.acquireExclusiveLock(file); @@ -210,11 +211,11 @@ public boolean deleteRecord(Key key) throws DBException { checkOpened(); checkReadOnly(); - + String fname = key.toString(); if ( !isExtensionValid(fname) ) return false; - + File file = new File(dir, fname); try { locks.acquireExclusiveLock(file); @@ -231,7 +232,7 @@ public long getRecordCount() throws DBException { checkOpened(); - + File[] files = dir.listFiles(new FileFilter() { public boolean accept(File file) { return file.isFile() && isExtensionValid(file.getName()); @@ -250,18 +251,18 @@ int idx = fname.lastIndexOf('.'); if ( idx == -1 ) return false; - String ext = fname.substring(idx+1); + String ext = fname.substring(idx + 1); if ( !extensions.contains(ext) ) return false; } return true; } - + /** * FSRecordSet */ - + private class FSRecordSet implements RecordSet { public File[] files; public int pos = 0; @@ -274,20 +275,20 @@ }); } - public boolean hasMoreRecords() { + public synchronized boolean hasMoreRecords() { return pos < files.length; } - public Record getNextRecord() throws DBException { + public synchronized Record getNextRecord() throws DBException { File file = files[pos++]; return readRecord(new Key(file.getName())); } - public Value getNextValue() throws DBException { + public synchronized Value getNextValue() throws DBException { return getNextRecord().getValue(); } - - public Key getNextKey() { + + public synchronized Key getNextKey() { return new Key(files[pos++].getName()); } } 1.2 +49 -60 xml-xindice/java/src/org/apache/xindice/core/filer/HashFiler.java Index: HashFiler.java =================================================================== RCS file: /home/cvs/xml-xindice/java/src/org/apache/xindice/core/filer/HashFiler.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- HashFiler.java 6 Dec 2001 21:00:12 -0000 1.1 +++ HashFiler.java 9 Jun 2002 19:49:02 -0000 1.2 @@ -56,11 +56,11 @@ * information on the Apache Software Foundation, please see * <http://www.apache.org/>. * - * $Id: HashFiler.java,v 1.1 2001/12/06 21:00:12 bradford Exp $ + * $Id: HashFiler.java,v 1.2 2002/06/09 19:49:02 bradford Exp $ */ -import org.apache.xindice.core.*; import org.apache.xindice.core.Collection; +import org.apache.xindice.core.*; import org.apache.xindice.core.data.*; import org.apache.xindice.util.*; @@ -104,8 +104,8 @@ } public void setLocation(String location) { - setFile(new File(collection.getCollectionRoot(), location+".tbl")); - btree = new BTree(new File(collection.getCollectionRoot(), location+".pkx")); + setFile(new File(collection.getCollectionRoot(), location + ".tbl")); + btree = new BTree(new File(collection.getCollectionRoot(), location + ".pkx")); } public String getName() { @@ -145,8 +145,8 @@ p = getPage(pageNum); ph = (HashPageHeader)p.getPageHeader(); if ( ph.getStatus() == RECORD - && ph.getKeyHash() == key.getHash() - && p.getKey().equals(key) ) + && ph.getKeyHash() == key.getHash() + && p.getKey().equals(key) ) return p; pageNum = ph.getNextCollision(); if ( pageNum == -1 ) @@ -162,10 +162,10 @@ while ( true ) { p = getPage(pageNum); ph = (HashPageHeader)p.getPageHeader(); - if ( ( ph.getStatus() == UNUSED || ph.getStatus() == DELETED ) - || ( ph.getStatus() == RECORD - && ph.getKeyHash() == key.getHash() - && p.getKey().equals(key) ) ) + if ( (ph.getStatus() == UNUSED || ph.getStatus() == DELETED) + || (ph.getStatus() == RECORD + && ph.getKeyHash() == key.getHash() + && p.getKey().equals(key)) ) return p; pageNum = ph.getNextCollision(); if ( pageNum == -1 ) { @@ -177,18 +177,18 @@ } } - public synchronized Record readRecord(Key key) throws DBException { + public Record readRecord(Key key) throws DBException { checkOpened(); try { Page startPage = seekRecordPage(key); if ( startPage != null ) { Value v = readValue(startPage); HashPageHeader sph = (HashPageHeader)startPage.getPageHeader(); - + HashMap meta = new HashMap(2); meta.put(Record.CREATED, new Long(sph.getCreated())); meta.put(Record.MODIFIED, new Long(sph.getModified())); - + return new Record(key, v, meta); } } @@ -198,12 +198,12 @@ return null; } - public synchronized boolean writeRecord(Key key, Value value) throws DBException { + public boolean writeRecord(Key key, Value value) throws DBException { checkOpened(); try { Page p = seekInsertionPage(key); HashPageHeader ph = (HashPageHeader)p.getPageHeader(); - + long t = System.currentTimeMillis(); if ( ph.getStatus() == UNUSED ) { // This is a new Record @@ -211,13 +211,13 @@ btree.addValue(key, p.getPageNum()); ph.setCreated(t); } - + ph.setModified(t); ph.setStatus(RECORD); p.setKey(key); writeValue(p, value); - + flush(); } catch ( Exception e ) { @@ -226,23 +226,23 @@ return true; } - public synchronized boolean deleteRecord(Key key) throws DBException { + public boolean deleteRecord(Key key) throws DBException { checkOpened(); try { int hash = key.getHash(); long pageNum = hash % fileHeader.getPageCount(); Page prev = null; Page page = null; - + HashPageHeader prevHead = null; HashPageHeader pageHead = null; - + while ( true ) { page = getPage(pageNum); pageHead = (HashPageHeader)page.getPageHeader(); if ( pageHead.getStatus() == RECORD - && pageHead.getKeyHash() == key.getHash() - && page.getKey().equals(key) ) + && pageHead.getKeyHash() == key.getHash() + && page.getKey().equals(key) ) break; pageNum = pageHead.getNextCollision(); if ( pageNum == -1 ) @@ -258,14 +258,14 @@ prevHead.setNextCollision(pageHead.nextCollision); prev.write(); } - + btree.removeValue(key); unlinkPages(page); fileHeader.decRecordCount(); - + flush(); - + return true; } catch ( Exception e ) { @@ -274,24 +274,24 @@ return false; } - public synchronized long getRecordCount() throws DBException { + public long getRecordCount() throws DBException { checkOpened(); return fileHeader.getRecordCount(); } - public synchronized RecordSet getRecordSet() throws DBException { + public RecordSet getRecordSet() throws DBException { checkOpened(); return new HashFilerRecordSet(); } - public synchronized void flush() throws DBException { + public void flush() throws DBException { super.flush(); } - + /** * HashFilerRecordSet */ - + private class HashFilerRecordSet implements RecordSet, BTreeCallback { private List keys = new ArrayList(); private Iterator enum; @@ -306,24 +306,24 @@ } } - public boolean indexInfo(Value value, long pointer) { + public synchronized boolean indexInfo(Value value, long pointer) { keys.add(new Key(value)); return true; } - public Key getNextKey() { + public synchronized Key getNextKey() { return (Key)enum.next(); } - public Record getNextRecord() throws DBException { + public synchronized Record getNextRecord() throws DBException { return readRecord((Key)enum.next()); } - public Value getNextValue() throws DBException { + public synchronized Value getNextValue() throws DBException { return getNextRecord().getValue(); } - public boolean hasMoreRecords() { + public synchronized boolean hasMoreRecords() { return enum.hasNext(); } } @@ -373,24 +373,24 @@ super(read); } - public void read(RandomAccessFile raf) throws IOException { + public synchronized void read(RandomAccessFile raf) throws IOException { super.read(raf); totalBytes = raf.readLong(); } - public void write(RandomAccessFile raf) throws IOException { + public synchronized void write(RandomAccessFile raf) throws IOException { super.write(raf); raf.writeLong(totalBytes); } /** The total number of bytes in use by the file */ - public void setTotalBytes(long totalBytes) { + public synchronized void setTotalBytes(long totalBytes) { this.totalBytes = totalBytes; setDirty(); } /** The total number of bytes in use by the file */ - public long getTotalBytes() { + public synchronized long getTotalBytes() { return totalBytes; } } @@ -411,7 +411,7 @@ super(dis); } - public void read(DataInputStream dis) throws IOException { + public synchronized void read(DataInputStream dis) throws IOException { super.read(dis); if ( getStatus() == UNUSED ) @@ -422,60 +422,49 @@ nextCollision = dis.readLong(); } - public void write(DataOutputStream dos) throws IOException { + public synchronized void write(DataOutputStream dos) throws IOException { super.write(dos); dos.writeLong(created); dos.writeLong(modified); dos.writeLong(nextCollision); } - public void setRecordLen(int recordLen) { - synchronized(fileHeader) { - fileHeader.setTotalBytes((fileHeader.totalBytes - getRecordLen()) + recordLen); - } + public synchronized void setRecordLen(int recordLen) { + fileHeader.setTotalBytes((fileHeader.totalBytes - getRecordLen()) + recordLen); super.setRecordLen(recordLen); } /** UNIX-time when this record was created */ - public void setCreated(long created) { + public synchronized void setCreated(long created) { this.created = created; setDirty(); } /** UNIX-time when this record was created */ - public long getCreated() { + public synchronized long getCreated() { return created; } /** UNIX-time when this record was last modified */ - public void setModified(long modified) { + public synchronized void setModified(long modified) { this.modified = modified; setDirty(); } /** UNIX-time when this record was last modified */ - public long getModified() { + public synchronized long getModified() { return modified; } /** The next page for a Record collision (if any) */ - public void setNextCollision(long nextCollision) { + public synchronized void setNextCollision(long nextCollision) { this.nextCollision = nextCollision; setDirty(); } /** The next page for a Record collision (if any) */ - public long getNextCollision() { + public synchronized long getNextCollision() { return nextCollision; } } } - - - - - - - - - 1.2 +18 -18 xml-xindice/java/src/org/apache/xindice/core/filer/MemFiler.java Index: MemFiler.java =================================================================== RCS file: /home/cvs/xml-xindice/java/src/org/apache/xindice/core/filer/MemFiler.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- MemFiler.java 6 Dec 2001 21:00:12 -0000 1.1 +++ MemFiler.java 9 Jun 2002 19:49:02 -0000 1.2 @@ -56,11 +56,11 @@ * information on the Apache Software Foundation, please see * <http://www.apache.org/>. * - * $Id: MemFiler.java,v 1.1 2001/12/06 21:00:12 bradford Exp $ + * $Id: MemFiler.java,v 1.2 2002/06/09 19:49:02 bradford Exp $ */ -import org.apache.xindice.core.*; import org.apache.xindice.core.Collection; +import org.apache.xindice.core.*; import org.apache.xindice.core.data.*; import org.apache.xindice.util.*; @@ -86,11 +86,11 @@ this.hashTable = hashTable; this.readOnly = readOnly; } - + public MemFiler(Map hashTable) { this(hashTable, false); } - + public void setCollection(Collection collection) { this.collection = collection; } @@ -108,7 +108,7 @@ if ( readOnly ) throw new FilerException(FaultCodes.COL_COLLECTION_READ_ONLY, "Filer is read-only"); } - + public boolean create() { hashTable.clear(); return true; @@ -137,13 +137,13 @@ opened = false; return !opened; } - + public void flush() { } - + public Record readRecord(Key key) throws DBException { checkOpened(); - return(Record)hashTable.get(key); + return (Record)hashTable.get(key); } public boolean writeRecord(Key key, Value value) throws DBException { @@ -169,30 +169,30 @@ return new MemRecordSet(); } - + /** * MemRecordSet */ - + private class MemRecordSet implements RecordSet { private Iterator enum = hashTable.values().iterator(); - public boolean hasMoreRecords() throws DBException { + public synchronized boolean hasMoreRecords() throws DBException { return enum.hasNext(); } - public Record getNextRecord() throws DBException { + public synchronized Record getNextRecord() throws DBException { checkOpened(); - return(Record)enum.next(); + return (Record)enum.next(); } - public Value getNextValue() throws DBException { + public synchronized Value getNextValue() throws DBException { checkOpened(); - return((Record)enum.next()).getValue(); + return ((Record)enum.next()).getValue(); } - - public Key getNextKey() { - return((Record)enum.next()).getKey(); + + public synchronized Key getNextKey() { + return ((Record)enum.next()).getKey(); } } } 1.4 +227 -134 xml-xindice/java/src/org/apache/xindice/core/filer/Paged.java Index: Paged.java =================================================================== RCS file: /home/cvs/xml-xindice/java/src/org/apache/xindice/core/filer/Paged.java,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- Paged.java 23 Feb 2002 03:26:27 -0000 1.3 +++ Paged.java 9 Jun 2002 19:49:02 -0000 1.4 @@ -56,10 +56,9 @@ * information on the Apache Software Foundation, please see * <http://www.apache.org/>. * - * $Id: Paged.java,v 1.3 2002/02/23 03:26:27 bradford Exp $ + * $Id: Paged.java,v 1.4 2002/06/09 19:49:02 bradford Exp $ */ -import org.apache.xindice.util.*; import org.apache.xindice.core.*; import org.apache.xindice.core.data.*; @@ -74,16 +73,18 @@ public abstract class Paged { private static final int MAX_DIRTY_SIZE = 128; - + private static final int MAX_DESCRIPTORS = 16; + protected static final byte UNUSED = 0; protected static final byte OVERFLOW = 126; protected static final byte DELETED = 127; private Map pages = new WeakHashMap(); private Map dirty = new HashMap(); - + private File file; - private RandomAccessFile raf; + private Stack descriptors = new Stack(); + private int descCount = 0; private boolean opened = false; private FileHeader fileHeader; @@ -114,6 +115,35 @@ return file; } + protected synchronized final RandomAccessFile getDescriptor() throws IOException { + if ( !descriptors.empty() ) + return (RandomAccessFile)descriptors.pop(); + else { + if ( descCount < MAX_DESCRIPTORS ) { + descCount++; + return new RandomAccessFile(file, "rw"); + } + else { + while ( true ) { + try { + wait(); + return (RandomAccessFile)descriptors.pop(); + } + catch ( Exception e ) { + // Who Cares + } + } + } + } + } + + protected synchronized final void putDescriptor(RandomAccessFile raf) { + if ( raf != null ) { + descriptors.push(raf); + notify(); + } + } + /** * getPage returns the page specified by pageNum. * @@ -122,17 +152,25 @@ * @throws IOException if an Exception occurs */ protected final Page getPage(Long lp) throws IOException { - Page p = (Page)dirty.get(lp); // Check if it's in the dirty stash - if ( p == null ) - p = (Page)pages.get(lp); // Check if it's in the volatile cache - if ( p == null ) { - p = new Page(lp.longValue()); - p.read(); - pages.put(lp, p); + Page p; + synchronized ( this ) { + p = (Page)dirty.get(lp); // Check if it's in the dirty stash + if ( p == null ) + p = (Page)pages.get(lp); // Check if it's in the volatile cache + if ( p == null ) { + p = new Page(lp.longValue()); + pages.put(lp, p); + } + } + synchronized ( p ) { + if ( !p.isLoaded() ) { + p.read(); + p.setLoaded(true); + } } return p; } - + /** * getPage returns the page specified by pageNum. * @@ -143,7 +181,7 @@ protected final Page getPage(long pageNum) throws IOException { return getPage(new Long(pageNum)); } - + /** * readValue reads the multi-Paged Value starting at the specified * Page. @@ -251,7 +289,7 @@ page.header.setNextPage(-1); page.write(); page = nextPage != -1 ? getPage(nextPage) - : null; + : null; } if ( page != null ) { @@ -303,7 +341,7 @@ else { // Grow the file pageNum = fileHeader.totalCount; - fileHeader.setTotalCount(pageNum+1); + fileHeader.setTotalCount(pageNum + 1); p = getPage(pageNum); } @@ -317,7 +355,7 @@ if ( !opened ) throw new FilerException(FaultCodes.COL_COLLECTION_CLOSED, "Filer is closed"); } - + /** * getFileHeader returns the FileHeader * @@ -332,22 +370,28 @@ } public boolean create() throws DBException { + RandomAccessFile raf = null; try { - raf = new RandomAccessFile(file, "rw"); + raf = getDescriptor(); fileHeader.write(); flush(); raf.close(); return true; } catch ( Exception e ) { - throw new FilerException(FaultCodes.GEN_CRITICAL_ERROR, "Error creating "+file.getName()); + throw new FilerException(FaultCodes.GEN_CRITICAL_ERROR, "Error creating " + file.getName()); + } + finally { + //putDescriptor(raf); + descCount = 0; } } public boolean open() throws DBException { + RandomAccessFile raf = null; try { if ( exists() ) { - raf = new RandomAccessFile(file, "rw"); + raf = getDescriptor(); fileHeader.read(); opened = true; } @@ -356,23 +400,34 @@ return opened; } catch ( Exception e ) { - throw new FilerException(FaultCodes.GEN_CRITICAL_ERROR, "Error opening "+file.getName()); + throw new FilerException(FaultCodes.GEN_CRITICAL_ERROR, "Error opening " + file.getName()); + } + finally { + putDescriptor(raf); } } - public boolean close() throws DBException { + public synchronized boolean close() throws DBException { try { if ( isOpened() ) { flush(); opened = false; - raf.close(); + while ( !descriptors.empty() ) { + try { + RandomAccessFile raf = getDescriptor(); + raf.close(); + } + catch ( Exception e ) { + // TODO Hmmmm.... + } + } return true; } else return false; } catch ( Exception e ) { - throw new FilerException(FaultCodes.GEN_CRITICAL_ERROR, "Error closing "+file.getName()); + throw new FilerException(FaultCodes.GEN_CRITICAL_ERROR, "Error closing " + file.getName()); } } @@ -389,7 +444,7 @@ return true; } catch ( Exception e ) { - throw new FilerException(FaultCodes.COL_CANNOT_DROP, "Can't drop "+file.getName()); + throw new FilerException(FaultCodes.COL_CANNOT_DROP, "Can't drop " + file.getName()); } } @@ -416,12 +471,12 @@ error = true; } } - + if ( error ) throw new FilerException(FaultCodes.GEN_CRITICAL_ERROR, "Error performing flush!"); } - - + + /** * createFileHeader must be implemented by a Paged implementation * in order to create an appropriate subclass instance of a FileHeader. @@ -471,78 +526,78 @@ // These are a bunch of utility methods for subclasses public static Value[] insertArrayValue(Value[] vals, Value val, int idx) { - Value[] newVals = new Value[vals.length+1]; + Value[] newVals = new Value[vals.length + 1]; if ( idx > 0 ) System.arraycopy(vals, 0, newVals, 0, idx); newVals[idx] = val; if ( idx < vals.length ) - System.arraycopy(vals, idx, newVals, idx+1, vals.length-idx); + System.arraycopy(vals, idx, newVals, idx + 1, vals.length - idx); return newVals; } public static Value[] deleteArrayValue(Value[] vals, int idx) { - Value[] newVals = new Value[vals.length-1]; + Value[] newVals = new Value[vals.length - 1]; if ( idx > 0 ) System.arraycopy(vals, 0, newVals, 0, idx); - if ( idx < newVals.length) - System.arraycopy(vals, idx+1, newVals, idx, newVals.length-idx); + if ( idx < newVals.length ) + System.arraycopy(vals, idx + 1, newVals, idx, newVals.length - idx); return newVals; } public static long[] insertArrayLong(long[] vals, long val, int idx) { - long[] newVals = new long[vals.length+1]; + long[] newVals = new long[vals.length + 1]; if ( idx > 0 ) System.arraycopy(vals, 0, newVals, 0, idx); newVals[idx] = val; if ( idx < vals.length ) - System.arraycopy(vals, idx, newVals, idx+1, vals.length-idx); + System.arraycopy(vals, idx, newVals, idx + 1, vals.length - idx); return newVals; } public static long[] deleteArrayLong(long[] vals, int idx) { - long[] newVals = new long[vals.length-1]; + long[] newVals = new long[vals.length - 1]; if ( idx > 0 ) System.arraycopy(vals, 0, newVals, 0, idx); - if ( idx < newVals.length) - System.arraycopy(vals, idx+1, newVals, idx, newVals.length-idx); + if ( idx < newVals.length ) + System.arraycopy(vals, idx + 1, newVals, idx, newVals.length - idx); return newVals; } public static int[] insertArrayInt(int[] vals, int val, int idx) { - int[] newVals = new int[vals.length+1]; + int[] newVals = new int[vals.length + 1]; if ( idx > 0 ) System.arraycopy(vals, 0, newVals, 0, idx); newVals[idx] = val; if ( idx < vals.length ) - System.arraycopy(vals, idx, newVals, idx+1, vals.length-idx); + System.arraycopy(vals, idx, newVals, idx + 1, vals.length - idx); return newVals; } public static int[] deleteArrayInt(int[] vals, int idx) { - int[] newVals = new int[vals.length-1]; + int[] newVals = new int[vals.length - 1]; if ( idx > 0 ) System.arraycopy(vals, 0, newVals, 0, idx); - if ( idx < newVals.length) - System.arraycopy(vals, idx+1, newVals, idx, newVals.length-idx); + if ( idx < newVals.length ) + System.arraycopy(vals, idx + 1, newVals, idx, newVals.length - idx); return newVals; } public static short[] insertArrayShort(short[] vals, short val, int idx) { - short[] newVals = new short[vals.length+1]; + short[] newVals = new short[vals.length + 1]; if ( idx > 0 ) System.arraycopy(vals, 0, newVals, 0, idx); newVals[idx] = val; if ( idx < vals.length ) - System.arraycopy(vals, idx, newVals, idx+1, vals.length-idx); + System.arraycopy(vals, idx, newVals, idx + 1, vals.length - idx); return newVals; } public static short[] deleteArrayShort(short[] vals, int idx) { - short[] newVals = new short[vals.length-1]; + short[] newVals = new short[vals.length - 1]; if ( idx > 0 ) System.arraycopy(vals, 0, newVals, 0, idx); - if ( idx < newVals.length) - System.arraycopy(vals, idx+1, newVals, idx, newVals.length-idx); + if ( idx < newVals.length ) + System.arraycopy(vals, idx + 1, newVals, idx, newVals.length - idx); return newVals; } @@ -586,13 +641,20 @@ read(); } - public final void read() throws IOException { - raf.seek(0); - read(raf); - calculateWorkSize(); + public synchronized final void read() throws IOException { + RandomAccessFile raf = null; + try { + raf = getDescriptor(); + raf.seek(0); + read(raf); + calculateWorkSize(); + } + finally { + putDescriptor(raf); + } } - public void read(RandomAccessFile raf) throws IOException { + public synchronized void read(RandomAccessFile raf) throws IOException { headerSize = raf.readShort(); pageSize = raf.readInt(); pageCount = raf.readLong(); @@ -604,16 +666,23 @@ recordCount = raf.readLong(); } - public final void write() throws IOException { + public synchronized final void write() throws IOException { if ( !dirty ) return; - - raf.seek(0); - write(raf); - dirty = false; + + RandomAccessFile raf = null; + try { + raf = getDescriptor(); + raf.seek(0); + write(raf); + dirty = false; + } + finally { + putDescriptor(raf); + } } - public void write(RandomAccessFile raf) throws IOException { + public synchronized void write(RandomAccessFile raf) throws IOException { raf.writeShort(headerSize); raf.writeInt(pageSize); raf.writeLong(pageCount); @@ -625,132 +694,132 @@ raf.writeLong(recordCount); } - public final void setDirty() { + public synchronized final void setDirty() { dirty = true; } - public final boolean isDirty() { + public synchronized final boolean isDirty() { return dirty; } /** The size of the FileHeader. Usually 1 OS Page */ - public final void setHeaderSize(short headerSize) { + public synchronized final void setHeaderSize(short headerSize) { this.headerSize = headerSize; dirty = true; } /** The size of the FileHeader. Usually 1 OS Page */ - public final short getHeaderSize() { + public synchronized final short getHeaderSize() { return headerSize; } /** The size of a page. Usually a multiple of a FS block */ - public final void setPageSize(int pageSize) { + public synchronized final void setPageSize(int pageSize) { this.pageSize = pageSize; calculateWorkSize(); dirty = true; } /** The size of a page. Usually a multiple of a FS block */ - public final int getPageSize() { + public synchronized final int getPageSize() { return pageSize; } /** The number of pages in primary storage */ - public final void setPageCount(long pageCount) { + public synchronized final void setPageCount(long pageCount) { this.pageCount = pageCount; dirty = true; } /** The number of pages in primary storage */ - public final long getPageCount() { + public synchronized final long getPageCount() { return pageCount; } /** The number of total pages in the file */ - public final void setTotalCount(long totalCount) { + public synchronized final void setTotalCount(long totalCount) { this.totalCount = totalCount; dirty = true; } /** The number of total pages in the file */ - public final long getTotalCount() { + public synchronized final long getTotalCount() { return totalCount; } /** The first free page in unused secondary space */ - public final void setFirstFreePage(long firstFreePage) { + public synchronized final void setFirstFreePage(long firstFreePage) { this.firstFreePage = firstFreePage; dirty = true; } /** The first free page in unused secondary space */ - public final long getFirstFreePage() { + public synchronized final long getFirstFreePage() { return firstFreePage; } /** The last free page in unused secondary space */ - public final void setLastFreePage(long lastFreePage) { + public synchronized final void setLastFreePage(long lastFreePage) { this.lastFreePage = lastFreePage; dirty = true; } /** The last free page in unused secondary space */ - public final long getLastFreePage() { + public synchronized final long getLastFreePage() { return lastFreePage; } /** The size of a page header. 64 is sufficient */ - public final void setPageHeaderSize(byte pageHeaderSize) { + public synchronized final void setPageHeaderSize(byte pageHeaderSize) { this.pageHeaderSize = pageHeaderSize; calculateWorkSize(); dirty = true; } /** The size of a page header. 64 is sufficient */ - public final byte getPageHeaderSize() { + public synchronized final byte getPageHeaderSize() { return pageHeaderSize; } /** The maximum number of bytes a key can be. 256 is good */ - public final void setMaxKeySize(short maxKeySize) { + public synchronized final void setMaxKeySize(short maxKeySize) { this.maxKeySize = maxKeySize; dirty = true; } /** The maximum number of bytes a key can be. 256 is good */ - public final short getMaxKeySize() { + public synchronized final short getMaxKeySize() { return maxKeySize; } /** The number of records being managed by the file (not pages) */ - public final void setRecordCount(long recordCount) { + public synchronized final void setRecordCount(long recordCount) { this.recordCount = recordCount; dirty = true; } /** Increment the number of records being managed by the file */ - public final void incRecordCount() { + public synchronized final void incRecordCount() { recordCount++; dirty = true; } /** Decrement the number of records being managed by the file */ - public final void decRecordCount() { + public synchronized final void decRecordCount() { recordCount--; dirty = true; } /** The number of records being managed by the file (not pages) */ - public final long getRecordCount() { + public synchronized final long getRecordCount() { return recordCount; } - private void calculateWorkSize() { + private synchronized void calculateWorkSize() { workSize = pageSize - pageHeaderSize; } - public final int getWorkSize() { + public synchronized final int getWorkSize() { return workSize; } } @@ -775,10 +844,10 @@ read(dis); } - public void read(DataInputStream dis) throws IOException { + public synchronized void read(DataInputStream dis) throws IOException { status = dis.readByte(); dirty = false; - + if ( status == UNUSED ) return; @@ -789,7 +858,7 @@ nextPage = dis.readLong(); } - public void write(DataOutputStream dos) throws IOException { + public synchronized void write(DataOutputStream dos) throws IOException { dirty = false; dos.writeByte(status); dos.writeShort(keyLen); @@ -799,26 +868,26 @@ dos.writeLong(nextPage); } - public final boolean isDirty() { + public synchronized final boolean isDirty() { return dirty; } - - public final void setDirty() { + + public synchronized final void setDirty() { dirty = true; } - + /** The status of this page (UNUSED, RECORD, DELETED, etc...) */ - public final void setStatus(byte status) { + public synchronized final void setStatus(byte status) { this.status = status; dirty = true; } /** The status of this page (UNUSED, RECORD, DELETED, etc...) */ - public final byte getStatus() { + public synchronized final byte getStatus() { return status; } - public final void setKey(Key key) { + public synchronized final void setKey(Key key) { // setKey WIPES OUT the Page data setRecordLen(0); dataLen = 0; @@ -828,57 +897,57 @@ } /** The length of the Key */ - public final void setKeyLen(short keyLen) { + public synchronized final void setKeyLen(short keyLen) { this.keyLen = keyLen; dirty = true; } /** The length of the Key */ - public final short getKeyLen() { + public synchronized final short getKeyLen() { return keyLen; } /** The hashed value of the Key for quick comparisons */ - public final void setKeyHash(int keyHash) { + public synchronized final void setKeyHash(int keyHash) { this.keyHash = keyHash; dirty = true; } /** The hashed value of the Key for quick comparisons */ - public final int getKeyHash() { + public synchronized final int getKeyHash() { return keyHash; } /** The length of the Data */ - public final void setDataLen(int dataLen) { + public synchronized final void setDataLen(int dataLen) { this.dataLen = dataLen; dirty = true; } /** The length of the Data */ - public final int getDataLen() { + public synchronized final int getDataLen() { return dataLen; } /** The length of the Record's value */ - public void setRecordLen(int recordLen) { + public synchronized void setRecordLen(int recordLen) { this.recordLen = recordLen; dirty = true; } /** The length of the Record's value */ - public final int getRecordLen() { + public synchronized final int getRecordLen() { return recordLen; } /** The next page for this Record (if overflowed) */ - public final void setNextPage(long nextPage) { + public synchronized final void setNextPage(long nextPage) { this.nextPage = nextPage; dirty = true; } /** The next page for this Record (if overflowed) */ - public final long getNextPage() { + public synchronized final long getNextPage() { return nextPage; } } @@ -906,6 +975,8 @@ /** The offset into the file that this page starts */ private long offset; + private boolean loaded; + public Page() { } @@ -914,24 +985,31 @@ setPageNum(pageNum); } - public void read() throws IOException { - Page page = null; - data = new byte[fileHeader.pageSize]; + public synchronized void read() throws IOException { + RandomAccessFile raf = null; + try { + Page page = null; + data = new byte[fileHeader.pageSize]; - raf.seek(offset); - raf.read(data); - - ByteArrayInputStream bis = new ByteArrayInputStream(data); - DataInputStream dis = new DataInputStream(bis); + raf = getDescriptor(); + raf.seek(offset); + raf.read(data); - // Read in the header - header.read(dis); + ByteArrayInputStream bis = new ByteArrayInputStream(data); + DataInputStream dis = new DataInputStream(bis); - keyPos = fileHeader.pageHeaderSize; - dataPos = keyPos + header.keyLen; + // Read in the header + header.read(dis); + + keyPos = fileHeader.pageHeaderSize; + dataPos = keyPos + header.keyLen; + } + finally { + putDescriptor(raf); + } } - public void write() throws IOException { + public synchronized void write() throws IOException { // Write out the header ByteArrayOutputStream bos = new ByteArrayOutputStream(fileHeader.getPageHeaderSize()); DataOutputStream dos = new DataOutputStream(bos); @@ -951,48 +1029,55 @@ } } - public void flush() throws IOException { - if ( offset >= raf.length() ) { - // Grow the file - long o = (fileHeader.headerSize + ((fileHeader.totalCount*3)/2)*fileHeader.pageSize)+(fileHeader.pageSize-1); - raf.seek(o); - raf.writeByte(0); + public synchronized void flush() throws IOException { + RandomAccessFile raf = null; + try { + raf = getDescriptor(); + if ( offset >= raf.length() ) { + // Grow the file + long o = (fileHeader.headerSize + ((fileHeader.totalCount * 3) / 2) * fileHeader.pageSize) + (fileHeader.pageSize - 1); + raf.seek(o); + raf.writeByte(0); + } + raf.seek(offset); + raf.write(data); + } + finally { + putDescriptor(raf); } - raf.seek(offset); - raf.write(data); } - - public void setPageNum(long pageNum) { + + public synchronized void setPageNum(long pageNum) { this.pageNum = pageNum; offset = fileHeader.headerSize + (pageNum * fileHeader.pageSize); } - public long getPageNum() { + public synchronized long getPageNum() { return pageNum; } - public PageHeader getPageHeader() { + public synchronized PageHeader getPageHeader() { return header; } - public void setKey(Key key) { + public synchronized void setKey(Key key) { header.setKey(key); key.copyTo(data, keyPos); } - public Key getKey() { + public synchronized Key getKey() { if ( header.keyLen > 0 ) return new Key(data, keyPos, header.keyLen); else return null; } - public void streamTo(OutputStream os) throws IOException { + public synchronized void streamTo(OutputStream os) throws IOException { if ( header.dataLen > 0 ) os.write(data, dataPos, header.dataLen); } - public void streamFrom(InputStream is) throws IOException { + public synchronized void streamFrom(InputStream is) throws IOException { int avail = is.available(); header.dataLen = fileHeader.workSize - header.keyLen; if ( avail < header.dataLen ) @@ -1000,8 +1085,16 @@ if ( header.dataLen > 0 ) is.read(data, keyPos + header.keyLen, header.dataLen); } - - public int compareTo(Object o) { + + public synchronized boolean isLoaded() { + return loaded; + } + + public synchronized void setLoaded(boolean loaded) { + this.loaded = loaded; + } + + public synchronized int compareTo(Object o) { return (int)(pageNum - ((Page)o).pageNum); } } 1.4 +5 -5 xml-xindice/java/src/org/apache/xindice/core/fulltext/FullTextIndexer.java Index: FullTextIndexer.java =================================================================== RCS file: /home/cvs/xml-xindice/java/src/org/apache/xindice/core/fulltext/FullTextIndexer.java,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- FullTextIndexer.java 21 Apr 2002 19:44:26 -0000 1.3 +++ FullTextIndexer.java 9 Jun 2002 19:49:03 -0000 1.4 @@ -56,7 +56,7 @@ * information on the Apache Software Foundation, please see * <http://www.apache.org/>. * - * $Id: FullTextIndexer.java,v 1.3 2002/04/21 19:44:26 bradford Exp $ + * $Id: FullTextIndexer.java,v 1.4 2002/06/09 19:49:03 bradford Exp $ */ import org.apache.xindice.core.*; @@ -248,7 +248,7 @@ return new IndexMatch(key, pos, len, elemID, attrID); } - public synchronized void remove(String value, Key key, int pos, int len, short elemID, short attrID) throws DBException { + public void remove(String value, Key key, int pos, int len, short elemID, short attrID) throws DBException { StringTokenizer st = new StringTokenizer(value); while ( st.hasMoreTokens() ) { String s = st.nextToken(); @@ -277,7 +277,7 @@ } } - public synchronized void add(String value, Key key, int pos, int len, short elemID, short attrID) throws DBException { + public void add(String value, Key key, int pos, int len, short elemID, short attrID) throws DBException { StringTokenizer st = new StringTokenizer(value); while ( st.hasMoreTokens() ) { String s = st.nextToken(); @@ -317,11 +317,11 @@ } } - public synchronized void flush() throws DBException { + public void flush() throws DBException { super.flush(); } - public synchronized IndexMatch[] queryMatches(final IndexQuery query) throws DBException { + public IndexMatch[] queryMatches(final IndexQuery query) throws DBException { // Pre-process the value-set for stop words and stemming Value[] vals = query.getValues(); for ( int i = 0; i < vals.length; i++ ) { 1.2 +11 -11 xml-xindice/java/src/org/apache/xindice/core/indexer/NameIndexer.java Index: NameIndexer.java =================================================================== RCS file: /home/cvs/xml-xindice/java/src/org/apache/xindice/core/indexer/NameIndexer.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- NameIndexer.java 6 Dec 2001 21:00:12 -0000 1.1 +++ NameIndexer.java 9 Jun 2002 19:49:03 -0000 1.2 @@ -56,7 +56,7 @@ * information on the Apache Software Foundation, please see * <http://www.apache.org/>. * - * $Id: NameIndexer.java,v 1.1 2001/12/06 21:00:12 bradford Exp $ + * $Id: NameIndexer.java,v 1.2 2002/06/09 19:49:03 bradford Exp $ */ import org.apache.xindice.core.*; @@ -82,14 +82,14 @@ public final class NameIndexer extends BTree implements Indexer { private static final IndexMatch[] EmptyMatches = new IndexMatch[0]; private static final Value EmptyValue = new Value(new byte[0]); - + private static final byte MATCHES = 20; private static final String NAME = "name"; private static final String PATTERN = "pattern"; private static final String PAGESIZE = "pagesize"; private static final String MAXKEYSIZE = "maxkeysize"; - + private Configuration config; private Collection collection; private SymbolTable symbols; @@ -112,7 +112,7 @@ pattern = config.getAttribute(PATTERN); wildcard = pattern.indexOf('*') != -1; - + fileHeader.setPageSize(config.getIntAttribute(PAGESIZE, fileHeader.getPageSize())); fileHeader.setMaxKeySize(config.getShortAttribute(MAXKEYSIZE, fileHeader.getMaxKeySize())); @@ -153,7 +153,7 @@ return pattern; } - public synchronized void remove(String value, Key key, int pos, int len, short elemID, short attrID) throws DBException { + public void remove(String value, Key key, int pos, int len, short elemID, short attrID) throws DBException { try { removeValue(key); } @@ -162,7 +162,7 @@ } } - public synchronized void add(String value, Key key, int pos, int len, short elemID, short attrID) throws DBException { + public void add(String value, Key key, int pos, int len, short elemID, short attrID) throws DBException { try { addValue(key, 0); } @@ -171,14 +171,14 @@ } } - public synchronized void flush() throws DBException { + public void flush() throws DBException { super.flush(); } - - public synchronized IndexMatch[] queryMatches(final IndexQuery query) throws DBException { + + public IndexMatch[] queryMatches(final IndexQuery query) throws DBException { final List results = new ArrayList(); final IndexPattern pattern = query.getPattern(); - + try { query(query, new BTreeCallback() { public boolean indexInfo(Value value, long pos) { @@ -193,7 +193,7 @@ catch ( Exception e ) { org.apache.xindice.Debug.printStackTrace(e); } - + return (IndexMatch[])results.toArray(EmptyMatches); } } 1.2 +14 -14 xml-xindice/java/src/org/apache/xindice/core/indexer/ValueIndexer.java Index: ValueIndexer.java =================================================================== RCS file: /home/cvs/xml-xindice/java/src/org/apache/xindice/core/indexer/ValueIndexer.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- ValueIndexer.java 6 Dec 2001 21:00:12 -0000 1.1 +++ ValueIndexer.java 9 Jun 2002 19:49:03 -0000 1.2 @@ -56,7 +56,7 @@ * information on the Apache Software Foundation, please see * <http://www.apache.org/>. * - * $Id: ValueIndexer.java,v 1.1 2001/12/06 21:00:12 bradford Exp $ + * $Id: ValueIndexer.java,v 1.2 2002/06/09 19:49:03 bradford Exp $ */ import org.apache.xindice.core.*; @@ -269,11 +269,11 @@ try { int l = key.getLength(); byte[] b = new byte[l+13]; - + // Write the key System.arraycopy(key.getData(), 0, b, 0, l); b[l] = 0; - + // Write the pos b[l+1] = (byte)((pos >>> 24) & 0xFF); b[l+2] = (byte)((pos >>> 16) & 0xFF); @@ -289,7 +289,7 @@ // Write the elemID b[l+9] = (byte)((elemID >>> 8) & 0xFF); b[l+10] = (byte)((elemID >>> 0) & 0xFF); - + // Write the attrID b[l+11] = (byte)((attrID >>> 8) & 0xFF); b[l+12] = (byte)((attrID >>> 0) & 0xFF); @@ -301,12 +301,12 @@ } return result; } - + private IndexMatch getIndexMatch(Value v) { byte[] b = v.getData(); int l = b.length-13; Key key = new Key(b, 0, b.length-13); - + int pos = ((b[l+1] << 24) | (b[l+2] << 16) | (b[l+3] << 8) | b[l+4]); int len = ((b[l+5] << 24) | (b[l+6] << 16) | (b[l+7] << 8) | b[l+8]); short elemID = (short)((b[l+9] << 8) | b[l+10]); @@ -314,8 +314,8 @@ return new IndexMatch(key, pos, len, elemID, attrID); } - - public synchronized void remove(String value, Key key, int pos, int len, short elemID, short attrID) throws DBException { + + public void remove(String value, Key key, int pos, int len, short elemID, short attrID) throws DBException { Value v = getTypedValue(value); if ( type != STRING && type != TRIMMED && v.getLength() == 0 ) return; @@ -333,14 +333,14 @@ } } - public synchronized void add(String value, Key key, int pos, int len, short elemID, short attrID) throws DBException { + public void add(String value, Key key, int pos, int len, short elemID, short attrID) throws DBException { Value v = getTypedValue(value); if ( type != STRING && type != TRIMMED && v.getLength() == 0 ) return; - + try { BTreeRootInfo root; - + try { root = findBTreeRoot(v); } @@ -362,11 +362,11 @@ } } - public synchronized void flush() throws DBException { + public void flush() throws DBException { super.flush(); } - - public synchronized IndexMatch[] queryMatches(final IndexQuery query) throws DBException { + + public IndexMatch[] queryMatches(final IndexQuery query) throws DBException { // Pre-process the value-set for typing and trimming if ( type != STRING ) { Value[] vals = query.getValues();