Merge lp:~pbeaman/akiban-persistit/fix-1073357-Value-getType into lp:akiban-persistit

Proposed by Peter Beaman
Status: Merged
Approved by: Peter Beaman
Approved revision: 392
Merged at revision: 387
Proposed branch: lp:~pbeaman/akiban-persistit/fix-1073357-Value-getType
Merge into: lp:akiban-persistit
Diff against target: 838 lines (+226/-528)
4 files modified
src/main/java/com/persistit/Key.java (+22/-0)
src/main/java/com/persistit/Value.java (+74/-3)
src/test/java/com/persistit/unit/KeyTest1.java (+25/-0)
src/test/java/com/persistit/unit/ValueTest4.java (+105/-525)
To merge this branch: bzr merge lp:~pbeaman/akiban-persistit/fix-1073357-Value-getType
Reviewer Review Type Date Requested Status
Akiban Build User Needs Fixing
Nathan Williams Approve
Review via email: mp+132758@code.launchpad.net

Description of the change

Fixes bug https://bugs.launchpad.net/akiban-persistit/+bug/1073357 in which the Value#getType() returns Object.class rather than the true type of the value field when that field contains a duplicate of an earlier value.

The Value object encodes object graphs in which possibly may include cycles. To do so it encodes the any reference to an object that has already been serialized into the value as a special "REREF" item with a reference handle. However the Value#getType() method did not follow the handle to the referenced object to determine its class. This proposal corrects that behavior and adds tests for it.

This branch also adds two convenience methods:

Value#skipNull
Key#skipNull

Each of these is equivalent to the corresponding class' isNull method, but if the field is detected to be null the field cursor is advanced to the next field. For example, Key#skipNull is equivalent to

  if (key.isNull()) {
    key.decodeNull();
    return true;
  } else {
    return false;
  }

These are intended to satisfy a need first identified by the server team and are intended to simplify coding in some use cases.

To post a comment you must log in.
Revision history for this message
Peter Beaman (pbeaman) wrote :

Note: the majority of ValueTest4 was deleted because it was identical to ValueTest3.

Revision history for this message
Yuval Shavit (yshavit) wrote :

I mentioned this in person to Peter, but it'd be nice to rename skipNull to isNullSkip or such. That way, the two methods would appear next to each other in IDEs with autocomplete. Not only would that be convenient, but it would also serve as a warning to anyone who (as many people do) navigates an API via autocomplete. Such a programmer would see these two similarly-named methods, and hopefully think, "hm, I should read what the distinction is."

As a slight variant, what about two overloads of isNull? One is isNull(boolean skipIfNull), the other is isNull() { return isNull(false); }. I merely mention that as a way of getting the same benefits (easy to find, autocomplete-friendly, yet consistent behavior for isNull() as compared to the other isXxx methods) with a bit less of linguistic hoop-jumping.

Revision history for this message
Peter Beaman (pbeaman) wrote :

Good idea, done. The method is now

isNull(boolean skipNull)

Revision history for this message
Yuval Shavit (yshavit) wrote :

Cool. I don't feel I'm qualified to comment on the rest of the merge prop, though if you'd like me to I can take a stab at it.

One comment on the test, lines 676-7, I believe the original bug was when the two objects were == (not just equal). So maybe create a new Long and then insert it twice, rather than inserting two unique Longs?

Revision history for this message
Nathan Williams (nwilliams) wrote :

Looks mostly fine.

What if valueCache() does not contain the object? I'm not terribly familiar with it, but it looks like that is filled lazily. For example, what about Value append(a), append(b), append(a), store, clear, fetch, skip, skip, getType?

review: Needs Information
Revision history for this message
Peter Beaman (pbeaman) wrote :

getValueCache() always returns a ValueCache instance, but that instance may be hollow. If it is hollow, the code throws an ISE. It's an illegal state because the only way to traverse a CLASS_REREF field is from the left, and therefore the referent should have been loaded first.

Revision history for this message
Peter Beaman (pbeaman) wrote :

Unless you skip the field, like you said... As usual I responded without reading your comment carefully enough.

Revision history for this message
Peter Beaman (pbeaman) wrote :

