DATAREDIS-512 - Skip repository index update checks on insert.

We now skip checking for existing index values on insert.

Related tickets: DATAREDIS-504.
Original pull request: #198.
This commit is contained in:
Christoph Strobl
2016-05-18 09:26:40 +02:00
committed by Mark Paluch
parent f732b5f6b9
commit 46f07d7056
5 changed files with 177 additions and 23 deletions

View File

@@ -25,6 +25,7 @@ import org.springframework.data.redis.core.convert.SimpleIndexedPropertyValue;
import org.springframework.data.redis.util.ByteUtils;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
/**
* {@link IndexWriter} takes care of writing <a href="http://redis.io/topics/indexes">secondary index</a> structures to
@@ -57,13 +58,27 @@ class IndexWriter {
this.converter = converter;
}
/**
* Initially creates indexes.
*
* @param key must not be {@literal null}.
* @param indexValues can be {@literal null}.
*/
public void createIndexes(Object key, Iterable<IndexedData> indexValues) {
createOrUpdateIndexes(key, indexValues, IndexWriteMode.CREATE);
}
/**
* Updates indexes by first removing key from existing one and then persisting new index data.
*
*
* @param key must not be {@literal null}.
* @param indexValues can be {@literal null}.
*/
public void updateIndexes(Object key, Iterable<IndexedData> indexValues) {
createOrUpdateIndexes(key, indexValues, IndexWriteMode.UPDATE);
}
private void createOrUpdateIndexes(Object key, Iterable<IndexedData> indexValues, IndexWriteMode writeMode) {
Assert.notNull(key, "Key must not be null!");
if (indexValues == null) {
@@ -72,7 +87,18 @@ class IndexWriter {
byte[] binKey = toBytes(key);
removeKeyFromExistingIndexes(binKey, indexValues);
if (ObjectUtils.nullSafeEquals(IndexWriteMode.UPDATE, writeMode)) {
if (indexValues.iterator().hasNext()) {
IndexedData data = indexValues.iterator().next();
if (data != null && data.getKeyspace() != null) {
removeKeyFromIndexes(data.getKeyspace(), binKey);
}
}
removeKeyFromExistingIndexes(binKey, indexValues);
}
addKeyToIndexes(binKey, indexValues);
}
@@ -123,8 +149,8 @@ class IndexWriter {
protected void removeKeyFromExistingIndexes(byte[] key, IndexedData indexedData) {
Assert.notNull(indexedData, "IndexedData must not be null!");
Set<byte[]> existingKeys = connection.keys(toBytes(indexedData.getKeyspace() + ":" + indexedData.getIndexName()
+ ":*"));
Set<byte[]> existingKeys = connection
.keys(toBytes(indexedData.getKeyspace() + ":" + indexedData.getIndexName() + ":*"));
if (!CollectionUtils.isEmpty(existingKeys)) {
for (byte[] existingKey : existingKeys) {
@@ -166,8 +192,8 @@ class IndexWriter {
// keep track of indexes used for the object
connection.sAdd(ByteUtils.concatAll(toBytes(indexedData.getKeyspace() + ":"), key, toBytes(":idx")), indexKey);
} else {
throw new IllegalArgumentException(String.format("Cannot write index data for unknown index type %s",
indexedData.getClass()));
throw new IllegalArgumentException(
String.format("Cannot write index data for unknown index type %s", indexedData.getClass()));
}
}
@@ -185,10 +211,17 @@ class IndexWriter {
return converter.getConversionService().convert(source, byte[].class);
}
throw new InvalidDataAccessApiUsageException(
String
.format(
"Cannot convert %s to binary representation for index key generation. Are you missing a Converter? Did you register a non PathBasedRedisIndexDefinition that might apply to a complex type?",
source.getClass()));
throw new InvalidDataAccessApiUsageException(String.format(
"Cannot convert %s to binary representation for index key generation. Are you missing a Converter? Did you register a non PathBasedRedisIndexDefinition that might apply to a complex type?",
source.getClass()));
}
/**
* @author Christoph Strobl
* @since 1.8
*/
private static enum IndexWriteMode {
CREATE, UPDATE
}
}

View File

@@ -25,7 +25,6 @@ import java.util.Set;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ApplicationListener;
@@ -38,7 +37,6 @@ import org.springframework.data.keyvalue.core.mapping.KeyValuePersistentProperty
import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.connection.MessageListener;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.convert.CustomConversions;
import org.springframework.data.redis.core.convert.KeyspaceConfiguration;
import org.springframework.data.redis.core.convert.MappingRedisConverter;
@@ -164,8 +162,7 @@ public class RedisKeyValueAdapter extends AbstractKeyValueAdapter
/**
* Default constructor.
*/
protected RedisKeyValueAdapter() {
}
protected RedisKeyValueAdapter() {}
/*
* (non-Javadoc)
@@ -198,7 +195,7 @@ public class RedisKeyValueAdapter extends AbstractKeyValueAdapter
byte[] key = toBytes(rdo.getId());
byte[] objectKey = createKey(rdo.getKeyspace(), rdo.getId());
connection.del(objectKey);
boolean isNew = connection.del(objectKey) == 0;
connection.hMSet(objectKey, rdo.getBucket().rawMap());
@@ -215,7 +212,12 @@ public class RedisKeyValueAdapter extends AbstractKeyValueAdapter
connection.sAdd(toBytes(rdo.getKeyspace()), key);
new IndexWriter(connection, converter).updateIndexes(key, rdo.getIndexedData());
IndexWriter indexWriter = new IndexWriter(connection, converter);
if (isNew) {
indexWriter.createIndexes(key, rdo.getIndexedData());
} else {
indexWriter.updateIndexes(key, rdo.getIndexedData());
}
return null;
}
});