Skip to content

Commit 34e7a91

Browse files
author
Tim Wu
committed
TABQA-7386: Don't return VersionedValue around a null when calling getAllVersioned() on a removed key.
git-svn-id: https://svn.terracotta.org/repo/tc/dso/trunk@24908 7fc7bbf3-cf45-46d4-be06-341739edd864
1 parent 5f06f46 commit 34e7a91

File tree

4 files changed

+45
-18
lines changed

4 files changed

+45
-18
lines changed

dso-l1/src/main/java/com/tc/object/TCObjectServerMapImpl.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -766,7 +766,7 @@ private void getAllValuesForKeyFromServer(final SetMultimap<ObjectID, Object> ma
766766
// update the local cache of corresponding TCServerMap
767767
map.updateLocalCacheIfNecessary(key, data);
768768
if (versioned) {
769-
rv.put(key, new VersionedObject(data, value.getVersion()));
769+
rv.put(key, data == null ? null : new VersionedObject(data, value.getVersion()));
770770
} else {
771771
rv.put(key, data);
772772
}

dso-l1/src/test/java/com/tc/object/TCObjectServerMapImplTest.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ public Void answer(final InvocationOnMock invocation) throws Throwable {
5252
Map<Object, Object> result = (Map<Object, Object>)invocation.getArguments()[1];
5353
result.put("foo", new CompoundResponse(new ObjectID(3), 1, 2, 3, 4, 5));
5454
result.put("bar", new CompoundResponse(new ObjectID(3), 1, 2, 3, 4, 4));
55+
result.put("baz", new CompoundResponse(ObjectID.NULL_ID, 0, 0, 0, 0, 0));
5556
return null;
5657
}
5758
}).when(serverMapManager).getMappingForAllKeys(anyMap(), anyMap());
@@ -62,10 +63,12 @@ public Void answer(final InvocationOnMock invocation) throws Throwable {
6263
SetMultimap<ObjectID, Object> request = HashMultimap.create();
6364
request.put(objectID, "foo");
6465
request.put(new ObjectID(2), "bar");
66+
request.put(objectID, "baz");
6567

6668
Map<Object, VersionedObject> result = tcObjectServerMap.getAllVersioned(request);
6769

6870
assertThat(result, hasEntry((Object) "foo", new VersionedObject(expirableMapEntry, 5)));
6971
assertThat(result, hasEntry((Object) "bar", new VersionedObject(expirableMapEntry, 4)));
72+
assertThat(result, hasEntry((Object) "baz", null));
7073
}
7174
}

toolkit-impl/src/main/java/com/terracotta/toolkit/collections/map/ServerMap.java

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
import org.terracotta.toolkit.store.ToolkitConfigFields.Consistency;
2424

