1 8 9 package com.sleepycat.persist; 10 11 import com.sleepycat.bind.EntryBinding; 12 import com.sleepycat.compat.DbCompat; 13 import com.sleepycat.je.Cursor; 14 import com.sleepycat.je.CursorConfig; 15 import com.sleepycat.je.Database; 16 import com.sleepycat.je.DatabaseConfig; 17 import com.sleepycat.je.DatabaseEntry; 18 import com.sleepycat.je.DatabaseException; 19 import com.sleepycat.je.LockMode; 20 import com.sleepycat.je.OperationStatus; 21 import com.sleepycat.je.SecondaryDatabase; 22 import com.sleepycat.je.Transaction; 23 import com.sleepycat.util.keyrange.KeyRange; 24 import com.sleepycat.util.keyrange.RangeCursor; 25 26 33 abstract class BasicIndex<K,E> implements EntityIndex<K,E> { 34 35 static final DatabaseEntry NO_RETURN_ENTRY; 36 static { 37 NO_RETURN_ENTRY = new DatabaseEntry(); 38 NO_RETURN_ENTRY.setPartial(0, 0, true); 39 } 40 41 Database db; 42 boolean transactional; 43 Class <K> keyClass; 44 EntryBinding keyBinding; 45 KeyRange emptyRange; 46 ValueAdapter<K> keyAdapter; 47 ValueAdapter<E> entityAdapter; 48 49 BasicIndex(Database db, 50 Class <K> keyClass, 51 EntryBinding keyBinding, 52 ValueAdapter<E> entityAdapter) 53 throws DatabaseException { 54 55 this.db = db; 56 DatabaseConfig config = db.getConfig(); 57 transactional = config.getTransactional(); 58 59 this.keyClass = keyClass; 60 this.keyBinding = keyBinding; 61 this.entityAdapter = entityAdapter; 62 63 emptyRange = new KeyRange(config.getBtreeComparator()); 64 keyAdapter = new KeyValueAdapter(keyClass, keyBinding); 65 } 66 67 71 72 public boolean contains(K key) 73 throws DatabaseException { 74 75 return contains(null, key, null); 76 } 77 78 public boolean contains(Transaction txn, K key, LockMode lockMode) 79 throws DatabaseException { 80 81 DatabaseEntry keyEntry = new DatabaseEntry(); 82 DatabaseEntry dataEntry = NO_RETURN_ENTRY; 83 keyBinding.objectToEntry(key, keyEntry); 84 85 OperationStatus status = db.get(txn, keyEntry, dataEntry, lockMode); 86 return (status == OperationStatus.SUCCESS); 87 } 88 89 public long count() 90 throws DatabaseException { 91 92 if (DbCompat.DATABASE_COUNT) { 93 return DbCompat.getDatabaseCount(db); 94 } else { 95 long count = 0; 96 boolean countDups = db instanceof SecondaryDatabase; 97 DatabaseEntry key = NO_RETURN_ENTRY; 98 DatabaseEntry data = NO_RETURN_ENTRY; 99 CursorConfig cursorConfig = CursorConfig.READ_UNCOMMITTED; 100 Cursor cursor = db.openCursor(null, cursorConfig); 101 try { 102 OperationStatus status = cursor.getFirst(key, data, null); 103 while (status == OperationStatus.SUCCESS) { 104 if (countDups) { 105 count += cursor.count(); 106 } else { 107 count += 1; 108 } 109 status = cursor.getNextNoDup(key, data, null); 110 } 111 } finally { 112 cursor.close(); 113 } 114 return count; 115 } 116 } 117 118 public boolean delete(K key) 119 throws DatabaseException { 120 121 return delete(null, key); 122 } 123 124 public boolean delete(Transaction txn, K key) 125 throws DatabaseException { 126 127 DatabaseEntry keyEntry = new DatabaseEntry(); 128 keyBinding.objectToEntry(key, keyEntry); 129 130 OperationStatus status = db.delete(txn, keyEntry); 131 return (status == OperationStatus.SUCCESS); 132 } 133 134 public EntityCursor<K> keys() 135 throws DatabaseException { 136 137 return keys(null, null); 138 } 139 140 public EntityCursor<K> keys(Transaction txn, CursorConfig config) 141 throws DatabaseException { 142 143 return cursor(txn, emptyRange, keyAdapter, config); 144 } 145 146 public EntityCursor<E> entities() 147 throws DatabaseException { 148 149 return cursor(null, emptyRange, entityAdapter, null); 150 } 151 152 public EntityCursor<E> entities(Transaction txn, 153 CursorConfig config) 154 throws DatabaseException { 155 156 return cursor(txn, emptyRange, entityAdapter, config); 157 } 158 159 public EntityCursor<K> keys(K fromKey, boolean fromInclusive, 160 K toKey, boolean toInclusive) 161 throws DatabaseException { 162 163 return cursor(null, fromKey, fromInclusive, toKey, toInclusive, 164 keyAdapter, null); 165 } 166 167 public EntityCursor<K> keys(Transaction txn, 168 K fromKey, 169 boolean fromInclusive, 170 K toKey, 171 boolean toInclusive, 172 CursorConfig config) 173 throws DatabaseException { 174 175 return cursor(txn, fromKey, fromInclusive, toKey, toInclusive, 176 keyAdapter, config); 177 } 178 179 public EntityCursor<E> entities(K fromKey, boolean fromInclusive, 180 K toKey, boolean toInclusive) 181 throws DatabaseException { 182 183 return cursor(null, fromKey, fromInclusive, toKey, toInclusive, 184 entityAdapter, null); 185 } 186 187 public EntityCursor<E> entities(Transaction txn, 188 K fromKey, 189 boolean fromInclusive, 190 K toKey, 191 boolean toInclusive, 192 CursorConfig config) 193 throws DatabaseException { 194 195 return cursor(txn, fromKey, fromInclusive, toKey, toInclusive, 196 entityAdapter, config); 197 } 198 199 228 229 private <V> EntityCursor<V> cursor(Transaction txn, 230 K fromKey, 231 boolean fromInclusive, 232 K toKey, 233 boolean toInclusive, 234 ValueAdapter<V> adapter, 235 CursorConfig config) 236 throws DatabaseException { 237 238 DatabaseEntry fromEntry = null; 239 if (fromKey != null) { 240 fromEntry = new DatabaseEntry(); 241 keyBinding.objectToEntry(fromKey, fromEntry); 242 } 243 DatabaseEntry toEntry = null; 244 if (toKey != null) { 245 toEntry = new DatabaseEntry(); 246 keyBinding.objectToEntry(toKey, toEntry); 247 } 248 KeyRange range = emptyRange.subRange 249 (fromEntry, fromInclusive, toEntry, toInclusive); 250 return cursor(txn, range, adapter, config); 251 } 252 253 private <V> EntityCursor<V> cursor(Transaction txn, 254 KeyRange range, 255 ValueAdapter<V> adapter, 256 CursorConfig config) 257 throws DatabaseException { 258 259 Cursor cursor = db.openCursor(txn, config); 260 RangeCursor rangeCursor = new RangeCursor(range, cursor); 261 return new BasicCursor<V>(rangeCursor, adapter); 262 } 263 } 264 | Popular Tags |