1/*- 2 * See the file LICENSE for redistribution information. 3 * 4 * Copyright (c) 2002,2008 Oracle. All rights reserved. 5 * 6 * $Id: TestStore.java,v 12.8 2008/02/07 17:12:31 mark Exp $ 7 */ 8 9package com.sleepycat.collections.test; 10 11import java.io.IOException; 12import java.util.ArrayList; 13import java.util.List; 14 15import com.sleepycat.bind.EntityBinding; 16import com.sleepycat.bind.EntryBinding; 17import com.sleepycat.bind.RecordNumberBinding; 18import com.sleepycat.collections.CurrentTransaction; 19import com.sleepycat.compat.DbCompat; 20import com.sleepycat.db.Database; 21import com.sleepycat.db.DatabaseException; 22import com.sleepycat.db.Environment; 23import com.sleepycat.db.SecondaryConfig; 24 25/** 26 * @author Mark Hayes 27 */ 28class TestStore { 29 30 static final TestKeyCreator BYTE_EXTRACTOR = new TestKeyCreator(false); 31 static final TestKeyCreator RECNO_EXTRACTOR = new TestKeyCreator(true); 32 static final EntryBinding VALUE_BINDING = new TestDataBinding(); 33 static final EntryBinding BYTE_KEY_BINDING = VALUE_BINDING; 34 static final EntryBinding RECNO_KEY_BINDING = new RecordNumberBinding(); 35 static final EntityBinding BYTE_ENTITY_BINDING = 36 new TestEntityBinding(false); 37 static final EntityBinding RECNO_ENTITY_BINDING = 38 new TestEntityBinding(true); 39 static final TestKeyAssigner BYTE_KEY_ASSIGNER = 40 new TestKeyAssigner(false); 41 static final TestKeyAssigner RECNO_KEY_ASSIGNER = 42 new TestKeyAssigner(true); 43 44 static final TestStore BTREE_UNIQ; 45 static final TestStore BTREE_DUP; 46 static final TestStore BTREE_DUPSORT; 47 static final TestStore BTREE_RECNUM; 48 static final TestStore HASH_UNIQ; 49 static final TestStore HASH_DUP; 50 static final TestStore HASH_DUPSORT; 51 static final TestStore QUEUE; 52 static final TestStore RECNO; 53 static final TestStore RECNO_RENUM; 54 55 static final TestStore[] ALL; 56 static { 57 List list = new ArrayList(); 58 SecondaryConfig config; 59 60 config = new SecondaryConfig(); 61 DbCompat.setTypeBtree(config); 62 BTREE_UNIQ = new TestStore("btree-uniq", config); 63 BTREE_UNIQ.indexOf = BTREE_UNIQ; 64 list.add(BTREE_UNIQ); 65 66 if (DbCompat.INSERTION_ORDERED_DUPLICATES) { 67 config = new SecondaryConfig(); 68 DbCompat.setTypeBtree(config); 69 DbCompat.setUnsortedDuplicates(config, true); 70 BTREE_DUP = new TestStore("btree-dup", config); 71 BTREE_DUP.indexOf = null; // indexes must use sorted dups 72 list.add(BTREE_DUP); 73 } else { 74 BTREE_DUP = null; 75 } 76 77 config = new SecondaryConfig(); 78 DbCompat.setTypeBtree(config); 79 DbCompat.setSortedDuplicates(config, true); 80 BTREE_DUPSORT = new TestStore("btree-dupsort", config); 81 BTREE_DUPSORT.indexOf = BTREE_UNIQ; 82 list.add(BTREE_DUPSORT); 83 84 if (DbCompat.BTREE_RECNUM_METHOD) { 85 config = new SecondaryConfig(); 86 DbCompat.setTypeBtree(config); 87 DbCompat.setBtreeRecordNumbers(config, true); 88 BTREE_RECNUM = new TestStore("btree-recnum", config); 89 BTREE_RECNUM.indexOf = BTREE_RECNUM; 90 list.add(BTREE_RECNUM); 91 } else { 92 BTREE_RECNUM = null; 93 } 94 95 if (DbCompat.HASH_METHOD) { 96 config = new SecondaryConfig(); 97 DbCompat.setTypeHash(config); 98 HASH_UNIQ = new TestStore("hash-uniq", config); 99 HASH_UNIQ.indexOf = HASH_UNIQ; 100 list.add(HASH_UNIQ); 101 102 if (DbCompat.INSERTION_ORDERED_DUPLICATES) { 103 config = new SecondaryConfig(); 104 DbCompat.setTypeHash(config); 105 DbCompat.setUnsortedDuplicates(config, true); 106 HASH_DUP = new TestStore("hash-dup", config); 107 HASH_DUP.indexOf = null; // indexes must use sorted dups 108 list.add(HASH_DUP); 109 } else { 110 HASH_DUP = null; 111 } 112 113 config = new SecondaryConfig(); 114 DbCompat.setTypeHash(config); 115 DbCompat.setSortedDuplicates(config, true); 116 HASH_DUPSORT = new TestStore("hash-dupsort", config); 117 HASH_DUPSORT.indexOf = HASH_UNIQ; 118 list.add(HASH_DUPSORT); 119 } else { 120 HASH_UNIQ = null; 121 HASH_DUP = null; 122 HASH_DUPSORT = null; 123 } 124 125 if (DbCompat.QUEUE_METHOD) { 126 config = new SecondaryConfig(); 127 DbCompat.setTypeQueue(config); 128 QUEUE = new TestStore("queue", config); 129 QUEUE.indexOf = QUEUE; 130 list.add(QUEUE); 131 } else { 132 QUEUE = null; 133 } 134 135 if (DbCompat.RECNO_METHOD) { 136 config = new SecondaryConfig(); 137 DbCompat.setTypeRecno(config); 138 RECNO = new TestStore("recno", config); 139 RECNO.indexOf = RECNO; 140 list.add(RECNO); 141 142 config = new SecondaryConfig(); 143 DbCompat.setTypeRecno(config); 144 DbCompat.setRenumbering(config, true); 145 RECNO_RENUM = new TestStore("recno-renum", config); 146 RECNO_RENUM.indexOf = null; // indexes must have stable keys 147 list.add(RECNO_RENUM); 148 } else { 149 RECNO = null; 150 RECNO_RENUM = null; 151 } 152 153 ALL = new TestStore[list.size()]; 154 list.toArray(ALL); 155 } 156 157 private String name; 158 private SecondaryConfig config; 159 private TestStore indexOf; 160 private boolean isRecNumFormat; 161 162 private TestStore(String name, SecondaryConfig config) { 163 164 this.name = name; 165 this.config = config; 166 167 isRecNumFormat = isQueueOrRecno() || 168 (DbCompat.isTypeBtree(config) && 169 DbCompat.getBtreeRecordNumbers(config)); 170 } 171 172 EntryBinding getValueBinding() { 173 174 return VALUE_BINDING; 175 } 176 177 EntryBinding getKeyBinding() { 178 179 return isRecNumFormat ? RECNO_KEY_BINDING : BYTE_KEY_BINDING; 180 } 181 182 EntityBinding getEntityBinding() { 183 184 return isRecNumFormat ? RECNO_ENTITY_BINDING : BYTE_ENTITY_BINDING; 185 } 186 187 TestKeyAssigner getKeyAssigner() { 188 189 if (isQueueOrRecno()) { 190 return null; 191 } else { 192 if (isRecNumFormat) { 193 return RECNO_KEY_ASSIGNER; 194 } else { 195 return BYTE_KEY_ASSIGNER; 196 } 197 } 198 } 199 200 String getName() { 201 202 return name; 203 } 204 205 boolean isOrdered() { 206 207 return !DbCompat.isTypeHash(config); 208 } 209 210 boolean isQueueOrRecno() { 211 212 return DbCompat.isTypeQueue(config) || DbCompat.isTypeRecno(config); 213 } 214 215 boolean areKeyRangesAllowed() { 216 return isOrdered() && !isQueueOrRecno(); 217 } 218 219 boolean areDuplicatesAllowed() { 220 221 return DbCompat.getSortedDuplicates(config) || 222 DbCompat.getUnsortedDuplicates(config); 223 } 224 225 boolean hasRecNumAccess() { 226 227 return isRecNumFormat; 228 } 229 230 boolean areKeysRenumbered() { 231 232 return hasRecNumAccess() && 233 (DbCompat.isTypeBtree(config) || 234 DbCompat.getRenumbering(config)); 235 } 236 237 TestStore getIndexOf() { 238 239 return DbCompat.SECONDARIES ? indexOf : null; 240 } 241 242 Database open(Environment env, String fileName) 243 throws IOException, DatabaseException { 244 245 int fixedLen = (isQueueOrRecno() ? 1 : 0); 246 return openDb(env, fileName, fixedLen, null); 247 } 248 249 Database openIndex(Database primary, String fileName) 250 throws IOException, DatabaseException { 251 252 int fixedLen = (isQueueOrRecno() ? 4 : 0); 253 config.setKeyCreator(isRecNumFormat ? RECNO_EXTRACTOR 254 : BYTE_EXTRACTOR); 255 Environment env = primary.getEnvironment(); 256 return openDb(env, fileName, fixedLen, primary); 257 } 258 259 private Database openDb(Environment env, String fileName, int fixedLen, 260 Database primary) 261 throws IOException, DatabaseException { 262 263 if (fixedLen > 0) { 264 DbCompat.setRecordLength(config, fixedLen); 265 DbCompat.setRecordPad(config, 0); 266 } else { 267 DbCompat.setRecordLength(config, 0); 268 } 269 config.setAllowCreate(true); 270 DbCompat.setReadUncommitted(config, true); 271 config.setTransactional(CurrentTransaction.getInstance(env) != null); 272 if (primary != null) { 273 return DbCompat.testOpenSecondaryDatabase 274 (env, null, fileName, null, primary, config); 275 } else { 276 return DbCompat.testOpenDatabase 277 (env, null, fileName, null, config); 278 } 279 } 280} 281