2525
import com.google.common.base.Preconditions;
26-
import com.google.common.collect.ImmutableMap;
2726
import com.google.common.collect.Maps;
2827
import com.google.common.collect.SetMultimap;
2928
import com.tc.abortable.AbortedOperationException;
@@ -1285,16 +1284,24 @@ public VersionedValue<V> getVersionedValue(Object key) {
12851284
@Override
12861285
public Map<K, VersionedValue<V>> getAllVersioned(final SetMultimap<ObjectID, K> mapIdToKeysMap) {
12871286
try {
1288-
return ImmutableMap.copyOf(Maps.transformEntries((Map)tcObjectServerMap.getAllVersioned((SetMultimap) mapIdToKeysMap),
1289-
new Maps.EntryTransformer<Object, VersionedObject, VersionedValue<V>>() {
1287+
return Collections.unmodifiableMap(new HashMap<K, VersionedValue<V>>(
1288+
Maps.transformEntries((Map)tcObjectServerMap.getAllVersioned((SetMultimap) mapIdToKeysMap),
1289+
new Maps.EntryTransformer<Object, VersionedObject, VersionedValue<V>>() {
12901290
@Override
12911291
public VersionedValue<V> transformEntry(final Object key, final VersionedObject value) {
1292+
if (value == null) {
1293+
return null;
1294+
}
12921295
V nonExpiredValue = checkAndGetNonExpiredValue((K)key,
12931296
value.getObject(), GetType.UNLOCKED, true);
1294-
return new VersionedValueImpl<V>(nonExpiredValue, value.getVersion());
1297+
if (nonExpiredValue == null) {
1298+
return null;
1299+
} else {
1300+
return new VersionedValueImpl<V>(nonExpiredValue, value.getVersion());
1301+
}
12951302
}
12961303
}
1297-
));
1304+
)));
12981305
} catch (AbortedOperationException e) {
12991306
throw new ToolkitAbortableOperationException(e);
13001307
}

toolkit-impl/src/test/java/com/terracotta/toolkit/collections/map/ServerMapTest.java

Lines changed: 29 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import org.terracotta.toolkit.builder.ToolkitCacheConfigBuilder;
99
import org.terracotta.toolkit.config.Configuration;
1010
import org.terracotta.toolkit.internal.cache.VersionedValue;
11+
import org.terracotta.toolkit.internal.store.ConfigFieldsInternal;
1112

1213
import com.google.common.collect.HashMultimap;
1314
import com.google.common.collect.Maps;
@@ -24,6 +25,7 @@
2425
import com.terracotta.toolkit.bulkload.BufferedOperation;
2526
import com.terracotta.toolkit.collections.servermap.api.ServerMapLocalStoreFactory;
2627
import com.terracotta.toolkit.factory.impl.ToolkitCacheDistributedTypeFactory;
28+
import com.terracotta.toolkit.object.serialization.CustomLifespanSerializedMapValue;
2729
import com.terracotta.toolkit.object.serialization.SerializationStrategy;
2830
import com.terracotta.toolkit.object.serialization.SerializedMapValue;
2931
import com.terracotta.toolkit.rejoin.PlatformServiceProvider;
@@ -40,6 +42,7 @@
4042
import static org.junit.Assert.assertEquals;
4143
import static org.mockito.Matchers.any;
4244
import static org.mockito.Matchers.anyBoolean;
45+
import static org.mockito.Matchers.anyInt;
4346
import static org.mockito.Matchers.eq;
4447
import static org.mockito.Matchers.isNull;
4548
import static org.mockito.Mockito.mock;
@@ -76,8 +79,7 @@ public void setUp() throws Exception {
7679

7780
@Test
7881
public void testCreateRemoveBufferedOperation() throws Exception {
79-
ServerMap serverMap = new ServerMap(configuration, "foo");
80-
serverMap.__tc_managed(tcObjectServerMap);
82+
ServerMap serverMap = getServerMap();
8183

8284
BufferedOperation bo = serverMap.createBufferedOperation(BufferedOperation.Type.REMOVE, "foo", null, 1, 2, 3, 4);
8385
assertThat(bo.getType(), is(BufferedOperation.Type.REMOVE));
@@ -87,8 +89,7 @@ public void testCreateRemoveBufferedOperation() throws Exception {
8789

8890
@Test
8991
public void testCreatePutIfAbsentBufferedOperation() throws Exception {
90-
ServerMap serverMap = new ServerMap(configuration, "foo");
91-
serverMap.__tc_managed(tcObjectServerMap);
92+
ServerMap serverMap = getServerMap();
9293

9394
BufferedOperation<String> bo = serverMap.createBufferedOperation(BufferedOperation.Type.PUT_IF_ABSENT, "foo", "bar", 1, 2, 3, 4);
9495
assertThat(bo.getType(), is(BufferedOperation.Type.PUT_IF_ABSENT));
@@ -101,8 +102,7 @@ public void testCreatePutIfAbsentBufferedOperation() throws Exception {
101102

102103
@Test
103104
public void testCreatePutBufferedOperation() throws Exception {
104-
ServerMap serverMap = new ServerMap(configuration, "foo");
105-
serverMap.__tc_managed(tcObjectServerMap);
105+
ServerMap serverMap = getServerMap();
106106

107107
BufferedOperation<String> bo = serverMap.createBufferedOperation(BufferedOperation.Type.PUT, "foo", "bar", 4, 3, 2, 1);
108108
assertThat(bo.getType(), is(BufferedOperation.Type.PUT));
@@ -115,8 +115,7 @@ public void testCreatePutBufferedOperation() throws Exception {
115115

116116
@Test
117117
public void testDrain() throws Exception {
118-
ServerMap serverMap = new ServerMap(configuration, "foo");
119-
serverMap.__tc_managed(tcObjectServerMap);
118+
ServerMap serverMap = getServerMap();
120119

121120
Map<String, BufferedOperation<String>> operations = new HashMap<String, BufferedOperation<String>>();
122121
operations.put("foo", serverMap.createBufferedOperation(BufferedOperation.Type.PUT, "foo", "bar", 4, 3, 2, 1));
@@ -131,27 +130,37 @@ public void testDrain() throws Exception {
131130

132131
@Test
133132
public void testGetAllVersioned() throws Exception {
134-
ServerMap serverMap = new ServerMap(configuration, "foo");
135-
serverMap.__tc_managed(tcObjectServerMap);
133+
ServerMap serverMap = getServerMap();
136134

137135
SetMultimap<ObjectID, Object> request = HashMultimap.create();
138136
request.putAll(new ObjectID(1), Sets.<Object>newHashSet("a", "b"));
139-
request.putAll(new ObjectID(2), Sets.<Object>newHashSet("c", "d"));
137+
request.putAll(new ObjectID(2), Sets.<Object>newHashSet("c", "d", "e", "f"));
140138

141139
Map<Object, Object> response = Maps.newHashMap();
142140
response.put("a", new VersionedObject(mockSerializedMapValue("1"), 1));
143141
response.put("b", new VersionedObject(mockSerializedMapValue("2"), 2));
144142
response.put("c", new VersionedObject(mockSerializedMapValue("3"), 3));
145143
response.put("d", new VersionedObject(mockSerializedMapValue("4"), 4));
144+
response.put("e", null);
145+
response.put("f", new VersionedObject(mockSerializedMapValue("5", true), 5));
146146

147147
when(tcObjectServerMap.getAllVersioned(request)).thenReturn(response);
148148

149149
Map<String, VersionedValue<String>> result = serverMap.getAllVersioned(request);
150-
assertEquals(4, result.size());
150+
assertEquals(6, result.size());
151151
assertThat(result, hasEntry("a", versionedValue("1", 1)));
152152
assertThat(result, hasEntry("b", versionedValue("2", 2)));
153153
assertThat(result, hasEntry("c", versionedValue("3", 3)));
154154
assertThat(result, hasEntry("d", versionedValue("4", 4)));
155+
assertThat(result, hasEntry("e", null));
156+
assertThat(result, hasEntry("f", null));
157+
}
158+
159+
private ServerMap getServerMap() {
160+
ServerMap serverMap = new ServerMap(configuration, "foo");
161+
serverMap.__tc_managed(tcObjectServerMap);
162+
serverMap.setLockStrategy(ConfigFieldsInternal.LOCK_STRATEGY.LONG_LOCK_STRATEGY);
163+
return serverMap;
155164
}
156165

157166
private static <T> VersionedValue<T> versionedValue(T value, long version) {
@@ -170,4 +179,12 @@ private static SerializedMapValue<String> mockSerializedMapValue(String value) t
170179
.thenReturn(value);
171180
return smv;
172181
}
182+
183+
private static SerializedMapValue<String> mockSerializedMapValue(String value, boolean expired) throws IOException, ClassNotFoundException {
184+
SerializedMapValue<String> smv = mock(CustomLifespanSerializedMapValue.class);
185+
when(smv.getDeserializedValue(any(SerializationStrategy.class), anyBoolean(), any(L1ServerMapLocalCacheStore.class), any(), anyBoolean()))
186+
.thenReturn(value);
187+
when(smv.isExpired(anyInt(), anyInt(), anyInt())).thenReturn(expired);
188+
return smv;
189+
}
173190
}

0 commit comments

Comments
 (0)