1 19 package org.netbeans.mdr.persistence.btreeimpl.btreeindex; 20 21 import org.netbeans.mdr.persistence.*; 22 import org.netbeans.mdr.util.MapEntryImpl; 23 import java.lang.ref.WeakReference ; 24 import java.util.*; 25 import java.text.*; 26 27 33 public class MultivaluedBtree extends Btree implements MultivaluedIndex { 34 35 private WeakHashMap listsByKey_cache = new WeakHashMap (); 37 38 public MultivaluedBtree(String name, Storage.EntryType keyType, 39 Storage.EntryType dataType, 40 boolean uniqueValues, 41 BtreePageSource pageSource) 42 throws StorageException { 43 super(name, keyType, dataType, pageSource); 44 this.uniqueValues = uniqueValues; 45 } 46 47 protected void init() throws StorageException { 48 uniqueKeys = false; 49 super.init(); 50 } 51 52 56 public MultivaluedBtree() { 57 } 58 59 66 public Collection getItems(Object key) throws StorageException { 67 WeakReference ref = (WeakReference ) listsByKey_cache.get (new BtreeListByKey.Key (key)); 68 BtreeListByKey list = null; 69 if (ref != null) 70 list = (BtreeListByKey) ref.get(); 71 if (list == null) { 72 list = new BtreeListByKey(this, key); 73 listsByKey_cache.put (list, new WeakReference (list)); 74 } 75 return list; 76 } 77 78 85 public Collection getObjects(Object key, SinglevaluedIndex repos) throws StorageException { 86 WeakReference ref = (WeakReference ) listsByKey_cache.get (new BtreeListByKey.Key (key)); 87 BtreeListByKey list = null; 88 if (ref != null) 89 list = (BtreeListByKey) ref.get(); 90 if (list == null) { 91 list = new BtreeListByKey(this, key); 92 listsByKey_cache.put (list, new WeakReference (list)); 93 } 94 return new BtreeListByKeyRepos(list, repos); 95 } 96 97 102 public boolean isUnique() { 103 return uniqueValues; 104 } 105 106 113 public boolean remove(Object key, Object value) throws StorageException { 114 beginWrite(); 115 try { 116 byte[] keyBuffer, dataBuffer; 117 boolean result; 118 119 if ((keyBuffer = keyInfo.toBuffer(key)) == null) { 120 throw new StorageBadRequestException( 121 MessageFormat.format( 122 "Invalid key type for this index: {0} received, {1} expected", 123 new Object [] { 124 key.getClass().getName(), 125 keyInfo.typeName()} )); 126 } 127 128 if ((dataBuffer = dataInfo.toBuffer(value)) == null) { 129 throw new StorageBadRequestException( 130 MessageFormat.format( 131 "Invalid data type for this index: {0} received, {1} expected", 132 new Object [] { 133 value.getClass().getName(), 134 dataInfo.typeName()} )); 135 } 136 137 BtreePage root = pageSource.getPage(rootPageId, this); 138 result = root.remove(keyBuffer, dataBuffer); 139 if (result) 140 updateKeyModCount (key); 141 pageSource.unpinPage(root); 142 return result; 143 } finally { 144 endWrite(); 145 } 146 } 147 148 public void add(Object key, Object data) throws StorageException { 149 super.add (key, data); 150 updateKeyModCount (key); 151 } 152 153 public boolean remove(Object key) throws StorageException { 154 boolean result = super.remove (key); 155 if (result) 156 updateKeyModCount (key); 157 return result; 158 } 159 160 164 public synchronized Collection queryByKeyPrefix (Object prefix, SinglevaluedIndex primaryIndex) throws StorageException { 165 if (keyType != Storage.EntryType.STRING) { 166 throw new UnsupportedOperationException ("Key type must be EntryType.STRING"); 167 } 168 169 List result = new LinkedList (); 170 byte [] prefixBytes = keyInfo.toBuffer (prefix); 171 SearchResult location = getLocation (prefixBytes); 172 if (location.entryNum == location.page.numEntries()) 173 BtreePage.getNext (null, location); 174 175 while ((location.entryNum < location.page.numEntries()) && 176 SinglevaluedBtree.isPrefix (prefixBytes, location.page.getKey (location.entryNum))) { 177 byte [] key = location.page.getKey (location.entryNum); 178 Object keyObject = keyInfo.objectFromBuffer (key, primaryIndex); 179 Collection data = getObjects (keyObject, primaryIndex); 180 Object entry = new MapEntryImpl (keyObject, data); 181 result.add (entry); 182 int size = data.size (); 183 location.page.findNth (location, key, size, false); 184 } return result; 186 } 187 188 private static boolean isPrefix (byte [] prefix, byte [] key) { 189 if (prefix.length > key.length) 190 return false; 191 for (int x = 0; x < prefix.length; x++) { 192 if (prefix [x] != key [x]) 193 return false; 194 } 195 return true; 196 } 197 198 202 protected void updateKeyModCount (Object key) { 203 WeakReference ref = (WeakReference ) listsByKey_cache.get (new BtreeListByKey.Key (key)); 204 if (ref == null) 205 return; 206 BtreeListByKey list = null; 207 list = (BtreeListByKey) ref.get (); 208 if (list != null) 209 list.increaseModCount (); 210 } 211 212 } 213 | Popular Tags |