1 /*- 2 * See the file LICENSE for redistribution information. 3 * 4 * Copyright (c) 2002, 2014 Oracle and/or its affiliates. All rights reserved. 5 * 6 */ 7 8 import static com.sleepycat.persist.model.Relationship.MANY_TO_ONE; 9 import static com.sleepycat.persist.model.Relationship.ONE_TO_ONE; 10 11 import com.sleepycat.je.CursorConfig; 12 import com.sleepycat.persist.EntityCursor; 13 import com.sleepycat.persist.EntityStore; 14 import com.sleepycat.persist.PrimaryIndex; 15 import com.sleepycat.persist.SecondaryIndex; 16 import com.sleepycat.persist.model.Entity; 17 import com.sleepycat.persist.model.PrimaryKey; 18 import com.sleepycat.persist.model.SecondaryKey; 19 20 @Entity 21 class RepTestData { 22 @SuppressWarnings("unused") 23 @PrimaryKey(sequence="KEY") 24 private int key; 25 26 @SuppressWarnings("unused") 27 @SecondaryKey(relate=ONE_TO_ONE) 28 private int data; 29 30 @SuppressWarnings("unused") 31 @SecondaryKey(relate=MANY_TO_ONE) 32 private String name; 33 setKey(int key)34 public void setKey(int key) { 35 this.key = key; 36 } 37 setData(int data)38 public void setData(int data) { 39 this.data = data; 40 } 41 setName(String name)42 public void setName(String name) { 43 this.name = name; 44 } 45 getKey()46 public int getKey() { 47 return key; 48 } 49 getData()50 public int getData() { 51 return data; 52 } 53 getName()54 public String getName() { 55 return name; 56 } 57 logicEquals(RepTestData object, int distance)58 public boolean logicEquals(RepTestData object, int distance) { 59 if (object == null) { 60 return false; 61 } 62 63 if (key == (object.getKey() + distance) && 64 data == (object.getData() + distance) && 65 name.equals(object.getName())) { 66 return true; 67 } 68 69 return false; 70 } 71 toString()72 public String toString() { 73 return "Instance: key = " + key + ", data = " + data + 74 ", name = " + name; 75 } 76 77 /* Insert dbSize records to the specified EntityStore. */ insertData(EntityStore dbStore, int dbSize)78 public static void insertData(EntityStore dbStore, int dbSize) 79 throws Exception { 80 81 insertData(dbStore, dbSize, false); 82 } 83 84 /* 85 * Insert dbSize reocrds to the specified EntityStore. 86 * 87 * If useFixedName is true, the name field will be assigned a fixed string, 88 * to make the assertion in ReplicaReading works corrrectly. 89 */ insertData(EntityStore dbStore, int dbSize, boolean useFixedName)90 public static void insertData(EntityStore dbStore, 91 int dbSize, 92 boolean useFixedName) 93 throws Exception { 94 95 PrimaryIndex<Integer, RepTestData> primaryIndex = 96 dbStore.getPrimaryIndex(Integer.class, RepTestData.class); 97 for (int i = 1; i <= dbSize; i++) { 98 RepTestData data = new RepTestData(); 99 data.setData(i); 100 data.setName(useFixedName ? "test" : generateNameField(i)); 101 primaryIndex.put(data); 102 } 103 System.out.println("num unique keys in names field = " + 104 countUniqueNames(dbStore, primaryIndex)); 105 dbStore.close(); 106 } 107 108 109 /* 110 * Vary the name field has a many-one secondary key. We will manipulate 111 * this data in order to create a duplicates data base with both single 112 * keys, and keys that have duplicate trees, to create more stress. 113 */ generateNameField(int index)114 public static String generateNameField(int index) { 115 if ((index % 5) == 0) { 116 return "testSingle_" + index; // singleton keys 117 } else if ((index % 7) == 0) { 118 return "test_7"; // dup tree of key=test7 119 } else if ((index % 4) == 0) { 120 return "test_4"; // dup tree of key=test4 121 } else if ((index % 3) == 0) { 122 return "test_3"; // dup tree of key=test3 123 } else if ((index % 2) == 0) { 124 return "test_2"; // dup tree of key=test2 125 } else { 126 return "testSingle_" + index; // singleton keys 127 } 128 } 129 130 /** 131 * Count the unique number of names in a entity store of RepTestData, in 132 * order to validate that there is a reasonable distribution of duplicate 133 * values. 134 */ 135 public static int countUniqueNames(EntityStore store, PrimaryIndex<Integer, RepTestData> primary)136 countUniqueNames(EntityStore store, 137 PrimaryIndex<Integer, RepTestData> primary) { 138 139 SecondaryIndex<String, Integer, RepTestData> recordByName = 140 store.getSecondaryIndex(primary, String.class, "name"); 141 EntityCursor<String> nameVals = 142 recordByName.keys(null, CursorConfig.READ_UNCOMMITTED); 143 int numUnique = 0; 144 while (nameVals.nextNoDup() != null) { 145 numUnique++; 146 147 } 148 nameVals.close(); 149 return numUnique; 150 } 151 } 152