|
What this is
Other links
The source codepackage org.netbeans.mdr.persistence.btreeimpl.btreeindex; /* * Sun Public License Notice * * The contents of this file are subject to the Sun Public License * Version 1.0 (the "License"). You may not use this file except in * compliance with the License. A copy of the License is available at * http://www.sun.com/ * * The Original Code is NetBeans. The Initial Developer of the Original * Code is Sun Microsystems, Inc. Portions Copyright 1997-2001 Sun * Microsystems, Inc. All Rights Reserved. */ import org.netbeans.mdr.persistence.*; import java.util.*; import java.text.*; /** * List view of the values associated with a single key in a MultivaluedBtree. * * @author Dana Bergen * @version 1.0 */ /* * Unlike BtreeIterator, we don't bother to unpin pages here. We can do this * because BtreeListByKey is only used with BtreeMDRSource-based btrees, * for which unpin is a no-op. */ public class BtreeListByKey extends AbstractSequentialList { private MultivaluedBtree btree; private byte[] key; private Object objectKey; private int listModCounter = 0; BtreeListByKey(MultivaluedBtree btree, Object key) throws StorageException { this.btree = btree; this.objectKey = key; this.key = btree.keyInfo.toBuffer(key); if (this.key == null) { throw new StorageBadRequestException( MessageFormat.format( "Invalid key type for this index: {0} received, {1} expected", new Object[] { key.getClass().getName(), btree.keyInfo.typeName()} )); } } public int size() { BtreeListByKeyIterator iterator = new BtreeListByKeyIterator(0, null); while (iterator.moveForward()) {} return iterator.previousIndex(); } public boolean isEmpty() { return !listIterator(0).hasNext(); } public boolean add(Object o) { ListIterator it = listIterator(); while (it.hasNext()) it.next(); it.add(o); return true; } public boolean addAll(Collection c) { boolean result = false; ListIterator it = listIterator(); Iterator cit; while (it.hasNext()) it.next(); for (cit = c.iterator(); cit.hasNext();) { try { it.add(cit.next()); result = true; } catch (RuntimeStorageException e) { } } return result; } public void increaseModCount () { listModCounter++; } public int hashCode() { return objectKey.hashCode(); } public boolean equals(Object o) { if (o instanceof BtreeListByKey) return ((BtreeListByKey) o).objectKey.equals(objectKey); if (o instanceof Key) return ((Key) o).objectKey.equals(objectKey); return false; } public ListIterator listIterator(int index) { return new BtreeListByKeyIterator(index, null); } ListIterator listIterator (int index, SinglevaluedIndex repos) { return new BtreeListByKeyIterator(index, repos); } // Iterator .................................................................. public class BtreeListByKeyIterator extends Object implements ListIterator { /* [TODO] Performance of next/previous operations should be improved by * implementing live scan position holder that reflects all changes done over * the index (for now, scan position relocations are required if the index is * modifed outside the iterator and btree pages storing data related to the * iterator are affected). */ /* Btree scan position */ private SearchResult current; /* Btree scan position of the leftmost entry matching the key */ private SearchResult first; /* Index of the last item returned */ private int index; private boolean empty; private int modCount; private SinglevaluedIndex repos; private boolean itemAvailable = false; /* true if the available item has been retrieved by next operation */ private boolean retrievedByNext = false; BtreeListByKeyIterator(int startIndex, SinglevaluedIndex repos) throws IndexOutOfBoundsException { try { this.repos = repos; btree.beginRead(); modCount = listModCounter; index = -1; current = btree.getLocation(key); first = new SearchResult (current); current.entryNum--; if (!current.matched) { empty = true; } if (startIndex < 0) throw new IndexOutOfBoundsException(); for (int i = 0; i < startIndex; i++) { if (!moveForward()) { throw new IndexOutOfBoundsException(); } } } catch (StorageException e) { throw new RuntimeStorageException(e); } finally { btree.endRead(); } } public Object next() throws NoSuchElementException { if (!moveForward()) { throw new NoSuchElementException(); } itemAvailable = true; retrievedByNext = true; return getCurrentItem(); } public Object previous() throws NoSuchElementException { Object item; if (index == -1) { throw new NoSuchElementException(); } item = getCurrentItem(); moveBackward(); itemAvailable = true; retrievedByNext = false; return item; } public boolean hasNext() { try { btree.beginRead(); checkModCount(); locateCurrentItem(); return BtreePage.hasNext(key, current); } catch (StorageException e) { throw new RuntimeStorageException(e); } finally { btree.endRead(); } } public boolean hasPrevious() { return (index >= 0); } private boolean moveForward() { try { btree.beginRead(); checkModCount(); locateCurrentItem(); BtreePage.getNext(key, current); index++; return current.matched; } catch (StorageException e) { e.printStackTrace (); throw new RuntimeStorageException(e); } finally { btree.endRead(); } } private void moveBackward() { try { btree.beginRead(); checkModCount(); locateCurrentItem(); int tempEntryNum = current.entryNum; BtreePage.getPrevious(key, current); if (!current.matched && (current.entryNum == tempEntryNum)) current.entryNum--; index--; } catch (StorageException e) { throw new RuntimeStorageException(e); } finally { btree.endRead(); } } private Object getCurrentItem() { Object result; try { btree.beginRead(); checkModCount(); locateCurrentItem(); if (repos != null) { result = btree.dataInfo.objectFromBuffer( current.page.getData(current.entryNum), repos); } else { result = btree.dataInfo.fromBuffer( current.page.getData(current.entryNum)); } return result; } catch (StorageException e) { throw new RuntimeStorageException(e); } finally { btree.endRead(); } } public int nextIndex() { return index + 1; } public int previousIndex() { return index; } private void checkModCount() { if (listModCounter != modCount) { throw new ConcurrentModificationException("Index " + btree.getName() + ", key " + objectKey + " has been modified since iterator was created."); } } public void remove() { if (!itemAvailable) throw new IllegalStateException (); checkModCount (); removeItem (); itemAvailable = false; if (retrievedByNext) index--; listModCounter++; modCount = listModCounter; } public void set(Object o) { if (!itemAvailable) throw new IllegalStateException (); checkModCount (); setItem (o); listModCounter++; modCount = listModCounter; } public void add(Object o) { checkModCount (); addItem (o); itemAvailable = false; index++; listModCounter++; modCount = listModCounter; } private void setItem(Object o) { try { btree.beginWrite(); locateCurrentItem(); BtreePage.BtreeEntry entry = new BtreePage.BtreeEntry (key, btree.dataInfo.toBuffer (o)); if (current.page instanceof ShrinkablePage) { BtreePage root = btree.pageSource.getPage(btree.rootPageId, btree); root.put(key, btree.dataInfo.toBuffer (o), Btree.REPLACE, index, current); btree.pageSource.unpinPage(root); } else { // we can call replace directly on a page (instead of tree) to achieve a better performance current.page.replace(entry, current.entryNum, null); } } catch (StorageException e) { throw new RuntimeStorageException(e); } finally { btree.endWrite(); } } private void removeItem() { try { btree.beginWrite(); locateCurrentItem(); SearchResult temp = new SearchResult (current); if (retrievedByNext) { BtreePage.getPrevious(key, current); if (!current.matched && (current.entryNum == temp.entryNum)) current.entryNum--; } else { BtreePage.getNext(key, temp); } // delete does not merge pages, thus we can perform it directly on the page temp.page.delete(temp.entryNum, temp.entryNum); if ((retrievedByNext && (index == 0)) || (!retrievedByNext && (index == -1))) { first = new SearchResult(current); BtreePage.getNext(key, first); } } catch (StorageException e) { throw new RuntimeStorageException(e); } finally { btree.endWrite(); } } private void addItem(Object o) { try { btree.beginWrite(); locateCurrentItem(); BtreePage root = btree.pageSource.getPage(btree.rootPageId, btree); root.put(key, btree.dataInfo.toBuffer (o), Btree.ADD, index + 1, current); btree.pageSource.unpinPage(root); if (index == -1) { first = new SearchResult(current); } // BtreePage.getNext(key, current); } catch (StorageException e) { throw new RuntimeStorageException(e); } finally { btree.endWrite(); } } private void locateCurrentItem() throws StorageException { SearchResult res = first.page.searchPage(key, first.entryNum); if ((first.entryNum != res.entryNum) || (first.page != res.page)) { first = res; current = new SearchResult (first); if (index == -1) { current.entryNum--; } else { first.page.findNth(current, key, index, false); } } else { if ((index > -1) && (current.page.compare(key, current.entryNum) != EntryTypeInfo.EQUAL)) { current = new SearchResult (first); first.page.findNth(current, key, index, false); } } } } // BtreeListByKeyIterator class /** * This class is used to query for BtreeListByKey instances in hashtables. */ static class Key { private Object objectKey; Key (Object key) { objectKey = key; } public int hashCode() { return objectKey.hashCode(); } public boolean equals(Object o) { if (o instanceof BtreeListByKey) return ((BtreeListByKey) o).objectKey.equals(objectKey); if (o instanceof Key) return ((Key) o).objectKey.equals(objectKey); return false; } } // Key class } |
... this post is sponsored by my books ... | |
#1 New Release! |
FP Best Seller |
Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse
URI on this website is
paid back to open source projects.