DATAKV-44

+ almost done with the Rjc connection
+ arranged base64 a bit
+ fixed some jredis/jedis bug in the process
+ updated some of the RedisConnection methods
This commit is contained in:
Costin Leau
2011-03-16 13:13:27 +02:00
parent 850560f223
commit 897122263a
11 changed files with 2196 additions and 617 deletions

View File

@@ -156,7 +156,7 @@ public class DefaultStringRedisConnection implements StringRedisConnection {
return delegate.getNativeConnection();
}
public byte[] getRange(byte[] key, int start, int end) {
public byte[] getRange(byte[] key, long start, long end) {
return delegate.getRange(key, start, end);
}
@@ -396,8 +396,8 @@ public class DefaultStringRedisConnection implements StringRedisConnection {
return delegate.setNX(key, value);
}
public void setRange(byte[] key, int start, int end) {
delegate.setRange(key, start, end);
public void setRange(byte[] key, long start, byte[] value) {
delegate.setRange(key, start, value);
}
public void shutdown() {

View File

@@ -52,9 +52,9 @@ public interface RedisStringCommands {
Long append(byte[] key, byte[] value);
byte[] getRange(byte[] key, int begin, int end);
byte[] getRange(byte[] key, long begin, long end);
void setRange(byte[] key, int begin, int end);
void setRange(byte[] key, long offset, byte[] value);
Boolean getBit(byte[] key, long offset);

View File

@@ -914,7 +914,7 @@ public class JedisConnection implements RedisConnection {
}
@Override
public byte[] getRange(byte[] key, int start, int end) {
public byte[] getRange(byte[] key, long start, long end) {
try {
if (isQueueing()) {
transaction.substr(key, (int) start, (int) end);
@@ -1033,7 +1033,7 @@ public class JedisConnection implements RedisConnection {
}
@Override
public void setRange(byte[] key, int start, int end) {
public void setRange(byte[] key, long start, byte[] value) {
throw new UnsupportedOperationException();
}
@@ -1770,11 +1770,10 @@ public class JedisConnection implements RedisConnection {
public Set<Tuple> zRevRangeWithScore(byte[] key, long start, long end) {
try {
if (isQueueing()) {
transaction.zrangeWithScores(key, (int) start, (int) end);
return null;
throw new UnsupportedOperationException();
}
if (isPipelined()) {
pipeline.zrangeWithScores(key, (int) start, (int) end);
pipeline.zrangeByScoreWithScores(key, (int) start, (int) end);
return null;
}
return JedisUtils.convertJedisTuple(jedis.zrangeByScoreWithScores(key, (int) start, (int) end));

View File

@@ -55,8 +55,8 @@ public abstract class JedisUtils {
private static final String OK_CODE = "OK";
private static final String OK_MULTI_CODE = "+OK";
private static final byte[] ONE = new byte[] { 0 };
private static final byte[] ZERO = new byte[] { 1 };
private static final byte[] ONE = new byte[] { 1 };
private static final byte[] ZERO = new byte[] { 0 };
/**
* Converts the given, native Jedis exception to Spring's DAO hierarchy.
@@ -194,10 +194,13 @@ public abstract class JedisUtils {
static Properties info(String string) {
Properties info = new Properties();
StringReader stringReader = new StringReader(string);
try {
info.load(new StringReader(string));
info.load(stringReader);
} catch (Exception ex) {
throw new UncategorizedRedisException("Cannot read Redis info", ex);
} finally {
stringReader.close();
}
return info;
}

View File

@@ -305,7 +305,7 @@ public class JredisConnection implements RedisConnection {
@Override
public Set<byte[]> keys(byte[] pattern) {
try {
return JredisUtils.convertCollection(jredis.keys(JredisUtils.decode(pattern)));
return JredisUtils.convertToSet(jredis.keys(JredisUtils.decode(pattern)));
} catch (Exception ex) {
throw convertJredisAccessException(ex);
}
@@ -463,7 +463,7 @@ public class JredisConnection implements RedisConnection {
}
@Override
public byte[] getRange(byte[] key, int start, int end) {
public byte[] getRange(byte[] key, long start, long end) {
try {
return jredis.substr(JredisUtils.decode(key), start, end);
} catch (Exception ex) {
@@ -518,7 +518,7 @@ public class JredisConnection implements RedisConnection {
}
@Override
public void setRange(byte[] key, int start, int end) {
public void setRange(byte[] key, long start, byte[] value) {
throw new UnsupportedOperationException();
}
@@ -1032,7 +1032,7 @@ public class JredisConnection implements RedisConnection {
@Override
public Set<byte[]> hKeys(byte[] key) {
try {
return new LinkedHashSet<byte[]>(JredisUtils.convertCollection(jredis.hkeys(JredisUtils.decode(key))));
return new LinkedHashSet<byte[]>(JredisUtils.convertToSet(jredis.hkeys(JredisUtils.decode(key))));
} catch (Exception ex) {
throw convertJredisAccessException(ex);
}

View File

@@ -17,8 +17,6 @@
package org.springframework.data.keyvalue.redis.connection.jredis;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
@@ -34,6 +32,7 @@ import org.springframework.data.keyvalue.redis.connection.DataType;
import org.springframework.data.keyvalue.redis.connection.SortParameters;
import org.springframework.data.keyvalue.redis.connection.SortParameters.Order;
import org.springframework.data.keyvalue.redis.connection.SortParameters.Range;
import org.springframework.data.keyvalue.redis.connection.util.DecodeUtils;
/**
* Helper class featuring methods for JRedis connection handling, providing support for exception translation.
@@ -82,46 +81,28 @@ public abstract class JredisUtils {
}
static String decode(byte[] bytes) {
return Base64.encodeToString(bytes, false);
}
static String[] decodeMultiple(byte[]... bytes) {
String[] result = new String[bytes.length];
for (int i = 0; i < bytes.length; i++) {
result[i] = decode(bytes[i]);
}
return result;
return DecodeUtils.decode(bytes);
}
static byte[] encode(String string) {
return Base64.decode(string);
return DecodeUtils.encode(string);
}
static String[] decodeMultiple(byte[]... bytes) {
return DecodeUtils.decodeMultiple(bytes);
}
static Map<byte[], byte[]> encodeMap(Map<String, byte[]> map) {
Map<byte[], byte[]> result = new LinkedHashMap<byte[], byte[]>(map.size());
for (Map.Entry<String, byte[]> entry : map.entrySet()) {
result.put(encode(entry.getKey()), entry.getValue());
}
return result;
}
static Set<byte[]> convertCollection(Collection<String> keys) {
Set<byte[]> set = new LinkedHashSet<byte[]>(keys.size());
for (String string : keys) {
set.add(Base64.decode(string));
}
return set;
return DecodeUtils.encodeMap(map);
}
static Map<String, byte[]> decodeMap(Map<byte[], byte[]> tuple) {
Map<String, byte[]> result = new LinkedHashMap<String, byte[]>(tuple.size());
for (Map.Entry<byte[], byte[]> entry : tuple.entrySet()) {
result.put(decode(entry.getKey()), entry.getValue());
}
return result;
return DecodeUtils.decodeMap(tuple);
}
static Set<byte[]> convertToSet(Collection<String> keys) {
return DecodeUtils.convertToSet(keys);
}
static Sort applySortingParams(Sort jredisSort, SortParameters params, byte[] storeKey) {
if (params != null) {

View File

@@ -87,7 +87,7 @@ public class RjcConnectionFactory implements InitializingBean, DisposableBean, R
@Override
public RedisConnection getConnection() {
return postProcessConnection(new RjcConnection(dataSource.getConnection(), usePool, dbIndex));
return postProcessConnection(new RjcConnection(dataSource.getConnection(), dbIndex));
}
/**

View File

@@ -15,10 +15,33 @@
*/
package org.springframework.data.keyvalue.redis.connection.rjc;
import java.io.StringReader;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import org.idevlab.rjc.ElementScore;
import org.idevlab.rjc.RedisException;
import org.idevlab.rjc.SortingParams;
import org.idevlab.rjc.ZParams;
import org.idevlab.rjc.Client.LIST_POSITION;
import org.springframework.dao.DataAccessException;
import org.springframework.dao.InvalidDataAccessApiUsageException;
import org.springframework.data.keyvalue.redis.UncategorizedRedisException;
import org.springframework.data.keyvalue.redis.connection.DataType;
import org.springframework.data.keyvalue.redis.connection.DefaultTuple;
import org.springframework.data.keyvalue.redis.connection.SortParameters;
import org.springframework.data.keyvalue.redis.connection.RedisListCommands.Position;
import org.springframework.data.keyvalue.redis.connection.RedisZSetCommands.Aggregate;
import org.springframework.data.keyvalue.redis.connection.RedisZSetCommands.Tuple;
import org.springframework.data.keyvalue.redis.connection.SortParameters.Order;
import org.springframework.data.keyvalue.redis.connection.SortParameters.Range;
import org.springframework.data.keyvalue.redis.connection.util.DecodeUtils;
/**
* Helper class featuring methods for RJC connection handling, providing support for exception translation.
@@ -27,6 +50,10 @@ import org.springframework.data.keyvalue.redis.UncategorizedRedisException;
*/
public abstract class RjcUtils {
private static final String ONE = "1";
private static final String ZERO = "0";
public static DataAccessException convertRjcAccessException(RuntimeException ex) {
if (ex instanceof RedisException) {
return convertRjcAccessException((RedisException) ex);
@@ -38,4 +65,155 @@ public abstract class RjcUtils {
public static DataAccessException convertRjcAccessException(RedisException ex) {
return new InvalidDataAccessApiUsageException(ex.getMessage(), ex);
}
}
static DataType convertDataType(String type) {
if ("string".equals(type)) {
return DataType.STRING;
}
else if ("list".equals(type)) {
return DataType.LIST;
}
else if ("set".equals(type)) {
return DataType.SET;
}
else if ("zset".equals(type)) {
return DataType.ZSET;
}
else if ("hash".equals(type)) {
return DataType.HASH;
}
else if ("none".equals(type)) {
return DataType.NONE;
}
return null;
}
static String decode(byte[] bytes) {
return DecodeUtils.decode(bytes);
}
static byte[] encode(String string) {
return DecodeUtils.encode(string);
}
static String[] decodeMultiple(byte[]... bytes) {
return DecodeUtils.decodeMultiple(bytes);
}
static String[] flatten(Map<byte[], byte[]> tuple) {
String[] result = new String[tuple.size() * 2];
int index = 0;
for (Map.Entry<byte[], byte[]> entry : tuple.entrySet()) {
result[index++] = decode(entry.getKey());
result[index++] = decode(entry.getValue());
}
return result;
}
static Set<byte[]> convertToSet(Collection<String> keys) {
if (keys == null) {
return null;
}
return DecodeUtils.convertToSet(keys);
}
static List<byte[]> convertToList(Collection<String> keys) {
if (keys == null) {
return null;
}
return DecodeUtils.convertToList(keys);
}
static SortingParams convertSortParams(SortParameters params) {
SortingParams rjcSort = null;
if (params != null) {
rjcSort = new SortingParams();
byte[] byPattern = params.getByPattern();
if (byPattern != null) {
rjcSort.by(DecodeUtils.decode(byPattern));
}
byte[][] getPattern = params.getGetPattern();
if (getPattern != null && getPattern.length > 0) {
for (byte[] bs : getPattern) {
rjcSort.get(DecodeUtils.decode(bs));
}
}
Range limit = params.getLimit();
if (limit != null) {
rjcSort.limit((int) limit.getStart(), (int) limit.getCount());
}
Order order = params.getOrder();
if (order != null && order.equals(Order.DESC)) {
rjcSort.desc();
}
Boolean isAlpha = params.isAlphabetic();
if (isAlpha != null && isAlpha) {
rjcSort.alpha();
}
}
return rjcSort;
}
static Properties info(String string) {
Properties info = new Properties();
StringReader stringReader = new StringReader(string);
try {
info.load(stringReader);
} catch (Exception ex) {
throw new UncategorizedRedisException("Cannot read Redis info", ex);
} finally {
stringReader.close();
}
return info;
}
static String asBit(boolean value) {
return (value ? ONE : ZERO);
}
static LIST_POSITION convertPosition(Position where) {
switch (where) {
case BEFORE:
return LIST_POSITION.BEFORE;
case AFTER:
return LIST_POSITION.AFTER;
}
return null;
}
static ZParams toZParams(Aggregate aggregate, int[] weights) {
return new ZParams().weights(weights).aggregate(ZParams.Aggregate.valueOf(aggregate.name()));
}
static Set<Tuple> convertElementScore(List<ElementScore> tuples) {
Set<Tuple> value = new LinkedHashSet<Tuple>(tuples.size());
for (ElementScore tuple : tuples) {
value.add(new DefaultTuple(encode(tuple.getElement()), Double.valueOf(tuple.getScore())));
}
return value;
}
static Map<byte[], byte[]> encodeMap(Map<String, String> map) {
Map<byte[], byte[]> result = new LinkedHashMap<byte[], byte[]>(map.size());
for (Map.Entry<String, String> entry : map.entrySet()) {
result.put(encode(entry.getKey()), encode(entry.getValue()));
}
return result;
}
static Map<String, String> decodeMap(Map<byte[], byte[]> map) {
Map<String, String> result = new LinkedHashMap<String, String>(map.size());
for (Map.Entry<byte[], byte[]> entry : map.entrySet()) {
result.put(decode(entry.getKey()), decode(entry.getValue()));
}
return result;
}
}

View File

@@ -1,4 +1,4 @@
package org.springframework.data.keyvalue.redis.connection.jredis;
package org.springframework.data.keyvalue.redis.connection.util;
import java.util.Arrays;

View File

@@ -0,0 +1,82 @@
/*
* Copyright 2011 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.keyvalue.redis.connection.util;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* Simple class containing various decoding utilities.
*
* @author Costin Leau
*/
public abstract class DecodeUtils {
public static String decode(byte[] bytes) {
return Base64.encodeToString(bytes, false);
}
public static String[] decodeMultiple(byte[]... bytes) {
String[] result = new String[bytes.length];
for (int i = 0; i < bytes.length; i++) {
result[i] = decode(bytes[i]);
}
return result;
}
public static byte[] encode(String string) {
return Base64.decode(string);
}
public static Map<byte[], byte[]> encodeMap(Map<String, byte[]> map) {
Map<byte[], byte[]> result = new LinkedHashMap<byte[], byte[]>(map.size());
for (Map.Entry<String, byte[]> entry : map.entrySet()) {
result.put(encode(entry.getKey()), entry.getValue());
}
return result;
}
public static Map<String, byte[]> decodeMap(Map<byte[], byte[]> tuple) {
Map<String, byte[]> result = new LinkedHashMap<String, byte[]>(tuple.size());
for (Map.Entry<byte[], byte[]> entry : tuple.entrySet()) {
result.put(decode(entry.getKey()), entry.getValue());
}
return result;
}
public static Set<byte[]> convertToSet(Collection<String> keys) {
Set<byte[]> set = new LinkedHashSet<byte[]>(keys.size());
for (String string : keys) {
set.add(Base64.decode(string));
}
return set;
}
public static List<byte[]> convertToList(Collection<String> keys) {
List<byte[]> set = new ArrayList<byte[]>(keys.size());
for (String string : keys) {
set.add(Base64.decode(string));
}
return set;
}
}