/
VersionedValueType.java
109 lines (97 loc) · 3.02 KB
/
VersionedValueType.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
/*
* Copyright 2004-2014 H2 Group. Multiple-Licensed under the MPL 2.0,
* and the EPL 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.lealone.transaction.local;
import java.nio.ByteBuffer;
import org.lealone.engine.DataType;
import org.lealone.engine.WriteBuffer;
import org.lealone.util.DataUtils;
/**
* The value type for a versioned value.
*/
class VersionedValueType implements DataType {
private final DataType valueType;
public VersionedValueType(DataType valueType) {
this.valueType = valueType;
}
@Override
public int getMemory(Object obj) {
VersionedValue v = (VersionedValue) obj;
return valueType.getMemory(v.value) + 8;
}
@Override
public int compare(Object aObj, Object bObj) {
if (aObj == bObj) {
return 0;
}
VersionedValue a = (VersionedValue) aObj;
VersionedValue b = (VersionedValue) bObj;
long comp = a.operationId - b.operationId;
if (comp == 0) {
return valueType.compare(a.value, b.value);
}
return Long.signum(comp);
}
@Override
public void read(ByteBuffer buff, Object[] obj, int len, boolean key) {
if (buff.get() == 0) {
// fast path (no op ids or null entries)
for (int i = 0; i < len; i++) {
VersionedValue v = new VersionedValue();
v.value = valueType.read(buff);
obj[i] = v;
}
} else {
// slow path (some entries may be null)
for (int i = 0; i < len; i++) {
obj[i] = read(buff);
}
}
}
@Override
public Object read(ByteBuffer buff) {
VersionedValue v = new VersionedValue();
v.operationId = DataUtils.readVarLong(buff);
if (buff.get() == 1) {
v.value = valueType.read(buff);
}
return v;
}
@Override
public void write(WriteBuffer buff, Object[] obj, int len, boolean key) {
boolean fastPath = true;
for (int i = 0; i < len; i++) {
VersionedValue v = (VersionedValue) obj[i];
if (v.operationId != 0 || v.value == null) {
fastPath = false;
}
}
if (fastPath) {
buff.put((byte) 0);
for (int i = 0; i < len; i++) {
VersionedValue v = (VersionedValue) obj[i];
valueType.write(buff, v.value);
}
} else {
// slow path:
// store op ids, and some entries may be null
buff.put((byte) 1);
for (int i = 0; i < len; i++) {
write(buff, obj[i]);
}
}
}
@Override
public void write(WriteBuffer buff, Object obj) {
VersionedValue v = (VersionedValue) obj;
buff.putVarLong(v.operationId);
if (v.value == null) {
buff.put((byte) 0);
} else {
buff.put((byte) 1);
valueType.write(buff, v.value);
}
}
}