Skip to content

Commit a50876a

Browse files
DATAREDIS-425 - Make sure index clean up removes values from all potential indexes.
1 parent be3a0f5 commit a50876a

File tree

3 files changed

+46
-9
lines changed

3 files changed

+46
-9
lines changed

src/main/java/org/springframework/data/redis/core/RedisKeyValueAdapter.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
import org.springframework.data.redis.core.convert.RedisData;
3535
import org.springframework.data.redis.core.convert.ReferenceResolverImpl;
3636
import org.springframework.data.redis.core.index.IndexConfiguration;
37+
import org.springframework.data.redis.util.ByteUtils;
3738
import org.springframework.data.util.CloseableIterator;
3839

3940
/**
@@ -88,6 +89,8 @@ public Object put(final Serializable id, final Object item, final Serializable k
8889
final RedisData rdo = new RedisData();
8990
converter.write(item, rdo);
9091

92+
final byte[] indexPostFixPattern = converter.toBytes(":*");
93+
9194
redisOps.execute(new RedisCallback<Object>() {
9295

9396
@Override
@@ -96,7 +99,18 @@ public Object doInRedis(RedisConnection connection) throws DataAccessException {
9699
connection.hMSet(rdo.getKey(), rdo.getData());
97100
connection.sAdd(rdo.getKeyspace(), rdo.getId());
98101

102+
// remove id from potential indexes since those might be invalid with the new data
103+
for (byte[] potentialIndex : rdo.getIndexPaths()) {
104+
105+
Set<byte[]> existingKeys = connection.keys(ByteUtils.concat(potentialIndex, indexPostFixPattern));
106+
107+
for (byte[] existingKey : existingKeys) {
108+
connection.sRem(existingKey, rdo.getId());
109+
}
110+
}
111+
99112
if (!rdo.getSimpleIndexKeys().isEmpty()) {
113+
100114
for (byte[] index : rdo.getSimpleIndexKeys()) {
101115
connection.sAdd(index, rdo.getId());
102116
}

src/main/java/org/springframework/data/redis/core/convert/MappingRedisConverter.java

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -343,23 +343,31 @@ public void doWithPersistentProperty(KeyValuePersistentProperty persistentProper
343343
.getTypeInformation().getActualType(), sink);
344344
} else {
345345

346-
if (indexConfiguration.hasIndexFor(entity.getKeySpace(), persistentProperty.getName())) {
346+
Object propertyValue = accessor.getProperty(persistentProperty);
347347

348-
// TODO: check all index types and add accordingly
349-
sink.addSimpleIndexKey(toBytes(persistentProperty.getName() + ":"
350-
+ accessor.getProperty(persistentProperty)));
348+
if (indexConfiguration.hasIndexFor(entity.getKeySpace(), propertyStringPath)) {
349+
350+
if (propertyValue != null) {
351+
sink.addSimpleIndexKey(toBytes(propertyStringPath + ":" + propertyValue));
352+
}
353+
354+
sink.addIndexPath(toBytes(propertyStringPath));
351355
}
352356

353357
else if (persistentProperty.isAnnotationPresent(Indexed.class)) {
354358

355359
// TOOD: read index type from annotation
356-
indexConfiguration.addIndexDefinition(new RedisIndexDefinition(entity.getKeySpace(), persistentProperty
357-
.getName(), IndexType.SIMPLE));
360+
indexConfiguration.addIndexDefinition(new RedisIndexDefinition(entity.getKeySpace(), propertyStringPath,
361+
IndexType.SIMPLE));
358362

359-
sink.addSimpleIndexKey(toBytes(persistentProperty.getName() + ":"
360-
+ accessor.getProperty(persistentProperty)));
363+
if (propertyValue != null) {
364+
sink.addSimpleIndexKey(toBytes(propertyStringPath + ":" + propertyValue));
365+
}
366+
367+
sink.addIndexPath(toBytes(propertyStringPath));
361368
}
362-
sink.addDataEntry(toBytes(propertyStringPath), toBytes(accessor.getProperty(persistentProperty)));
369+
370+
sink.addDataEntry(toBytes(propertyStringPath), toBytes(propertyValue));
363371
}
364372
}
365373
});

src/main/java/org/springframework/data/redis/core/convert/RedisData.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,11 +42,13 @@ public class RedisData {
4242

4343
private Map<ByteArrayWrapper, byte[]> data;
4444
private Set<ByteArrayWrapper> simpleIndexKeys;
45+
private Set<ByteArrayWrapper> indexPaths;
4546

4647
public RedisData() {
4748

4849
this.data = new LinkedHashMap<ByteArrayWrapper, byte[]>();
4950
this.simpleIndexKeys = new HashSet<ByteArrayWrapper>();
51+
this.indexPaths = new HashSet<ByteArrayWrapper>();
5052
}
5153

5254
public RedisData(Map<byte[], byte[]> raw) {
@@ -137,6 +139,10 @@ public void addSimpleIndexKey(byte[] bytes) {
137139
this.simpleIndexKeys.add(new ByteArrayWrapper(bytes));
138140
}
139141

142+
public void addIndexPath(byte[] path) {
143+
this.indexPaths.add(new ByteArrayWrapper(path));
144+
}
145+
140146
public Set<byte[]> getSimpleIndexKeys() {
141147

142148
Set<byte[]> target = new HashSet<byte[]>();
@@ -146,6 +152,15 @@ public Set<byte[]> getSimpleIndexKeys() {
146152
return target;
147153
}
148154

155+
public Set<byte[]> getIndexPaths() {
156+
157+
Set<byte[]> target = new HashSet<byte[]>();
158+
for (ByteArrayWrapper wrapper : this.indexPaths) {
159+
target.add(ByteUtils.concatAll(keyspace, PATH_SEPERATOR, wrapper.getArray()));
160+
}
161+
return target;
162+
}
163+
149164
/**
150165
* @return
151166
*/

0 commit comments

Comments
 (0)