Modified further so that both get() and getType() correct return the value or type of the skipped field. See com.persistit.unit.ValueTest4#streamModeGetAfterSkip().

Thanks for identifying this issue.

Revision history for this message
Nathan Williams (nwilliams) wrote :

Looks plausible. And who am I to argue with passing tests.

review: Approve
Revision history for this message
Akiban Build User (build-akiban) wrote :

There were 2 failures during build/test:

* job persistit-build failed at build number 473: http://172.16.20.104:8080/job/persistit-build/473/

* view must-pass failed: persistit-build is yellow

review: Needs Fixing
Revision history for this message
Peter Beaman (pbeaman) wrote :

An InUseException which may be either (a) weird I/O on the test machine, or (b) a bug I'm currently trying to track down in the stress tests. At any rate, the failure is unrelated to the code changes so I am re-Approving.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'src/main/java/com/persistit/Key.java'
--- src/main/java/com/persistit/Key.java 2012-10-22 14:25:58 +0000
+++ src/main/java/com/persistit/Key.java 2012-11-06 17:54:23 +0000
@@ -3108,6 +3108,28 @@
3108 }3108 }
31093109
3110 /**3110 /**
3111 * Determine if the current segment would return <code>null</code> if
3112 * {@link #decode()} were called. As a side effect, if <code>skipNull</code>
3113 * is true and the segment does encode a <code>null</code> value, then the
3114 * index is advanced to the beginning of the next segment.
3115 *
3116 * @param skipNull
3117 * whether to advance the index past a null segment value
3118 * @return <code>true</code> if the current segment is null,
3119 * <code>false</code> otherwise.
3120 */
3121 public boolean isNull(final boolean skipNull) {
3122 if (getTypeCode() == TYPE_NULL) {
3123 if (skipNull) {
3124 _index = decodeEnd(_index + 1);
3125 }
3126 return true;
3127 } else {
3128 return false;
3129 }
3130 }
3131
3132 /**
3111 * Advance the index to the beginning of the next key segment. If the index3133 * Advance the index to the beginning of the next key segment. If the index
3112 * is already at the end of the key, then wrap it to the beginning and3134 * is already at the end of the key, then wrap it to the beginning and
3113 * return -1.3135 * return -1.
31143136
=== modified file 'src/main/java/com/persistit/Value.java'
--- src/main/java/com/persistit/Value.java 2012-09-25 21:00:18 +0000
+++ src/main/java/com/persistit/Value.java 2012-11-06 17:54:23 +0000
@@ -963,6 +963,30 @@
963 return getTypeHandle() == TYPE_NULL;963 return getTypeHandle() == TYPE_NULL;
964 }964 }
965965
966 /**
967 * Determine whether the data held by this <code>Value</code> is null. As a
968 * side effect, if <code>skipNull</code> is true and <a
969 * href="#_streamMode">Stream Mode</a> is enabled this method also advances
970 * the cursor to the next field if the current field is null.
971 *
972 * @param skipNull
973 * if <code>true</code>, the <code>Value</code> is in stream mode
974 * and the current field is null, then advance the cursor to next
975 * field
976 * @return <code>true</code> if the current state of this <code>Value</code>
977 * represents <i>null</i>.
978 */
979 public boolean isNull(final boolean skipNull) {
980 if (isNull()) {
981 if (skipNull && _depth > 0) {
982 _next++;
983 }
984 return true;
985 } else {
986 return false;
987 }
988 }
989
966 boolean isAntiValue() {990 boolean isAntiValue() {
967 return getTypeHandle() == CLASS_ANTIVALUE;991 return getTypeHandle() == CLASS_ANTIVALUE;
968 }992 }
@@ -1574,7 +1598,15 @@
1574 final int saveEnd = _end;1598 final int saveEnd = _end;
1575 try {1599 try {
1576 final int classHandle = nextType();1600 final int classHandle = nextType();
1577 if (classHandle > 0 && classHandle < CLASSES.length && CLASSES[classHandle] != null) {1601 if (classHandle == CLASS_REREF) {
1602 final int base = _bytes[_next++] & 0xFF;
1603 final int handle = decodeVariableLengthInt(base);
1604 final Object object = getValueCache().get(handle);
1605 if (object == null) {
1606 throw new IllegalStateException("Reference to handle " + handle + " has no value");
1607 }
1608 return object.getClass();
1609 } else if (classHandle > 0 && classHandle < CLASSES.length && CLASSES[classHandle] != null) {
1578 return CLASSES[classHandle];1610 return CLASSES[classHandle];
1579 } else if (classHandle == CLASS_ARRAY) {1611 } else if (classHandle == CLASS_ARRAY) {
1580 _depth++;1612 _depth++;
@@ -3956,8 +3988,12 @@
3956 * to be decoded and constructed.3988 * to be decoded and constructed.
3957 */3989 */
3958 public void skip() {3990 public void skip() {
3959 if (_depth == 0)3991 if (_depth == 0) {
3960 return;3992 return;
3993 }
3994 final int currentHandle = _serializedItemCount++;
3995 final int saveNext = _next;
3996 final int saveEnd = _end;
3961 final int classHandle = nextType();3997 final int classHandle = nextType();
3962 if (classHandle == 0)3998 if (classHandle == 0)
3963 return;3999 return;
@@ -3973,6 +4009,7 @@
3973 if (size >= 0) {4009 if (size >= 0) {
3974 _next += size;4010 _next += size;
3975 } else {4011 } else {
4012 getValueCache().put(currentHandle, new SkippedFieldMarker(this, saveNext, saveEnd));
3976 closeVariableLengthItem();4013 closeVariableLengthItem();
3977 }4014 }
3978 }4015 }
@@ -5015,7 +5052,12 @@
5015 * @return The object5052 * @return The object
5016 */5053 */
5017 Object get(final int handle) {5054 Object get(final int handle) {
5018 return _array[handle];5055 Object object = _array[handle];
5056 if (object instanceof SkippedFieldMarker) {
5057 object = ((SkippedFieldMarker) object).get();
5058 _array[handle] = object;
5059 }
5060 return object;
5019 }5061 }
50205062
5021 /**5063 /**
@@ -5078,6 +5120,35 @@
5078 }5120 }
5079 }5121 }
50805122
5123 private static class SkippedFieldMarker {
5124 final Value _value;
5125 final int _next;
5126 final int _end;
5127
5128 private SkippedFieldMarker(final Value value, final int next, final int end) {
5129 _value = value;
5130 _next = next;
5131 _end = end;
5132 }
5133
5134 private Object get() {
5135 final int saveDepth = _value._depth;
5136 final int saveLevel = _value._level;
5137 final int saveNext = _value._next;
5138 final int saveEnd = _value._end;
5139 try {
5140 _value._next = _next;
5141 _value._end = _end;
5142 return _value.get();
5143 } finally {
5144 _value._end = saveEnd;
5145 _value._next = saveNext;
5146 _value._level = saveLevel;
5147 _value._depth = saveDepth;
5148 }
5149 }
5150 }
5151
5081 static class Version {5152 static class Version {
5082 private final long _versionHandle;5153 private final long _versionHandle;
5083 private final long _commitTimestamp;5154 private final long _commitTimestamp;
50845155
=== modified file 'src/test/java/com/persistit/unit/KeyTest1.java'
--- src/test/java/com/persistit/unit/KeyTest1.java 2012-10-22 14:25:58 +0000
+++ src/test/java/com/persistit/unit/KeyTest1.java 2012-11-06 17:54:23 +0000
@@ -703,6 +703,31 @@
703 }703 }
704704
705 @Test705 @Test
706 public void testSkipNull() {
707 final Key key1 = new Key(_persistit);
708 key1.clear().append(null).append(1).append(2).append(null).append(null).append(5);
709 key1.reset();
710 assertTrue("seg0 is null: " + key1, key1.isNull(true));
711 assertFalse("seg1 is not null: " + key1, key1.isNull(true));
712 assertEquals("expect seg1 value", 1, key1.decode());
713 assertFalse("seg2 is not null: " + key1, key1.isNull(true));
714 assertEquals("expect seg2 value", 2, key1.decode());
715 assertTrue("seg3 is null: " + key1, key1.isNull(true));
716 assertTrue("seg4 is null: " + key1, key1.isNull(true));
717 assertFalse("seg5 is not null:" + key1, key1.isNull(true));
718 assertFalse("seg5 is not null:" + key1, key1.isNull(true));
719 assertFalse("seg5 is not null:" + key1, key1.isNull(true));
720 assertEquals("expect seg5 value", 5, key1.decodeInt());
721
722 try {
723 key1.isNull(true);
724 Assert.fail("Expected MissingKeySegmentException!");
725 } catch (final MissingKeySegmentException e) {
726 // expected
727 }
728 }
729
730 @Test
706 public void testFirstUniqueSegmentDepth() {731 public void testFirstUniqueSegmentDepth() {
707 final Key key1 = new Key(_persistit);732 final Key key1 = new Key(_persistit);
708 final Key key2 = new Key(_persistit);733 final Key key2 = new Key(_persistit);
709734
=== modified file 'src/test/java/com/persistit/unit/ValueTest4.java'
--- src/test/java/com/persistit/unit/ValueTest4.java 2012-08-24 13:57:19 +0000
+++ src/test/java/com/persistit/unit/ValueTest4.java 2012-11-06 17:54:23 +0000
@@ -18,536 +18,116 @@
18import static org.junit.Assert.assertEquals;18import static org.junit.Assert.assertEquals;
19import static org.junit.Assert.assertTrue;19import static org.junit.Assert.assertTrue;
2020
21import java.io.Externalizable;
22import java.io.IOException;
23import java.io.ObjectInput;
24import java.io.ObjectInputStream;
25import java.io.ObjectOutput;
26import java.io.ObjectOutputStream;
27import java.io.ObjectStreamException;
28import java.io.ObjectStreamField;
29import java.io.Serializable;
30import java.util.ArrayList;
31
32import org.junit.Test;21import org.junit.Test;
3322
34import com.persistit.DefaultCoderManager;
35import com.persistit.DefaultValueCoder;
36import com.persistit.Exchange;
37import com.persistit.Persistit;
38import com.persistit.PersistitUnitTestCase;23import com.persistit.PersistitUnitTestCase;
39import com.persistit.Value;24import com.persistit.Value;
40import com.persistit.encoding.CoderContext;
41import com.persistit.encoding.CoderManager;
42import com.persistit.encoding.SerialValueCoder;
43import com.persistit.encoding.ValueCoder;
44import com.persistit.exception.PersistitException;
4525
46public class ValueTest4 extends PersistitUnitTestCase {26public class ValueTest4 extends PersistitUnitTestCase {
4727
48 /**28 private final static String ABC = "abc";
49 * Tests JSA 1.1 default serialization. Requires the29
50 * enableCompatibleConstructors to be true.30 @Test
51 */31 public void streamMode() throws Exception {
52 Exchange _exchange;32 final Value value = new Value(_persistit);
5333 value.setStreamMode(true);
54 public static class CustomSet extends ArrayList {34 value.put(1);
55 private final static long serialVersionUID = 1L;35 value.put(2f);
56 }36 value.put(ABC);
5737 value.put(ABC);
58 private static class T implements Serializable {38 value.put("xxabc".substring(2));
59 private final static long serialVersionUID = 1L;39 value.put(new Long(5));
6040 value.put(new Long(5));
61 private String _a;41 value.setStreamMode(false);
62 private String _b;42 value.setStreamMode(true);
6343 assertEquals("expect primitive int class", int.class, value.getType());
64 private T(final String a, final String b) {44 assertEquals("expect value", 1, value.get());
65 _a = a;45 assertEquals("expect primitive float class", float.class, value.getType());
66 _b = b;46 assertEquals("expect value", 2f, value.get());
67 }47 assertEquals("expect String class", String.class, value.getType());
6848 final String s1 = (String) value.get();
69 private T(final String a, final String b, final boolean f) {49 assertEquals("expect String class", String.class, value.getType());
70 _a = a;50 final String s2 = (String) value.get();
71 _b = b;51 assertEquals("expect String class", String.class, value.getType());
72 assertTrue("T 3-arg constructor should not be called", false);52 final String s3 = (String) value.get();
73 }53 assertEquals("expect value", ABC, s1);
7454 assertEquals("expect value", ABC, s2);
75 private T(final int x, final boolean y, final String z) {55 assertEquals("expect value", ABC, s3);
76 assertTrue("T 3-arg constructor should not be called", false);56 assertEquals("expect Long class", Long.class, value.getType());
77 }57 final Long l1 = (Long) value.get();
7858 assertEquals("expect Long class", Long.class, value.getType());
79 @Override59 final Long l2 = (Long) value.get();
80 public String toString() {60 assertEquals("expect equal values", l1, l2);
81 return "T:" + _a + _b;61 assertTrue("encoding of primitive wrapper classes loses identity", l1 == l2);
82 }62 assertTrue("interned constant \"abc\" has same identity", s1 == s2);
83 }63 assertTrue("computed object \"xxabc\".substring(2) has different identity", s1 != s3);
8464 }
85 private static class TT extends T {65
86 private final static long serialVersionUID = 1L;66 @Test
8767 public void streamModeSkipNull() throws Exception {
88 private TT(final String a, final String b) {68 final Value value = new Value(_persistit);
89 super(a, b);69 value.setStreamMode(true);
90 }70 value.put(1);
9171 value.put(2);
92 private TT(final String a, final String b, final boolean f) {72 value.put(null);
93 super(a, b, f);73 value.put(4);
94 }74 value.put(null);
9575 value.put(null);
96 private TT(final int x, final boolean y, final String z) {76 value.put(null);
97 super(x, y, z);77 value.put(8);
98 }78 value.setStreamMode(false);
9979 value.setStreamMode(true);
100 @Override80 assertEquals("expected value of field 1", 1, value.get());
101 public String toString() {81 assertEquals("expected value of field 2", 2, value.get());
102 return "T" + super.toString();82 assertTrue("field 3 is null, don't advance cursor", value.isNull());
103 }83 assertTrue("field 3 is null, don't advance cursor", value.isNull());
104 }84 assertTrue("field 3 is null, don't advance cursor", value.isNull());
10585 assertTrue("field 3 is null, do advance cursor", value.isNull(true));
106 private static class TTT extends TT {86 assertTrue("should be field 4", !value.isNull());
107 private final static long serialVersionUID = 1L;87 assertTrue("should be field 4", !value.isNull(true));
10888 assertEquals("expected value of field 4", 4, value.getInt());
109 private TTT(final String a, final String b) {89 assertTrue("field 5 should be null", value.isNull(true));
110 super(a, b);90 assertTrue("field 6 should be null", value.isNull(true));
111 assertTrue(a != null);91 assertTrue("field 7 should be null", value.isNull(true));
112 }92 assertTrue("field 8 should not be null", !value.isNull(true));
11393 assertTrue("field 8 should not be null", !value.isNull(true));
114 private TTT(final String a, final String b, final boolean f) {94 assertTrue("field 8 should not be null", !value.isNull(true));
115 super(a, b, f);95 assertTrue("field 8 should not be null", !value.isNull(true));
116 assertTrue(a != null);96 assertEquals("expected value of field 8", 8, value.get());
117 }97 }
11898
119 private TTT(final int x, final boolean y, final String z) {99 @Test
120 super(x, y, z);100 public void streamModeGetAfterSkip() throws Exception {
121 }101 final Value value = new Value(_persistit);
122102 value.setStreamMode(true);
123 @Override103 // All same instance due to constant intern
124 public String toString() {104 value.put(ABC);
125 return "T" + super.toString();105 value.put(2);
126 }106 value.put(ABC);
127107 value.put(4);
128 }108 value.put(ABC);
129109 value.put(6);
130 private static class TTTValueCoder extends DefaultValueCoder {110 value.put(ABC);
131 static int _getCounter;111 value.put(8);
132112 value.put(ABC);
133 TTTValueCoder(final Persistit persistit) {113 value.put(ABC);
134 super(persistit, TTT.class);114 value.put(ABC);
135 }115 value.setStreamMode(false);
136116 value.setStreamMode(true);
137 @Override117 value.skip(); // "abc"
138 public Object get(final Value value, final Class clazz, final CoderContext context) {118 assertEquals("expect 2", 2, value.getInt());
139 _getCounter++;119 value.skip(); // "abc"
140 final TTT ttt = new TTT("x", "y");120 assertEquals("expect 2", 4, value.getInt());
141 value.registerEncodedObject(ttt);121
142 render(value, ttt, clazz, context);122 assertEquals("Field 5 should be a String", String.class, value.getType());
143 return ttt;123 final String s5 = value.getString();
144 }124 assertEquals("expect value", ABC, s5);
145 }125
146126 assertEquals("expect 6", 6, value.getInt());
147 private static class S implements Serializable {127
148 String _a;128 assertEquals("Field 7 should be a String", String.class, value.getType());
149 String _b;129 final String s7 = value.getString();
150130 assertTrue("expect identical", s5 == s7);
151 private final static long serialVersionUID = 1L;131
152132 }
153 public void readObject(final ObjectInputStream ois) throws IOException, ClassNotFoundException {
154 ois.defaultReadObject();
155 }
156
157 public void writeObject(final ObjectOutputStream oos) throws IOException {
158 oos.defaultWriteObject();
159 }
160
161 @Override
162 public String toString() {
163 return "S:" + _a + _b;
164 }
165 }
166
167 private static class SS extends S {
168 private final static long serialVersionUID = 1L;
169
170 private final String _c;
171 private final String _d;
172 protected String _ff;
173
174 private SS(final String c, final String d) {
175 _c = c;
176 _d = d;
177 _ff = "Final field";
178 }
179
180 @Override
181 public String toString() {
182 return "S" + super.toString() + _c + _d;
183 }
184 }
185
186 private static class SSS extends SS {
187 private final static long serialVersionUID = 1L;
188
189 R _e;
190 private final W _f;
191
192 private SSS(final String c, final String d, final boolean e, final int f) {
193 super(c, d);
194 _e = new R(e);
195 _f = new W(f);
196 }
197
198 @Override
199 public String toString() {
200 return "S" + super.toString() + _e + _f;
201
202 }
203 }
204
205 private static class SSSS extends SSS {
206 private final static long serialVersionUID = 1L;
207
208 private String _g;
209 private String _h;
210
211 private SSSS() {
212 super("SSSS-c", "SSSS-d", true, 42);
213 _g = "Field g";
214 _h = "Field h";
215 }
216
217 private static final ObjectStreamField[] serialPersistentFields = { new ObjectStreamField("_g", String.class), };
218
219 @Override
220 public String toString() {
221 return "S" + super.toString() + _g + _h + _ff;
222 }
223 }
224
225 private static class R implements Serializable {
226 private final static long serialVersionUID = 1L;
227
228 final static R R_TRUE = new R(true);
229 final static R R_FALSE = new R(false);
230
231 boolean _value;
232
233 R(final boolean b) {
234 _value = b;
235 }
236
237 public Object readResolve() throws ObjectStreamException {
238 return _value ? R_TRUE : R_FALSE;
239 }
240
241 @Override
242 public String toString() {
243 if (this == R_TRUE) {
244 return "true";
245 } else if (this == R_FALSE) {
246 return "false";
247 } else {
248 return "notReplaced";
249 }
250 }
251 }
252
253 private static class W implements Serializable {
254 private final static long serialVersionUID = 1L;
255
256 int _value;
257
258 W(final int v) {
259 _value = v;
260 }
261
262 private Object writeReplace() throws ObjectStreamException {
263 return new WReplacement(_value);
264 }
265
266 @Override
267 public String toString() {
268 return "W:" + _value;
269 }
270 }
271
272 private static class WReplacement implements Serializable {
273 private final static long serialVersionUID = 1L;
274
275 int _value;
276
277 WReplacement(final int v) {
278 _value = v;
279 }
280
281 private Object readResolve() throws ObjectStreamException {
282 return new W(_value);
283 }
284
285 @Override
286 public String toString() {
287 return "WReplacement:" + _value;
288 }
289
290 }
291
292 private static class E implements Externalizable {
293 private final static long serialVersionUID = 1L;
294 String _a;
295 String _b;
296
297 public E() {
298 }
299
300 @Override
301 public void readExternal(final ObjectInput oi) throws IOException {
302 oi.readUTF(); // "foo"
303 _a = oi.readUTF();
304 _b = oi.readUTF();
305 }
306
307 @Override
308 public void writeExternal(final ObjectOutput oo) throws IOException {
309 oo.writeUTF("hello");
310 oo.writeUTF(_a);
311 oo.writeUTF(_b);
312 }
313
314 @Override
315 public String toString() {
316 return "E:" + _a + _b;
317 }
318 }
319
320 private static class EE extends E {
321 private final static long serialVersionUID = 1L;
322 private final Thread _thread = Thread.currentThread(); // intentionally
323
324 // not
325 // Serializable
326
327 public EE() {
328 super();
329 }
330
331 EE(final String a, final String b) {
332 _a = a;
333 _b = b;
334 }
335
336 @Override
337 public String toString() {
338 return "E" + super.toString() + (_thread != null ? "" : "");
339 }
340 }
341
342 @Override
343 public void setUp() throws Exception {
344 super.setUp();
345 _exchange = _persistit.getExchange("persistit", getClass().getSimpleName(), true);
346 }
347
348 @Override
349 public void tearDown() throws Exception {
350 _persistit.releaseExchange(_exchange);
351 _exchange = null;
352 super.tearDown();
353 }
354
355 @Test
356 public void test1() throws PersistitException {
357 System.out.print("test1 ");
358 final S s = new S();
359 s._a = "1";
360 s._b = "2";
361 _exchange.getValue().put(s);
362 _exchange.clear().append("test1").store();
363 final Object x = _exchange.getValue().get();
364 assertEquals("S:12", x.toString());
365 System.out.println("- done");
366 }
367
368 @Test
369 public void test2() throws PersistitException {
370 System.out.print("test2 ");
371 final SS ss = new SS("3", "4");
372 ss._a = "1";
373 ss._b = "2";
374 _exchange.getValue().put(ss);
375 _exchange.clear().append("test2").store();
376 final Object x = _exchange.getValue().get();
377 assertEquals("SS:1234", x.toString());
378 System.out.println("- done");
379 }
380
381 @Test
382 public void test3() throws PersistitException {
383 System.out.print("test3 ");
384 final E e = new E();
385 e._a = "1";
386 e._b = "2";
387 _exchange.getValue().put(e);
388 _exchange.clear().append("test3").store();
389 final Object x = _exchange.getValue().get();
390 assertEquals("E:12", x.toString());
391 System.out.println("- done");
392 }
393
394 @Test
395 public void test4() throws PersistitException {
396 System.out.print("test4 ");
397 final EE ee = new EE("6", "7");
398 ee._a = "1";
399 ee._b = "2";
400 _exchange.getValue().put(ee);
401 _exchange.clear().append("test4").store();
402 final Object x = _exchange.getValue().get();
403 assertEquals("EE:12", x.toString());
404 System.out.println("- done");
405 }
406
407 @Test
408 public void test5() throws PersistitException {
409 System.out.print("test5 ");
410 final T t = new T("1", "2");
411 _exchange.getValue().put(t);
412 _exchange.clear().append("test5").store();
413 final Object x = _exchange.getValue().get();
414 assertEquals("T:12", x.toString());
415 System.out.println("- done");
416 }
417
418 @Test
419 public void test6() throws PersistitException {
420 System.out.print("test6 ");
421 final TT tt = new TT("1", "2");
422 _exchange.getValue().put(tt);
423 _exchange.clear().append("test6").store();
424 final Object x = _exchange.getValue().get();
425 assertEquals("TT:12", x.toString());
426 System.out.println("- done");
427 }
428
429 @Test
430 public void test7() throws PersistitException {
431 System.out.print("test7 ");
432 final CoderManager cm = _persistit.getCoderManager();
433 cm.registerValueCoder(TTT.class, new TTTValueCoder(_persistit));
434 TTTValueCoder._getCounter = 0;
435 final TTT ttt = new TTT("1", "2");
436 _exchange.getValue().put(ttt);
437 _exchange.clear().append("test7").store();
438 final Object x = _exchange.getValue().get();
439 assertEquals("TTT:12", x.toString());
440 assertEquals(1, TTTValueCoder._getCounter);
441 cm.unregisterValueCoder(TTT.class);
442 System.out.println("- done");
443 }
444
445 @Test
446 public void test8() throws PersistitException {
447 System.out.print("test8 ");
448 final CoderManager cm = _persistit.getCoderManager();
449 cm.registerValueCoder(TTT.class, new TTTValueCoder(_persistit));
450 TTTValueCoder._getCounter = 0;
451 final TTT ttt = new TTT("1", "2");
452 _exchange.getValue().put(ttt);
453 _exchange.clear().append("test8").store();
454 final Object x = _exchange.getValue().get();
455 assertEquals("TTT:12", x.toString());
456 assertEquals(1, TTTValueCoder._getCounter);
457 cm.unregisterValueCoder(TTT.class);
458 System.out.println("- done");
459 }
460
461 @Test
462 public void test9() throws PersistitException {
463 System.out.print("test9 ");
464 final SSS sss = new SSS("3", "4", true, 5);
465 sss._a = "1";
466 sss._b = "2";
467 _exchange.getValue().put(sss);
468 _exchange.clear().append("test9").store();
469 final Object x = _exchange.getValue().get();
470 assertEquals("SSS:1234trueW:5", x.toString());
471 System.out.println("- done");
472 }
473
474 @Test
475 public void test10() throws PersistitException {
476 System.out.print("test10 ");
477 final SSS sss = new SSS("3", "4", true, 5);
478 sss._a = "1";
479 sss._b = "2";
480 _exchange.getValue().put(sss);
481 _exchange.clear().append("test10").store();
482 final Object x = _exchange.getValue().get();
483 assertEquals("SSS:1234trueW:5", x.toString());
484 System.out.println("- done");
485 }
486
487 @Test
488 public void test11() throws PersistitException {
489 System.out.print("test11 ");
490 final SSSS ssss = new SSSS();
491 ssss._a = "Field a";
492 ssss._b = "Field b";
493 ssss._g = "Field g";
494 ssss._h = "Field h";
495 _exchange.getValue().put(ssss);
496 _exchange.clear().append("test11").store();
497 final Object x = _exchange.getValue().get();
498 // assertEquals("SSSS:0000falsenull", x.toString());
499 System.out.print(" x=" + x + " ");
500 System.out.println();
501 System.out.println("Value: " + _exchange.getValue());
502 System.out.println("- done");
503 }
504
505 @Test
506 public void test12() throws PersistitException {
507 System.out.print("test12 ");
508 final CoderManager cm = _persistit.getCoderManager();
509 final ValueCoder defaultCoder = cm.getValueCoder(SSSS.class);
510 _persistit.getCoderManager().registerValueCoder(SSSS.class, new SerialValueCoder(SSSS.class));
511 final SSSS ssss = new SSSS();
512 ssss._a = "Field a";
513 ssss._b = "Field b";
514 ssss._g = "Field g";
515 ssss._h = "Field h";
516 _exchange.getValue().put(ssss);
517 _exchange.clear().append("test12").store();
518 final Object x = _exchange.getValue().get();
519 // assertEquals("SSSS:0000falsenull", x.toString());
520 System.out.print(" x=" + x + " ");
521 System.out.println();
522 System.out.println("Value: " + _exchange.getValue());
523 cm.registerValueCoder(SSSS.class, defaultCoder);
524 System.out.println("- done");
525 }
526
527 public static void main(final String[] args) throws Exception {
528 new ValueTest4().initAndRunTest();
529 }
530
531 @Override
532 public void runAllTests() throws Exception {
533 final CoderManager cm = _persistit.getCoderManager();
534 _persistit.setCoderManager(new DefaultCoderManager(_persistit, "com.persistit.unit.ValueTest4$*"));
535 _exchange = _persistit.getExchange("persistit", "ValueTest4", true);
536
537 test1();
538 test2();
539 test3();
540 test4();
541 test5();
542 test6();
543 test7();
544 test8();
545 test9();
546 test10();
547 test11();
548 test12();
549
550 _persistit.setCoderManager(cm);
551 }
552
553}133}

Subscribers

People subscribed via source and target branches