1 8 9 package com.sleepycat.je.test; 10 11 import java.util.HashMap ; 12 import java.util.HashSet ; 13 import java.util.Iterator ; 14 import java.util.Map ; 15 import java.util.Set ; 16 17 import junit.framework.Test; 18 19 import com.sleepycat.je.Cursor; 20 import com.sleepycat.je.Database; 21 import com.sleepycat.je.DatabaseConfig; 22 import com.sleepycat.je.DatabaseEntry; 23 import com.sleepycat.je.DatabaseException; 24 import com.sleepycat.je.OperationStatus; 25 import com.sleepycat.je.SecondaryConfig; 26 import com.sleepycat.je.SecondaryCursor; 27 import com.sleepycat.je.SecondaryDatabase; 28 import com.sleepycat.je.SecondaryMultiKeyCreator; 29 import com.sleepycat.je.Transaction; 30 31 37 public class ToManyTest extends TxnTestCase { 38 39 48 private Map priMap0 = new HashMap (); 49 private Map secMap0 = new HashMap (); 50 private Database priDb; 51 private SecondaryDatabase secDb; 52 53 public static Test suite() { 54 55 60 return txnTestSuite(ToManyTest.class, null, 61 new String [] {TxnTestCase.TXN_USER, 62 TxnTestCase.TXN_AUTO}); 63 } 64 65 public void tearDown() 66 throws Exception { 67 68 super.tearDown(); 69 priMap0 = null; 70 secMap0 = null; 71 priDb = null; 72 secDb = null; 73 } 74 75 public void testManyToMany() 76 throws DatabaseException { 77 78 priDb = openPrimary("pri"); 79 secDb = openSecondary(priDb, "sec", true ); 80 81 writeAndVerify((byte) 0, new byte[] {}); 82 writeAndVerify((byte) 0, null); 83 writeAndVerify((byte) 0, new byte[] {0, 1, 2}); 84 writeAndVerify((byte) 0, null); 85 writeAndVerify((byte) 0, new byte[] {}); 86 writeAndVerify((byte) 0, new byte[] {0}); 87 writeAndVerify((byte) 0, new byte[] {0, 1}); 88 writeAndVerify((byte) 0, new byte[] {0, 1, 2}); 89 writeAndVerify((byte) 0, new byte[] {1, 2}); 90 writeAndVerify((byte) 0, new byte[] {2}); 91 writeAndVerify((byte) 0, new byte[] {}); 92 writeAndVerify((byte) 0, null); 93 94 writeAndVerify((byte) 0, new byte[] {0, 1, 2}); 95 writeAndVerify((byte) 1, new byte[] {1, 2, 3}); 96 writeAndVerify((byte) 0, null); 97 writeAndVerify((byte) 1, null); 98 writeAndVerify((byte) 0, new byte[] {0, 1, 2}); 99 writeAndVerify((byte) 1, new byte[] {1, 2, 3}); 100 writeAndVerify((byte) 0, new byte[] {0}); 101 writeAndVerify((byte) 1, new byte[] {3}); 102 writeAndVerify((byte) 0, null); 103 writeAndVerify((byte) 1, null); 104 105 secDb.close(); 106 priDb.close(); 107 } 108 109 public void testOneToMany() 110 throws DatabaseException { 111 112 priDb = openPrimary("pri"); 113 secDb = openSecondary(priDb, "sec", false ); 114 115 writeAndVerify((byte) 0, new byte[] {1, 5}); 116 writeAndVerify((byte) 1, new byte[] {2, 4}); 117 writeAndVerify((byte) 0, new byte[] {0, 1, 5, 6}); 118 writeAndVerify((byte) 1, new byte[] {2, 3, 4}); 119 write((byte) 0, new byte[] {3}, true ); 120 writeAndVerify((byte) 1, new byte[] {}); 121 writeAndVerify((byte) 0, new byte[] {0, 1, 2, 3, 4, 5, 6}); 122 writeAndVerify((byte) 0, null); 123 writeAndVerify((byte) 1, new byte[] {0, 1, 2, 3, 4, 5, 6}); 124 writeAndVerify((byte) 1, null); 125 126 secDb.close(); 127 priDb.close(); 128 } 129 130 134 private void writeAndVerify(byte priKey, byte[] priData) 135 throws DatabaseException { 136 137 write(priKey, priData, false ); 138 updateMaps(new Byte (priKey), bytesToSet(priData)); 139 verify(); 140 } 141 142 145 private void write(byte priKey, byte[] priData, boolean expectException) 146 throws DatabaseException { 147 148 DatabaseEntry keyEntry = new DatabaseEntry(new byte[] { priKey }); 149 DatabaseEntry dataEntry = new DatabaseEntry(priData); 150 151 Transaction txn = txnBegin(); 152 try { 153 OperationStatus status; 154 if (priData != null) { 155 status = priDb.put(txn, keyEntry, dataEntry); 156 } else { 157 status = priDb.delete(txn, keyEntry); 158 } 159 assertSame(OperationStatus.SUCCESS, status); 160 txnCommit(txn); 161 assertTrue(!expectException); 162 } catch (Exception e) { 163 txnAbort(txn); 164 assertTrue(e.toString(), expectException); 165 } 166 } 167 168 171 private void updateMaps(Byte priKey, Set newPriData) { 172 173 174 Set oldPriData = (Set ) priMap0.get(priKey); 175 if (oldPriData != null) { 176 for (Iterator i = oldPriData.iterator(); i.hasNext();) { 177 Byte secKey = (Byte ) i.next(); 178 Set priKeySet = (Set ) secMap0.get(secKey); 179 assertNotNull(priKeySet); 180 assertTrue(priKeySet.remove(priKey)); 181 if (priKeySet.isEmpty()) { 182 secMap0.remove(secKey); 183 } 184 } 185 } 186 187 if (newPriData != null) { 188 189 priMap0.put(priKey, newPriData); 190 191 for (Iterator i = newPriData.iterator(); i.hasNext();) { 192 Byte secKey = (Byte ) i.next(); 193 Set priKeySet = (Set ) secMap0.get(secKey); 194 if (priKeySet == null) { 195 priKeySet = new HashSet (); 196 secMap0.put(secKey, priKeySet); 197 } 198 assertTrue(priKeySet.add(priKey)); 199 } 200 } else { 201 202 priMap0.remove(priKey); 203 } 204 } 205 206 209 private void verify() 210 throws DatabaseException { 211 212 Transaction txn = txnBeginCursor(); 213 DatabaseEntry priKeyEntry = new DatabaseEntry(); 214 DatabaseEntry secKeyEntry = new DatabaseEntry(); 215 DatabaseEntry dataEntry = new DatabaseEntry(); 216 Map priMap1 = new HashMap (); 217 Map priMap2 = new HashMap (); 218 Map secMap1 = new HashMap (); 219 Map secMap2 = new HashMap (); 220 221 222 priMap2 = new HashMap (); 223 Cursor priCursor = priDb.openCursor(txn, null); 224 while (priCursor.getNext(priKeyEntry, dataEntry, null) == 225 OperationStatus.SUCCESS) { 226 Byte priKey = new Byte (priKeyEntry.getData()[0]); 227 Set priData = bytesToSet(dataEntry.getData()); 228 229 230 priMap1.put(priKey, priData); 231 232 233 for (Iterator i = priData.iterator(); i.hasNext();) { 234 Byte secKey = (Byte ) i.next(); 235 Set priKeySet = (Set ) secMap1.get(secKey); 236 if (priKeySet == null) { 237 priKeySet = new HashSet (); 238 secMap1.put(secKey, priKeySet); 239 } 240 assertTrue(priKeySet.add(priKey)); 241 } 242 243 247 if (priData.isEmpty()) { 248 priMap2.put(priKey, priData); 249 } 250 } 251 priCursor.close(); 252 253 254 SecondaryCursor secCursor = secDb.openSecondaryCursor(txn, null); 255 while (secCursor.getNext(secKeyEntry, priKeyEntry, dataEntry, null) == 256 OperationStatus.SUCCESS) { 257 Byte priKey = new Byte (priKeyEntry.getData()[0]); 258 Byte secKey = new Byte (secKeyEntry.getData()[0]); 259 260 261 Set priData = (Set ) priMap2.get(priKey); 262 if (priData == null) { 263 priData = new HashSet (); 264 priMap2.put(priKey, priData); 265 } 266 priData.add(secKey); 267 268 269 Set secData = (Set ) secMap2.get(secKey); 270 if (secData == null) { 271 secData = new HashSet (); 272 secMap2.put(secKey, secData); 273 } 274 secData.add(priKey); 275 } 276 secCursor.close(); 277 278 279 assertEquals(priMap0, priMap1); 280 assertEquals(priMap1, priMap2); 281 assertEquals(secMap0, secMap1); 282 assertEquals(secMap1, secMap2); 283 284 txnCommit(txn); 285 } 286 287 private Set bytesToSet(byte[] bytes) { 288 Set set = null; 289 if (bytes != null) { 290 set = new HashSet (); 291 for (int i = 0; i < bytes.length; i += 1) { 292 set.add(new Byte (bytes[i])); 293 } 294 } 295 return set; 296 } 297 298 private Database openPrimary(String name) 299 throws DatabaseException { 300 301 DatabaseConfig dbConfig = new DatabaseConfig(); 302 dbConfig.setTransactional(isTransactional); 303 dbConfig.setAllowCreate(true); 304 305 Transaction txn = txnBegin(); 306 try { 307 return env.openDatabase(txn, name, dbConfig); 308 } finally { 309 txnCommit(txn); 310 } 311 } 312 313 private SecondaryDatabase openSecondary(Database priDb, 314 String dbName, 315 boolean dups) 316 throws DatabaseException { 317 318 SecondaryConfig dbConfig = new SecondaryConfig(); 319 dbConfig.setTransactional(isTransactional); 320 dbConfig.setAllowCreate(true); 321 dbConfig.setSortedDuplicates(dups); 322 dbConfig.setMultiKeyCreator(new MyKeyCreator()); 323 324 Transaction txn = txnBegin(); 325 try { 326 return env.openSecondaryDatabase(txn, dbName, priDb, dbConfig); 327 } finally { 328 txnCommit(txn); 329 } 330 } 331 332 private static class MyKeyCreator implements SecondaryMultiKeyCreator { 333 334 public void createSecondaryKeys(SecondaryDatabase secondary, 335 DatabaseEntry key, 336 DatabaseEntry data, 337 Set results) 338 throws DatabaseException { 339 340 for (int i = 0; i < data.getSize(); i+= 1) { 341 results.add(new DatabaseEntry(data.getData(), i, 1)); 342 } 343 } 344 } 345 } 346 | Popular Tags |