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