+ arranged internal code better with respect to serialization util methods

+ fix annoying connection leakage in old integration test
This commit is contained in:
Costin Leau
2011-03-15 15:00:02 +02:00
parent e68430101d
commit 99ca110696
22 changed files with 157 additions and 153 deletions

View File

@@ -15,7 +15,6 @@
*/
package org.springframework.data.keyvalue.redis.connection;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
@@ -26,6 +25,7 @@ import java.util.Set;
import org.springframework.data.keyvalue.redis.UncategorizedRedisException;
import org.springframework.data.keyvalue.redis.serializer.RedisSerializer;
import org.springframework.data.keyvalue.redis.serializer.SerializationUtils;
import org.springframework.data.keyvalue.redis.serializer.StringRedisSerializer;
import org.springframework.util.Assert;
@@ -240,7 +240,7 @@ public class DefaultStringRedisConnection implements StringRedisConnection {
return delegate.isSubscribed();
}
public Collection<byte[]> keys(byte[] pattern) {
public Set<byte[]> keys(byte[] pattern) {
return delegate.keys(pattern);
}
@@ -593,28 +593,12 @@ public class DefaultStringRedisConnection implements StringRedisConnection {
}
private List<String> deserialize(Collection<byte[]> data) {
if (data == null) {
return null;
}
List<String> result = new ArrayList<String>(data.size());
for (byte[] raw : data) {
result.add(serializer.deserialize(raw));
}
return result;
private List<String> deserialize(List<byte[]> data) {
return SerializationUtils.deserialize(data, serializer);
}
private Set<String> deserialize(Set<byte[]> data) {
if (data == null) {
return null;
}
Set<String> result = new LinkedHashSet<String>(data.size());
for (byte[] raw : data) {
result.add(serializer.deserialize(raw));
}
return result;
return SerializationUtils.deserialize(data, serializer);
}
private String deserialize(byte[] data) {

View File

@@ -16,8 +16,8 @@
package org.springframework.data.keyvalue.redis.connection;
import java.util.Collection;
import java.util.List;
import java.util.Set;
/**
* Interface for the commands supported by Redis.
@@ -33,7 +33,7 @@ public interface RedisCommands extends RedisTxCommands, RedisStringCommands, Red
DataType type(byte[] key);
Collection<byte[]> keys(byte[] pattern);
Set<byte[]> keys(byte[] pattern);
byte[] randomKey();

View File

@@ -18,7 +18,6 @@ package org.springframework.data.keyvalue.redis.connection.jedis;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
@@ -577,7 +576,7 @@ public class JedisConnection implements RedisConnection {
}
@Override
public Collection<byte[]> keys(byte[] pattern) {
public Set<byte[]> keys(byte[] pattern) {
try {
if (isQueueing()) {
transaction.keys(pattern);

View File

@@ -16,7 +16,6 @@
package org.springframework.data.keyvalue.redis.connection.jredis;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.List;
@@ -300,7 +299,7 @@ public class JredisConnection implements RedisConnection {
}
@Override
public Collection<byte[]> keys(byte[] pattern) {
public Set<byte[]> keys(byte[] pattern) {
try {
return JredisUtils.convertCollection(jredis.keys(JredisUtils.decode(pattern)));
} catch (Exception ex) {

View File

@@ -16,11 +16,12 @@
package org.springframework.data.keyvalue.redis.connection.jredis;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import org.jredis.ClientRuntimeException;
import org.jredis.RedisException;
@@ -104,16 +105,15 @@ public abstract class JredisUtils {
return result;
}
static Collection<byte[]> convertCollection(Collection<String> keys) {
Collection<byte[]> list = new ArrayList<byte[]>(keys.size());
static Set<byte[]> convertCollection(Collection<String> keys) {
Set<byte[]> set = new LinkedHashSet<byte[]>(keys.size());
for (String string : keys) {
list.add(Base64.decode(string));
set.add(Base64.decode(string));
}
return list;
return set;
}
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()) {

View File

@@ -23,6 +23,7 @@ import java.util.Set;
import org.springframework.data.keyvalue.redis.connection.RedisConnection;
import org.springframework.data.keyvalue.redis.serializer.RedisSerializer;
import org.springframework.data.keyvalue.redis.serializer.SerializationUtils;
import org.springframework.util.Assert;
/**
@@ -130,18 +131,24 @@ abstract class AbstractOperations<K, V> {
return rawKeys;
}
<T extends Collection<V>> T deserializeValues(Collection<byte[]> rawValues, Class<T> type) {
return SerializationUtils.deserializeValues(rawValues, type, valueSerializer);
@SuppressWarnings("unchecked")
Set<V> deserializeValues(Set<byte[]> rawValues) {
return SerializationUtils.deserialize(rawValues, valueSerializer);
}
@SuppressWarnings("unchecked")
<T> Set<T> deserializeHashKeys(Collection<byte[]> rawKeys) {
return SerializationUtils.deserializeValues(rawKeys, Set.class, hashKeySerializer);
List<V> deserializeValues(List<byte[]> rawValues) {
return SerializationUtils.deserialize(rawValues, valueSerializer);
}
@SuppressWarnings("unchecked")
<T> List<T> deserializeHashValues(Collection<byte[]> rawValues) {
return SerializationUtils.deserializeValues(rawValues, List.class, hashValueSerializer);
<T> Set<T> deserializeHashKeys(Set<byte[]> rawKeys) {
return SerializationUtils.deserialize(rawKeys, hashKeySerializer);
}
@SuppressWarnings("unchecked")
<T> List<T> deserializeHashValues(List<byte[]> rawValues) {
return SerializationUtils.deserialize(rawValues, hashValueSerializer);
}
@SuppressWarnings("unchecked")
@@ -162,26 +169,25 @@ abstract class AbstractOperations<K, V> {
@SuppressWarnings("unchecked")
K deserializeKey(byte[] value) {
return (K) SerializationUtils.deserialize(value, keySerializer);
return (K) keySerializer.deserialize(value);
}
@SuppressWarnings("unchecked")
V deserializeValue(byte[] value) {
return (V) SerializationUtils.deserialize(value, valueSerializer);
return (V) valueSerializer.deserialize(value);
}
@SuppressWarnings("unchecked")
String deserializeString(byte[] value) {
return (String) SerializationUtils.deserialize(value, stringSerializer);
return (String) stringSerializer.deserialize(value);
}
@SuppressWarnings( { "unchecked" })
<HK> HK deserializeHashKey(byte[] value) {
return (HK) SerializationUtils.deserialize(value, hashKeySerializer);
return (HK) hashKeySerializer.deserialize(value);
}
@SuppressWarnings("unchecked")
<HV> HV deserializeHashValue(byte[] value) {
return (HV) SerializationUtils.deserialize(value, hashValueSerializer);
return (HV) hashValueSerializer.deserialize(value);
}
}

View File

@@ -119,7 +119,7 @@ class DefaultListOperations<K, V> extends AbstractOperations<K, V> implements Li
@SuppressWarnings("unchecked")
@Override
public List<V> doInRedis(RedisConnection connection) {
return deserializeValues(connection.lRange(rawKey, start, end), List.class);
return deserializeValues(connection.lRange(rawKey, start, end));
}
}, true);
}

View File

@@ -60,7 +60,7 @@ class DefaultSetOperations<K, V> extends AbstractOperations<K, V> implements Set
}
}, true);
return deserializeValues(rawValues, Set.class);
return deserializeValues(rawValues);
}
@Override
@@ -97,7 +97,7 @@ class DefaultSetOperations<K, V> extends AbstractOperations<K, V> implements Set
}
}, true);
return deserializeValues(rawValues, Set.class);
return deserializeValues(rawValues);
}
@Override
@@ -141,7 +141,7 @@ class DefaultSetOperations<K, V> extends AbstractOperations<K, V> implements Set
}
}, true);
return deserializeValues(rawValues, Set.class);
return deserializeValues(rawValues);
}
@Override
@@ -218,7 +218,7 @@ class DefaultSetOperations<K, V> extends AbstractOperations<K, V> implements Set
}
}, true);
return deserializeValues(rawValues, Set.class);
return deserializeValues(rawValues);
}
@Override

View File

@@ -130,7 +130,7 @@ class DefaultValueOperations<K, V> extends AbstractOperations<K, V> implements V
}
}, true);
return deserializeValues(rawValues, List.class);
return deserializeValues(rawValues);
}
@Override

View File

@@ -88,7 +88,7 @@ class DefaultZSetOperations<K, V> extends AbstractOperations<K, V> implements ZS
}
}, true);
return deserializeValues(rawValues, Set.class);
return deserializeValues(rawValues);
}
@SuppressWarnings("unchecked")
@@ -103,7 +103,7 @@ class DefaultZSetOperations<K, V> extends AbstractOperations<K, V> implements ZS
}
}, true);
return deserializeValues(rawValues, Set.class);
return deserializeValues(rawValues);
}
@Override
@@ -183,7 +183,7 @@ class DefaultZSetOperations<K, V> extends AbstractOperations<K, V> implements ZS
}
}, true);
return deserializeValues(rawValues, Set.class);
return deserializeValues(rawValues);
}
@Override

View File

@@ -29,9 +29,11 @@ import org.springframework.data.keyvalue.redis.connection.DataType;
import org.springframework.data.keyvalue.redis.connection.RedisConnection;
import org.springframework.data.keyvalue.redis.connection.RedisConnectionFactory;
import org.springframework.data.keyvalue.redis.connection.SortParameters;
import org.springframework.data.keyvalue.redis.core.query.QueryUtils;
import org.springframework.data.keyvalue.redis.core.query.SortQuery;
import org.springframework.data.keyvalue.redis.serializer.JdkSerializationRedisSerializer;
import org.springframework.data.keyvalue.redis.serializer.RedisSerializer;
import org.springframework.data.keyvalue.redis.serializer.SerializationUtils;
import org.springframework.data.keyvalue.redis.serializer.StringRedisSerializer;
import org.springframework.transaction.support.TransactionSynchronizationManager;
import org.springframework.util.Assert;
@@ -377,7 +379,7 @@ public class RedisTemplate<K, V> extends RedisAccessor implements RedisOperation
@SuppressWarnings("unchecked")
private K deserializeKey(byte[] value) {
return (K) SerializationUtils.deserialize(value, keySerializer);
return (K) keySerializer.deserialize(value);
}
//
@@ -503,7 +505,7 @@ public class RedisTemplate<K, V> extends RedisAccessor implements RedisOperation
}
}, true);
return (Set<K>) SerializationUtils.deserializeValues(rawKeys, Set.class, keySerializer);
return (Set<K>) SerializationUtils.deserialize(rawKeys, keySerializer);
}
@Override
@@ -638,11 +640,10 @@ public class RedisTemplate<K, V> extends RedisAccessor implements RedisOperation
return sort(query, valueSerializer);
}
@SuppressWarnings("unchecked")
@Override
public <T> List<T> sort(SortQuery<K> query, RedisSerializer<T> resultSerializer) {
final byte[] rawKey = rawKey(query.getKey());
final SortParameters params = SerializationUtils.convertQuery(query, stringSerializer);
final SortParameters params = QueryUtils.convertQuery(query, stringSerializer);
List<byte[]> vals = execute(new RedisCallback<List<byte[]>>() {
@Override
@@ -651,7 +652,7 @@ public class RedisTemplate<K, V> extends RedisAccessor implements RedisOperation
}
}, true);
return (List<T>) SerializationUtils.deserializeValues(vals, List.class, resultSerializer);
return SerializationUtils.deserialize(vals, resultSerializer);
}
@SuppressWarnings("unchecked")
@@ -685,7 +686,7 @@ public class RedisTemplate<K, V> extends RedisAccessor implements RedisOperation
public Long sort(SortQuery<K> query, K storeKey) {
final byte[] rawStoreKey = rawKey(storeKey);
final byte[] rawKey = rawKey(query.getKey());
final SortParameters params = SerializationUtils.convertQuery(query, stringSerializer);
final SortParameters params = QueryUtils.convertQuery(query, stringSerializer);
return execute(new RedisCallback<Long>() {
@Override

View File

@@ -13,45 +13,22 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.keyvalue.redis.core;
package org.springframework.data.keyvalue.redis.core.query;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.List;
import org.springframework.data.keyvalue.redis.connection.DefaultSortParameters;
import org.springframework.data.keyvalue.redis.connection.SortParameters;
import org.springframework.data.keyvalue.redis.core.query.SortQuery;
import org.springframework.data.keyvalue.redis.serializer.RedisSerializer;
/**
* Utility class with various serialization-related methods.
* Utilities for {@link SortQuery} implementations.
*
* @author Costin Leau
*/
public abstract class SerializationUtils {
public static <T> T deserialize(byte[] value, RedisSerializer<T> serializer) {
return serializer.deserialize(value);
}
@SuppressWarnings("unchecked")
static <T extends Collection<?>> T deserializeValues(Collection<byte[]> rawValues, Class<T> type, RedisSerializer<?> redisSerializer) {
// connection in pipeline/multi mode
if (rawValues == null) {
return null;
}
Collection<Object> values = (List.class.isAssignableFrom(type) ? new ArrayList<Object>(rawValues.size())
: new LinkedHashSet<Object>(rawValues.size()));
for (byte[] bs : rawValues) {
values.add(redisSerializer.deserialize(bs));
}
return (T) values;
}
public abstract class QueryUtils {
public static <K> SortParameters convertQuery(SortQuery<K> query, RedisSerializer<String> stringSerializer) {
@@ -59,7 +36,7 @@ public abstract class SerializationUtils {
query.getGetPattern(), stringSerializer), query.getOrder(), query.isAlphabetic());
}
public static byte[][] serialize(List<String> strings, RedisSerializer<String> stringSerializer) {
private static byte[][] serialize(List<String> strings, RedisSerializer<String> stringSerializer) {
List<byte[]> raw = null;
if (strings == null) {
@@ -73,4 +50,4 @@ public abstract class SerializationUtils {
}
return raw.toArray(new byte[raw.size()][]);
}
}
}

View File

@@ -15,7 +15,6 @@
*/
package org.springframework.data.keyvalue.redis.listener.adapter;
import java.io.Serializable;
import java.lang.reflect.InvocationTargetException;
import org.apache.commons.logging.Log;
@@ -152,8 +151,7 @@ public class MessageListenerAdapter implements MessageListener {
/**
* Set the serializer that will convert incoming raw Redis messages to
* listener method arguments.
* <p>The default converter is a {@link JdkSerializationRedisSerializer}, which is able
* to handle {@link Serializable} objects.
* <p>The default converter is a {@link StringRedisSerializer}.
*/
public void setSerializer(RedisSerializer<?> serializer) {
this.serializer = serializer;

View File

@@ -46,7 +46,7 @@ public class JacksonJsonRedisSerializer<T> implements RedisSerializer<T> {
@SuppressWarnings("unchecked")
@Override
public T deserialize(byte[] bytes) throws SerializationException {
if (SerializerUtils.isEmpty(bytes)) {
if (SerializationUtils.isEmpty(bytes)) {
return null;
}
try {
@@ -59,7 +59,7 @@ public class JacksonJsonRedisSerializer<T> implements RedisSerializer<T> {
@Override
public byte[] serialize(Object t) throws SerializationException {
if (t == null) {
return SerializerUtils.EMPTY_ARRAY;
return SerializationUtils.EMPTY_ARRAY;
}
try {
return this.objectMapper.writeValueAsBytes(t);

View File

@@ -34,7 +34,7 @@ public class JdkSerializationRedisSerializer implements RedisSerializer<Object>
@SuppressWarnings("unchecked")
@Override
public Object deserialize(byte[] bytes) {
if (SerializerUtils.isEmpty(bytes)) {
if (SerializationUtils.isEmpty(bytes)) {
return null;
}
@@ -48,7 +48,7 @@ public class JdkSerializationRedisSerializer implements RedisSerializer<Object>
@Override
public byte[] serialize(Object object) {
if (object == null) {
return SerializerUtils.EMPTY_ARRAY;
return SerializationUtils.EMPTY_ARRAY;
}
try {
return serializer.convert(object);

View File

@@ -72,7 +72,7 @@ public class OxmSerializer implements InitializingBean, RedisSerializer<Object>
@Override
public Object deserialize(byte[] bytes) throws SerializationException {
if (SerializerUtils.isEmpty(bytes)) {
if (SerializationUtils.isEmpty(bytes)) {
return null;
}
@@ -86,7 +86,7 @@ public class OxmSerializer implements InitializingBean, RedisSerializer<Object>
@Override
public byte[] serialize(Object t) throws SerializationException {
if (t == null) {
return SerializerUtils.EMPTY_ARRAY;
return SerializationUtils.EMPTY_ARRAY;
}
ByteArrayOutputStream stream = new ByteArrayOutputStream();

View File

@@ -0,0 +1,68 @@
/*
* 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.serializer;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
/**
* Utility class with various serialization-related methods.
*
* @author Costin Leau
*/
public abstract class SerializationUtils {
static final byte[] EMPTY_ARRAY = new byte[0];
static boolean isEmpty(byte[] data) {
return (data == null || data.length == 0);
}
@SuppressWarnings("unchecked")
static <T extends Collection<?>> T deserializeValues(Collection<byte[]> rawValues, Class<T> type, RedisSerializer<?> redisSerializer) {
// connection in pipeline/multi mode
if (rawValues == null) {
return null;
}
Collection<Object> values = (List.class.isAssignableFrom(type) ? new ArrayList<Object>(rawValues.size())
: new LinkedHashSet<Object>(rawValues.size()));
for (byte[] bs : rawValues) {
values.add(redisSerializer.deserialize(bs));
}
return (T) values;
}
@SuppressWarnings("unchecked")
public static <T> Set<T> deserialize(Set<byte[]> rawValues, RedisSerializer<T> redisSerializer) {
return deserializeValues(rawValues, Set.class, redisSerializer);
}
@SuppressWarnings("unchecked")
public static <T> List<T> deserialize(List<byte[]> rawValues, RedisSerializer<T> redisSerializer) {
return deserializeValues(rawValues, List.class, redisSerializer);
}
@SuppressWarnings("unchecked")
public static <T> Collection<T> deserialize(Collection<byte[]> rawValues, RedisSerializer<T> redisSerializer) {
return deserializeValues(rawValues, List.class, redisSerializer);
}
}

View File

@@ -1,29 +0,0 @@
/*
* 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.serializer;
/**
* Minimal class used for sharing pieces of code between the serializers
*
* @author Costin Leau
*/
abstract class SerializerUtils {
static final byte[] EMPTY_ARRAY = new byte[0];
static boolean isEmpty(byte[] data) {
return (data == null || data.length == 0);
}
}

View File

@@ -19,13 +19,17 @@ package org.springframework.data.keyvalue.redis.connection;
import static org.junit.Assert.*;
import java.util.Arrays;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Properties;
import java.util.Set;
import java.util.UUID;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.Test;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.dao.DataAccessException;
import org.springframework.data.keyvalue.redis.Address;
import org.springframework.data.keyvalue.redis.Person;
@@ -43,12 +47,30 @@ public abstract class AbstractConnectionIntegrationTests {
private static final String listName = "test-list";
private static final byte[] EMPTY_ARRAY = new byte[0];
protected abstract RedisConnectionFactory getConnectionFactory();
private static Set<RedisConnectionFactory> connFactories = new LinkedHashSet<RedisConnectionFactory>();
@Before
public void setUp() {
connection = new DefaultStringRedisConnection(getConnectionFactory().getConnection());
connFactories.add(getConnectionFactory());
}
@AfterClass
public static void cleanUp() {
if (connFactories != null) {
for (RedisConnectionFactory connectionFactory : connFactories) {
try {
((DisposableBean) connectionFactory).destroy();
} catch (Exception ex) {
System.err.println("Cannot clean factory " + connectionFactory + ex);
}
}
}
}
protected abstract RedisConnectionFactory getConnectionFactory();
@After
public void tearDown() {

View File

@@ -51,26 +51,6 @@ public class JRedisConnectionIntegrationTests extends AbstractConnectionIntegrat
System.out.println(jr.get("foobar"));
}
@Ignore("JRedis has connecting issues with null")
public void testNullSerialization() {
}
@Ignore("JRedis has connecting issues with null")
public void testHashNullValue() {
}
@Ignore("JRedis has connecting issues with null")
public void testHashNullKey() {
}
@Ignore("JRedis has connecting issues with null")
public void testNullValue() {
}
@Ignore("JRedis has connecting issues with null")
public void testNullKey() {
}
@Ignore("JRedis does not support pipelining")
public void testNullCollections() {
}

View File

@@ -25,8 +25,8 @@ import org.mockito.MockitoAnnotations;
import org.springframework.data.keyvalue.redis.connection.DefaultMessage;
import org.springframework.data.keyvalue.redis.connection.Message;
import org.springframework.data.keyvalue.redis.connection.MessageListener;
import org.springframework.data.keyvalue.redis.serializer.JdkSerializationRedisSerializer;
import org.springframework.data.keyvalue.redis.serializer.RedisSerializer;
import org.springframework.data.keyvalue.redis.serializer.StringRedisSerializer;
/**
* Unit test for MessageListenerAdapter.
@@ -35,16 +35,16 @@ import org.springframework.data.keyvalue.redis.serializer.RedisSerializer;
*/
public class MessageListenerTest {
private static final RedisSerializer serializer = new JdkSerializationRedisSerializer();
private static final RedisSerializer serializer = new StringRedisSerializer();
private static final String CHANNEL = "some::test:";
private static final byte[] RAW_CHANNEL = serializer.serialize(CHANNEL);
private static final String PAYLOAD = "do re mi";
private static final byte[] RAW_PAYLOAD = serializer.serialize(PAYLOAD);
private static final Message STRING_MSG = new DefaultMessage(RAW_PAYLOAD, RAW_CHANNEL);
private static final Message STRING_MSG = new DefaultMessage(RAW_CHANNEL, RAW_PAYLOAD);
private MessageListenerAdapter adapter;
interface Delegate {
public static interface Delegate {
void handleMessage(String argument);
void customMethod(String arg);
@@ -76,7 +76,6 @@ public class MessageListenerTest {
MessageListenerAdapter adapter = new MessageListenerAdapter(mock);
adapter.onMessage(STRING_MSG, null);
verify(mock).onMessage(STRING_MSG, null);
}

View File

@@ -141,7 +141,7 @@ public abstract class AbstractRedisZSetTest<T> extends AbstractRedisCollectionTe
assertEquals(Long.valueOf(0), zSet.rank(t1));
assertEquals(Long.valueOf(1), zSet.rank(t2));
assertEquals(Long.valueOf(2), zSet.rank(t3));
System.out.println(zSet.rank(getT()));
assertNull(zSet.rank(getT()));
//assertNull();
}