From 98708e19b8065e7e0164feda147e69abe5b570d1 Mon Sep 17 00:00:00 2001 From: Nikita Date: Thu, 30 Jan 2014 21:10:41 +0400 Subject: [PATCH] Redisson.trySetComparator implemented --- .../java/org/redisson/RedissonSortedSet.java | 90 ++++++++++++++++++- .../java/org/redisson/core/RSortedSet.java | 7 ++ 2 files changed, 93 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/redisson/RedissonSortedSet.java b/src/main/java/org/redisson/RedissonSortedSet.java index eece218ad..63e8da771 100644 --- a/src/main/java/org/redisson/RedissonSortedSet.java +++ b/src/main/java/org/redisson/RedissonSortedSet.java @@ -1,7 +1,12 @@ package org.redisson; +import java.io.DataInputStream; +import java.io.Serializable; +import java.math.BigInteger; +import java.net.URL; +import java.net.URLConnection; +import java.security.MessageDigest; import java.util.Collection; -import java.util.Collections; import java.util.Comparator; import java.util.Iterator; import java.util.List; @@ -20,8 +25,24 @@ import com.lambdaworks.redis.ScoredValue; * * @param */ +// TODO comparator setup sync +// TODO lock up-down scores during adding an element public class RedissonSortedSet extends RedissonObject implements RSortedSet { + private static class NaturalComparator implements Comparator, Serializable { + + private static final long serialVersionUID = 7207038068494060240L; + + static final NaturalComparator NATURAL_ORDER = new NaturalComparator(); + + public int compare(V c1, V c2) { + Comparable c1co = (Comparable) c1; + Comparable c2co = (Comparable) c2; + return c1co.compareTo(c2co); + } + + } + public static class BinarySearchResult { private V value; @@ -55,11 +76,58 @@ public class RedissonSortedSet extends RedissonObject implements RSortedSet comparator = Collections.reverseOrder(Collections.reverseOrder()); + private Comparator comparator = NaturalComparator.NATURAL_ORDER; RedissonSortedSet(ConnectionManager connectionManager, String name) { super(name); this.connectionManager = connectionManager; + + loadComparator(); + } + + private void loadComparator() { + RedisConnection connection = connectionManager.connection(); + try { + String comparatorSign = connection.get(getComparatorKeyName()); + if (comparatorSign != null) { + String[] parts = comparatorSign.split(":"); + String className = parts[0]; + String sign = parts[1]; + + String result = calcClassSign(className); + if (!result.equals(sign)) { + throw new IllegalStateException("Local class signature of " + className + " differs from used by this SortedSet!"); + } + + Class clazz = Class.forName(className); + comparator = (Comparator) clazz.newInstance(); + } + } catch (Exception e) { + throw new IllegalStateException(e); + } finally { + connectionManager.release(connection); + } + } + + private static String calcClassSign(String name) { + try { + Class clazz = Class.forName(name); + URL c = clazz.getResource(clazz.getSimpleName() + ".class"); + + URLConnection cc = c.openConnection(); + byte[] classData = new byte[cc.getContentLength()]; + DataInputStream dataIs = new DataInputStream(cc.getInputStream()); + dataIs.readFully(classData); + dataIs.close(); + + MessageDigest crypt = MessageDigest.getInstance("SHA-1"); + crypt.reset(); + crypt.update(classData); + + return new BigInteger(1, crypt.digest()).toString(16); + } catch (Exception e) { + throw new IllegalStateException("Can't calculate sign of " + name, e); + } } @Override @@ -371,10 +439,24 @@ public class RedissonSortedSet extends RedissonObject implements RSortedSet comparator) { - // TODO Auto-generated method stub - return false; + RedisConnection connection = connectionManager.connection(); + try { + String className = comparator.getClass().getName(); + String comparatorSign = className + ":" + calcClassSign(className); + if (connection.setnx(getComparatorKeyName(), comparatorSign)) { + this.comparator = comparator; + return true; + } + return false; + } finally { + connectionManager.release(connection); + } } private double getScoreAtIndex(int index, RedisConnection connection) { diff --git a/src/main/java/org/redisson/core/RSortedSet.java b/src/main/java/org/redisson/core/RSortedSet.java index 5ecb35b87..699686004 100644 --- a/src/main/java/org/redisson/core/RSortedSet.java +++ b/src/main/java/org/redisson/core/RSortedSet.java @@ -5,6 +5,13 @@ import java.util.SortedSet; public interface RSortedSet extends SortedSet, RObject { + /** + * Sets new comparator only if current set is empty + * + * @param comparator + * @return true if new comparator setted + * false otherwise + */ boolean trySetComparator(Comparator comparator); }