Browse Source

Merge pull request #26 in CORE/base-third from ~RINOUX/base-third:feature/10.0 to feature/10.0

* commit '548d65b314f13fabe2e498e31d8e899e7348fc07':
  无JIRA任务 3rd加入jedis的包
10.0
superman 7 years ago
parent
commit
7626917872
  1. 17
      build.third_step6.gradle
  2. 118
      fine-jedis/src/com/fr/third/org/apache/commons/pool2/BaseKeyedPooledObjectFactory.java
  3. 45
      fine-jedis/src/com/fr/third/org/apache/commons/pool2/BaseObject.java
  4. 125
      fine-jedis/src/com/fr/third/org/apache/commons/pool2/BaseObjectPool.java
  5. 104
      fine-jedis/src/com/fr/third/org/apache/commons/pool2/BasePooledObjectFactory.java
  6. 230
      fine-jedis/src/com/fr/third/org/apache/commons/pool2/KeyedObjectPool.java
  7. 148
      fine-jedis/src/com/fr/third/org/apache/commons/pool2/KeyedPooledObjectFactory.java
  8. 178
      fine-jedis/src/com/fr/third/org/apache/commons/pool2/ObjectPool.java
  9. 1824
      fine-jedis/src/com/fr/third/org/apache/commons/pool2/PoolUtils.java
  10. 218
      fine-jedis/src/com/fr/third/org/apache/commons/pool2/PooledObject.java
  11. 137
      fine-jedis/src/com/fr/third/org/apache/commons/pool2/PooledObjectFactory.java
  12. 86
      fine-jedis/src/com/fr/third/org/apache/commons/pool2/PooledObjectState.java
  13. 36
      fine-jedis/src/com/fr/third/org/apache/commons/pool2/SwallowedExceptionListener.java
  14. 36
      fine-jedis/src/com/fr/third/org/apache/commons/pool2/TrackedUse.java
  15. 39
      fine-jedis/src/com/fr/third/org/apache/commons/pool2/UsageTracking.java
  16. 289
      fine-jedis/src/com/fr/third/org/apache/commons/pool2/impl/AbandonedConfig.java
  17. 1339
      fine-jedis/src/com/fr/third/org/apache/commons/pool2/impl/BaseGenericObjectPool.java
  18. 718
      fine-jedis/src/com/fr/third/org/apache/commons/pool2/impl/BaseObjectPoolConfig.java
  19. 54
      fine-jedis/src/com/fr/third/org/apache/commons/pool2/impl/CallStack.java
  20. 89
      fine-jedis/src/com/fr/third/org/apache/commons/pool2/impl/CallStackUtils.java
  21. 53
      fine-jedis/src/com/fr/third/org/apache/commons/pool2/impl/DefaultEvictionPolicy.java
  22. 297
      fine-jedis/src/com/fr/third/org/apache/commons/pool2/impl/DefaultPooledObject.java
  23. 114
      fine-jedis/src/com/fr/third/org/apache/commons/pool2/impl/DefaultPooledObjectInfo.java
  24. 115
      fine-jedis/src/com/fr/third/org/apache/commons/pool2/impl/DefaultPooledObjectInfoMBean.java
  25. 114
      fine-jedis/src/com/fr/third/org/apache/commons/pool2/impl/EvictionConfig.java
  26. 45
      fine-jedis/src/com/fr/third/org/apache/commons/pool2/impl/EvictionPolicy.java
  27. 129
      fine-jedis/src/com/fr/third/org/apache/commons/pool2/impl/EvictionTimer.java
  28. 1625
      fine-jedis/src/com/fr/third/org/apache/commons/pool2/impl/GenericKeyedObjectPool.java
  29. 195
      fine-jedis/src/com/fr/third/org/apache/commons/pool2/impl/GenericKeyedObjectPoolConfig.java
  30. 205
      fine-jedis/src/com/fr/third/org/apache/commons/pool2/impl/GenericKeyedObjectPoolMXBean.java
  31. 1203
      fine-jedis/src/com/fr/third/org/apache/commons/pool2/impl/GenericObjectPool.java
  32. 155
      fine-jedis/src/com/fr/third/org/apache/commons/pool2/impl/GenericObjectPoolConfig.java
  33. 219
      fine-jedis/src/com/fr/third/org/apache/commons/pool2/impl/GenericObjectPoolMXBean.java
  34. 57
      fine-jedis/src/com/fr/third/org/apache/commons/pool2/impl/InterruptibleReentrantLock.java
  35. 1425
      fine-jedis/src/com/fr/third/org/apache/commons/pool2/impl/LinkedBlockingDeque.java
  36. 48
      fine-jedis/src/com/fr/third/org/apache/commons/pool2/impl/NoOpCallStack.java
  37. 126
      fine-jedis/src/com/fr/third/org/apache/commons/pool2/impl/PoolImplUtils.java
  38. 98
      fine-jedis/src/com/fr/third/org/apache/commons/pool2/impl/PooledSoftReference.java
  39. 129
      fine-jedis/src/com/fr/third/org/apache/commons/pool2/impl/SecurityManagerCallStack.java
  40. 453
      fine-jedis/src/com/fr/third/org/apache/commons/pool2/impl/SoftReferenceObjectPool.java
  41. 86
      fine-jedis/src/com/fr/third/org/apache/commons/pool2/impl/ThrowableCallStack.java
  42. 42
      fine-jedis/src/com/fr/third/org/apache/commons/pool2/impl/package.html
  43. 50
      fine-jedis/src/com/fr/third/org/apache/commons/pool2/overview.html
  44. 63
      fine-jedis/src/com/fr/third/org/apache/commons/pool2/package.html
  45. 121
      fine-jedis/src/com/fr/third/org/apache/commons/pool2/proxy/BaseProxyHandler.java
  46. 54
      fine-jedis/src/com/fr/third/org/apache/commons/pool2/proxy/CglibProxyHandler.java
  47. 82
      fine-jedis/src/com/fr/third/org/apache/commons/pool2/proxy/CglibProxySource.java
  48. 53
      fine-jedis/src/com/fr/third/org/apache/commons/pool2/proxy/JdkProxyHandler.java
  49. 85
      fine-jedis/src/com/fr/third/org/apache/commons/pool2/proxy/JdkProxySource.java
  50. 134
      fine-jedis/src/com/fr/third/org/apache/commons/pool2/proxy/ProxiedKeyedObjectPool.java
  51. 126
      fine-jedis/src/com/fr/third/org/apache/commons/pool2/proxy/ProxiedObjectPool.java
  52. 51
      fine-jedis/src/com/fr/third/org/apache/commons/pool2/proxy/ProxySource.java
  53. 37
      fine-jedis/src/com/fr/third/org/apache/commons/pool2/proxy/package.html
  54. 1205
      fine-jedis/src/com/fr/third/redis/clients/jedis/BinaryClient.java
  55. 3850
      fine-jedis/src/com/fr/third/redis/clients/jedis/BinaryJedis.java
  56. 1977
      fine-jedis/src/com/fr/third/redis/clients/jedis/BinaryJedisCluster.java
  57. 127
      fine-jedis/src/com/fr/third/redis/clients/jedis/BinaryJedisPubSub.java
  58. 925
      fine-jedis/src/com/fr/third/redis/clients/jedis/BinaryShardedJedis.java
  59. 11
      fine-jedis/src/com/fr/third/redis/clients/jedis/BitOP.java
  60. 27
      fine-jedis/src/com/fr/third/redis/clients/jedis/BitPosParams.java
  61. 5
      fine-jedis/src/com/fr/third/redis/clients/jedis/Builder.java
  62. 482
      fine-jedis/src/com/fr/third/redis/clients/jedis/BuilderFactory.java
  63. 1123
      fine-jedis/src/com/fr/third/redis/clients/jedis/Client.java
  64. 5
      fine-jedis/src/com/fr/third/redis/clients/jedis/ClusterReset.java
  65. 328
      fine-jedis/src/com/fr/third/redis/clients/jedis/Connection.java
  66. 31
      fine-jedis/src/com/fr/third/redis/clients/jedis/DebugParams.java
  67. 47
      fine-jedis/src/com/fr/third/redis/clients/jedis/GeoCoordinate.java
  68. 37
      fine-jedis/src/com/fr/third/redis/clients/jedis/GeoRadiusResponse.java
  69. 13
      fine-jedis/src/com/fr/third/redis/clients/jedis/GeoUnit.java
  70. 153
      fine-jedis/src/com/fr/third/redis/clients/jedis/HostAndPort.java
  71. 3582
      fine-jedis/src/com/fr/third/redis/clients/jedis/Jedis.java
  72. 1979
      fine-jedis/src/com/fr/third/redis/clients/jedis/JedisCluster.java
  73. 170
      fine-jedis/src/com/fr/third/redis/clients/jedis/JedisClusterCommand.java
  74. 73
      fine-jedis/src/com/fr/third/redis/clients/jedis/JedisClusterConnectionHandler.java
  75. 268
      fine-jedis/src/com/fr/third/redis/clients/jedis/JedisClusterInfoCache.java
  76. 157
      fine-jedis/src/com/fr/third/redis/clients/jedis/JedisFactory.java
  77. 16
      fine-jedis/src/com/fr/third/redis/clients/jedis/JedisMonitor.java
  78. 258
      fine-jedis/src/com/fr/third/redis/clients/jedis/JedisPool.java
  79. 27
      fine-jedis/src/com/fr/third/redis/clients/jedis/JedisPoolAbstract.java
  80. 13
      fine-jedis/src/com/fr/third/redis/clients/jedis/JedisPoolConfig.java
  81. 179
      fine-jedis/src/com/fr/third/redis/clients/jedis/JedisPubSub.java
  82. 348
      fine-jedis/src/com/fr/third/redis/clients/jedis/JedisSentinelPool.java
  83. 252
      fine-jedis/src/com/fr/third/redis/clients/jedis/JedisShardInfo.java
  84. 82
      fine-jedis/src/com/fr/third/redis/clients/jedis/JedisSlotBasedConnectionHandler.java
  85. 12
      fine-jedis/src/com/fr/third/redis/clients/jedis/ListPosition.java
  86. 41
      fine-jedis/src/com/fr/third/redis/clients/jedis/Module.java
  87. 692
      fine-jedis/src/com/fr/third/redis/clients/jedis/MultiKeyPipelineBase.java
  88. 160
      fine-jedis/src/com/fr/third/redis/clients/jedis/Pipeline.java
  89. 1692
      fine-jedis/src/com/fr/third/redis/clients/jedis/PipelineBase.java
  90. 281
      fine-jedis/src/com/fr/third/redis/clients/jedis/Protocol.java
  91. 34
      fine-jedis/src/com/fr/third/redis/clients/jedis/Queable.java
  92. 77
      fine-jedis/src/com/fr/third/redis/clients/jedis/Response.java
  93. 78
      fine-jedis/src/com/fr/third/redis/clients/jedis/ScanParams.java
  94. 48
      fine-jedis/src/com/fr/third/redis/clients/jedis/ScanResult.java
  95. 934
      fine-jedis/src/com/fr/third/redis/clients/jedis/ShardedJedis.java
  96. 77
      fine-jedis/src/com/fr/third/redis/clients/jedis/ShardedJedisPipeline.java
  97. 120
      fine-jedis/src/com/fr/third/redis/clients/jedis/ShardedJedisPool.java
  98. 159
      fine-jedis/src/com/fr/third/redis/clients/jedis/SortingParams.java
  99. 94
      fine-jedis/src/com/fr/third/redis/clients/jedis/Transaction.java
  100. 80
      fine-jedis/src/com/fr/third/redis/clients/jedis/Tuple.java
  101. Some files were not shown because too many files have changed in this diff Show More

17
build.third_step6.gradle

@ -4,19 +4,19 @@ tasks.withType(JavaCompile){
options.encoding = 'UTF-8'
destinationDir = file('build/classes/6')
}
//jdk版本
//ָ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>jdk<EFBFBD>
sourceCompatibility=1.5
def jarname="fine-third-10.0.jar"
def classesDir='build/classes/6'
def ftpreport='E:/ftp/share/report/'
//lib下的jar到classes文件夹
//<EFBFBD><EFBFBD>ѹlib<EFBFBD>µ<EFBFBD>jar<EFBFBD><EFBFBD>classes<EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD>
jar{
baseName="fine-third_6-10.0"
}
def srcDir="."
//
//<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Դ<EFBFBD><EFBFBD>·<EFBFBD><EFBFBD>
sourceSets{
main{
java{
@ -30,6 +30,9 @@ sourceSets{
"${srcDir}/fine-lucene/resources",
"${srcDir}/fine-cglib/src",
"${srcDir}/fine-cglib/resources",
"${srcDir}/fine-jedis/src",
"${srcDir}/fine-jedis/resources",
]
}
}
@ -41,12 +44,12 @@ repositories{
mavenCentral()
}
//
//<EFBFBD><EFBFBD>ȡʲô<EFBFBD><EFBFBD>֧<EFBFBD><EFBFBD>
FileTree files =fileTree(dir:'./',include:'build.*.gradle')
def buildDir=files[0].path.substring(0,files[0].path.lastIndexOf ('/'))
def branchName=buildDir.substring(buildDir.lastIndexOf ('/')+1)
//
//ָ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
dependencies{
compile fileTree(dir:"${srcDir}/fine-jackson/lib",include:'**/*.jar')
compile fileTree(dir:"${srcDir}/fine-ehcache/lib",include:'**/*.jar')
@ -56,7 +59,7 @@ dependencies{
testCompile 'junit:junit:4.12'
}
//
//ָ<EFBFBD><EFBFBD><EFBFBD>޷<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>·<EFBFBD><EFBFBD>
def dataContent ={def dir ->
copySpec{
from ("${dir}"){
@ -80,6 +83,8 @@ task copyFiles(type:Copy,dependsOn:'compileJava'){
with dataContent.call("${srcDir}/fine-lucene/resources")
with dataContent.call("${srcDir}/fine-cglib/src")
with dataContent.call("${srcDir}/fine-cglib/resources")
with dataContent.call("${srcDir}/fine-jedis/src")
with dataContent.call("${srcDir}/fine-jedis/resources")
into "${classesDir}"
}
}

118
fine-jedis/src/com/fr/third/org/apache/commons/pool2/BaseKeyedPooledObjectFactory.java

@ -0,0 +1,118 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 com.fr.third.org.apache.commons.pool2;
/**
* A base implementation of <code>KeyedPooledObjectFactory</code>.
* <p>
* All operations defined here are essentially no-op's.
* </p>
* This class is immutable, and therefore thread-safe.
*
* @see KeyedPooledObjectFactory
*
* @param <K> The type of keys managed by this factory.
* @param <V> Type of element managed by this factory.
*
* @since 2.0
*/
public abstract class BaseKeyedPooledObjectFactory<K,V> extends BaseObject
implements KeyedPooledObjectFactory<K,V> {
/**
* Create an instance that can be served by the pool.
*
* @param key the key used when constructing the object
* @return an instance that can be served by the pool
*
* @throws Exception if there is a problem creating a new instance,
* this will be propagated to the code requesting an object.
*/
public abstract V create(K key)
throws Exception;
/**
* Wrap the provided instance with an implementation of
* {@link PooledObject}.
*
* @param value the instance to wrap
*
* @return The provided instance, wrapped by a {@link PooledObject}
*/
public abstract PooledObject<V> wrap(V value);
@Override
public PooledObject<V> makeObject(final K key) throws Exception {
return wrap(create(key));
}
/**
* Destroy an instance no longer needed by the pool.
* <p>
* The default implementation is a no-op.
*
* @param key the key used when selecting the instance
* @param p a {@code PooledObject} wrapping the instance to be destroyed
*/
@Override
public void destroyObject(final K key, final PooledObject<V> p)
throws Exception {
// The default implementation is a no-op.
}
/**
* Ensures that the instance is safe to be returned by the pool.
* <p>
* The default implementation always returns {@code true}.
*
* @param key the key used when selecting the object
* @param p a {@code PooledObject} wrapping the instance to be validated
* @return always <code>true</code> in the default implementation
*/
@Override
public boolean validateObject(final K key, final PooledObject<V> p) {
return true;
}
/**
* Reinitialize an instance to be returned by the pool.
* <p>
* The default implementation is a no-op.
*
* @param key the key used when selecting the object
* @param p a {@code PooledObject} wrapping the instance to be activated
*/
@Override
public void activateObject(final K key, final PooledObject<V> p)
throws Exception {
// The default implementation is a no-op.
}
/**
* Uninitialize an instance to be returned to the idle object pool.
* <p>
* The default implementation is a no-op.
*
* @param key the key used when selecting the object
* @param p a {@code PooledObject} wrapping the instance to be passivated
*/
@Override
public void passivateObject(final K key, final PooledObject<V> p)
throws Exception {
// The default implementation is a no-op.
}
}

45
fine-jedis/src/com/fr/third/org/apache/commons/pool2/BaseObject.java

@ -0,0 +1,45 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 com.fr.third.org.apache.commons.pool2;
/**
* A base class for common functionality.
*
* @since 2.4.3
*/
public abstract class BaseObject {
@Override
public String toString() {
final StringBuilder builder = new StringBuilder();
builder.append(getClass().getSimpleName());
builder.append(" [");
toStringAppendFields(builder);
builder.append("]");
return builder.toString();
}
/**
* Used by sub-classes to include the fields defined by the sub-class in the
* {@link #toString()} output.
*
* @param builder Field names and values are appended to this object
*/
protected void toStringAppendFields(final StringBuilder builder) {
// do nothing by default, needed for b/w compatibility.
}
}

125
fine-jedis/src/com/fr/third/org/apache/commons/pool2/BaseObjectPool.java

@ -0,0 +1,125 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 com.fr.third.org.apache.commons.pool2;
/**
* A simple base implementation of {@link ObjectPool}.
* Optional operations are implemented to either do nothing, return a value
* indicating it is unsupported or throw {@link UnsupportedOperationException}.
* <p>
* This class is intended to be thread-safe.
*
* @param <T> Type of element pooled in this pool.
*
* @since 2.0
*/
public abstract class BaseObjectPool<T> extends BaseObject implements ObjectPool<T> {
@Override
public abstract T borrowObject() throws Exception;
@Override
public abstract void returnObject(T obj) throws Exception;
@Override
public abstract void invalidateObject(T obj) throws Exception;
/**
* Not supported in this base implementation.
*
* @return a negative value.
*/
@Override
public int getNumIdle() {
return -1;
}
/**
* Not supported in this base implementation.
*
* @return a negative value.
*/
@Override
public int getNumActive() {
return -1;
}
/**
* Not supported in this base implementation.
*
* @throws UnsupportedOperationException if the pool does not implement this
* method
*/
@Override
public void clear() throws Exception, UnsupportedOperationException {
throw new UnsupportedOperationException();
}
/**
* Not supported in this base implementation. Subclasses should override
* this behavior.
*
* @throws UnsupportedOperationException if the pool does not implement this
* method
*/
@Override
public void addObject() throws Exception, UnsupportedOperationException {
throw new UnsupportedOperationException();
}
/**
* {@inheritDoc}
* <p>
* This affects the behavior of <code>isClosed</code> and
* <code>assertOpen</code>.
*/
@Override
public void close() {
closed = true;
}
/**
* Has this pool instance been closed.
*
* @return <code>true</code> when this pool has been closed.
*/
public final boolean isClosed() {
return closed;
}
/**
* Throws an <code>IllegalStateException</code> when this pool has been
* closed.
*
* @throws IllegalStateException when this pool has been closed.
*
* @see #isClosed()
*/
protected final void assertOpen() throws IllegalStateException {
if (isClosed()) {
throw new IllegalStateException("Pool not open");
}
}
private volatile boolean closed = false;
@Override
protected void toStringAppendFields(final StringBuilder builder) {
builder.append("closed=");
builder.append(closed);
}
}

104
fine-jedis/src/com/fr/third/org/apache/commons/pool2/BasePooledObjectFactory.java

@ -0,0 +1,104 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 com.fr.third.org.apache.commons.pool2;
/**
* A base implementation of <code>PoolableObjectFactory</code>.
* <p>
* All operations defined here are essentially no-op's.
* <p>
* This class is immutable, and therefore thread-safe
*
* @param <T> Type of element managed in this factory.
*
* @see PooledObjectFactory
* @see BaseKeyedPooledObjectFactory
*
* @since 2.0
*/
public abstract class BasePooledObjectFactory<T> extends BaseObject implements PooledObjectFactory<T> {
/**
* Creates an object instance, to be wrapped in a {@link PooledObject}.
* <p>This method <strong>must</strong> support concurrent, multi-threaded
* activation.</p>
*
* @return an instance to be served by the pool
*
* @throws Exception if there is a problem creating a new instance,
* this will be propagated to the code requesting an object.
*/
public abstract T create() throws Exception;
/**
* Wrap the provided instance with an implementation of
* {@link PooledObject}.
*
* @param obj the instance to wrap
*
* @return The provided instance, wrapped by a {@link PooledObject}
*/
public abstract PooledObject<T> wrap(T obj);
@Override
public PooledObject<T> makeObject() throws Exception {
return wrap(create());
}
/**
* No-op.
*
* @param p ignored
*/
@Override
public void destroyObject(final PooledObject<T> p)
throws Exception {
// The default implementation is a no-op.
}
/**
* This implementation always returns {@code true}.
*
* @param p ignored
*
* @return {@code true}
*/
@Override
public boolean validateObject(final PooledObject<T> p) {
return true;
}
/**
* No-op.
*
* @param p ignored
*/
@Override
public void activateObject(final PooledObject<T> p) throws Exception {
// The default implementation is a no-op.
}
/**
* No-op.
*
* @param p ignored
*/
@Override
public void passivateObject(final PooledObject<T> p)
throws Exception {
// The default implementation is a no-op.
}
}

230
fine-jedis/src/com/fr/third/org/apache/commons/pool2/KeyedObjectPool.java

@ -0,0 +1,230 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 com.fr.third.org.apache.commons.pool2;
import java.io.Closeable;
import java.util.NoSuchElementException;
/**
* A "keyed" pooling interface.
* <p>
* A keyed pool maintains a pool of instances for each key value.
* <p>
* Example of use:
* <pre style="border:solid thin; padding: 1ex;"
* > Object obj = <code style="color:#00C">null</code>;
* Object key = <code style="color:#C00">"Key"</code>;
*
* <code style="color:#00C">try</code> {
* obj = pool.borrowObject(key);
* <code style="color:#0C0">//...use the object...</code>
* } <code style="color:#00C">catch</code>(Exception e) {
* <code style="color:#0C0">// invalidate the object</code>
* pool.invalidateObject(key, obj);
* <code style="color:#0C0">// do not return the object to the pool twice</code>
* obj = <code style="color:#00C">null</code>;
* } <code style="color:#00C">finally</code> {
* <code style="color:#0C0">// make sure the object is returned to the pool</code>
* <code style="color:#00C">if</code>(<code style="color:#00C">null</code> != obj) {
* pool.returnObject(key, obj);
* }
* }</pre>
* <p>
* {@link KeyedObjectPool} implementations <i>may</i> choose to store at most
* one instance per key value, or may choose to maintain a pool of instances
* for each key (essentially creating a {@link java.util.Map Map} of
* {@link ObjectPool pools}).
* <p>
* See {@link org.apache.commons.pool2.impl.GenericKeyedObjectPool
* GenericKeyedObjectPool} for an implementation.
*
* @param <K> The type of keys maintained by this pool.
* @param <V> Type of element pooled in this pool.
*
* @see KeyedPooledObjectFactory
* @see ObjectPool
* @see org.apache.commons.pool2.impl.GenericKeyedObjectPool GenericKeyedObjectPool
*
* @since 2.0
*/
public interface KeyedObjectPool<K,V> extends Closeable {
/**
* Obtains an instance from this pool for the specified <code>key</code>.
* <p>
* Instances returned from this method will have been either newly created
* with {@link KeyedPooledObjectFactory#makeObject makeObject} or will be
* a previously idle object and have been activated with
* {@link KeyedPooledObjectFactory#activateObject activateObject} and then
* (optionally) validated with
* {@link KeyedPooledObjectFactory#validateObject validateObject}.
* <p>
* By contract, clients <strong>must</strong> return the borrowed object
* using {@link #returnObject returnObject},
* {@link #invalidateObject invalidateObject}, or a related method as
* defined in an implementation or sub-interface, using a <code>key</code>
* that is {@link Object#equals equivalent} to the one used to borrow the
* instance in the first place.
* <p>
* The behaviour of this method when the pool has been exhausted is not
* strictly specified (although it may be specified by implementations).
*
* @param key the key used to obtain the object
*
* @return an instance from this pool.
*
* @throws IllegalStateException
* after {@link #close close} has been called on this pool
* @throws Exception
* when {@link KeyedPooledObjectFactory#makeObject
* makeObject} throws an exception
* @throws NoSuchElementException
* when the pool is exhausted and cannot or will not return
* another instance
*/
V borrowObject(K key) throws Exception, NoSuchElementException, IllegalStateException;
/**
* Return an instance to the pool. By contract, <code>obj</code>
* <strong>must</strong> have been obtained using
* {@link #borrowObject borrowObject} or a related method as defined in an
* implementation or sub-interface using a <code>key</code> that is
* equivalent to the one used to borrow the instance in the first place.
*
* @param key the key used to obtain the object
* @param obj a {@link #borrowObject borrowed} instance to be returned.
*
* @throws IllegalStateException
* if an attempt is made to return an object to the pool that
* is in any state other than allocated (i.e. borrowed).
* Attempting to return an object more than once or attempting
* to return an object that was never borrowed from the pool
* will trigger this exception.
*
* @throws Exception if an instance cannot be returned to the pool
*/
void returnObject(K key, V obj) throws Exception;
/**
* Invalidates an object from the pool.
* <p>
* By contract, <code>obj</code> <strong>must</strong> have been obtained
* using {@link #borrowObject borrowObject} or a related method as defined
* in an implementation or sub-interface using a <code>key</code> that is
* equivalent to the one used to borrow the <code>Object</code> in the first
* place.
* <p>
* This method should be used when an object that has been borrowed is
* determined (due to an exception or other problem) to be invalid.
*
* @param key the key used to obtain the object
* @param obj a {@link #borrowObject borrowed} instance to be returned.
*
* @throws Exception if the instance cannot be invalidated
*/
void invalidateObject(K key, V obj) throws Exception;
/**
* Create an object using the {@link KeyedPooledObjectFactory factory} or
* other implementation dependent mechanism, passivate it, and then place it
* in the idle object pool. <code>addObject</code> is useful for
* "pre-loading" a pool with idle objects (Optional operation).
*
* @param key the key a new instance should be added to
*
* @throws Exception
* when {@link KeyedPooledObjectFactory#makeObject} fails.
* @throws IllegalStateException
* after {@link #close} has been called on this pool.
* @throws UnsupportedOperationException
* when this pool cannot add new idle objects.
*/
void addObject(K key) throws Exception, IllegalStateException,
UnsupportedOperationException;
/**
* Returns the number of instances corresponding to the given
* <code>key</code> currently idle in this pool. Returns a negative value if
* this information is not available.
*
* @param key the key to query
* @return the number of instances corresponding to the given
* <code>key</code> currently idle in this pool.
*/
int getNumIdle(K key);
/**
* Returns the number of instances currently borrowed from but not yet
* returned to the pool corresponding to the given <code>key</code>.
* Returns a negative value if this information is not available.
*
* @param key the key to query
* @return the number of instances currently borrowed from but not yet
* returned to the pool corresponding to the given <code>key</code>.
= */
int getNumActive(K key);
/**
* Returns the total number of instances currently idle in this pool.
* Returns a negative value if this information is not available.
* @return the total number of instances currently idle in this pool.
= */
int getNumIdle();
/**
* Returns the total number of instances current borrowed from this pool but
* not yet returned. Returns a negative value if this information is not
* available.
* @return the total number of instances current borrowed from this pool but
* not yet returned.
*/
int getNumActive();
/**
* Clears the pool, removing all pooled instances (optional operation).
*
* @throws UnsupportedOperationException when this implementation doesn't
* support the operation
*
* @throws Exception if the pool cannot be cleared
*/
void clear() throws Exception, UnsupportedOperationException;
/**
* Clears the specified pool, removing all pooled instances corresponding to
* the given <code>key</code> (optional operation).
*
* @param key the key to clear
*
* @throws UnsupportedOperationException when this implementation doesn't
* support the operation
*
* @throws Exception if the key cannot be cleared
*/
void clear(K key) throws Exception, UnsupportedOperationException;
/**
* Close this pool, and free any resources associated with it.
* <p>
* Calling {@link #addObject addObject} or
* {@link #borrowObject borrowObject} after invoking this method on a pool
* will cause them to throw an {@link IllegalStateException}.
* <p>
* Implementations should silently fail if not all resources can be freed.
*/
@Override
void close();
}

148
fine-jedis/src/com/fr/third/org/apache/commons/pool2/KeyedPooledObjectFactory.java

@ -0,0 +1,148 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 com.fr.third.org.apache.commons.pool2;
/**
* An interface defining life-cycle methods for
* instances to be served by a {@link KeyedObjectPool}.
* <p>
* By contract, when an {@link KeyedObjectPool}
* delegates to a {@link KeyedPooledObjectFactory},
* <ol>
* <li>
* {@link #makeObject} is called whenever a new instance is needed.
* </li>
* <li>
* {@link #activateObject} is invoked on every instance that has been
* {@link #passivateObject passivated} before it is
* {@link KeyedObjectPool#borrowObject borrowed} from the pool.
* </li>
* <li>
* {@link #validateObject} may be invoked on {@link #activateObject activated}
* instances to make sure they can be
* {@link KeyedObjectPool#borrowObject borrowed} from the pool.
* <code>validateObject</code> may also be used to test an
* instance being {@link KeyedObjectPool#returnObject returned} to the pool
* before it is {@link #passivateObject passivated}. It will only be invoked
* on an activated instance.
* </li>
* <li>
* {@link #passivateObject passivateObject}
* is invoked on every instance when it is returned to the pool.
* </li>
* <li>
* {@link #destroyObject destroyObject}
* is invoked on every instance when it is being "dropped" from the
* pool (whether due to the response from <code>validateObject</code>,
* or for reasons specific to the pool implementation.) There is no
* guarantee that the instance being destroyed will
* be considered active, passive or in a generally consistent state.
* </li>
* </ol>
* {@link KeyedPooledObjectFactory} must be thread-safe. The only promise
* an {@link KeyedObjectPool} makes is that the same instance of an object will
* not be passed to more than one method of a
* <code>KeyedPoolableObjectFactory</code> at a time.
* <p>
* While clients of a {@link KeyedObjectPool} borrow and return instances of
* the underlying value type V, the factory methods act on instances of
* {@link PooledObject PooledObject&lt;V&gt;}. These are the object wrappers that
* pools use to track and maintain state informations about the objects that
* they manage.
*
* @see KeyedObjectPool
* @see BaseKeyedPooledObjectFactory
*
* @param <K> The type of keys managed by this factory.
* @param <V> Type of element managed by this factory.
*
* @since 2.0
*/
public interface KeyedPooledObjectFactory<K,V> {
/**
* Create an instance that can be served by the pool and
* wrap it in a {@link PooledObject} to be managed by the pool.
*
* @param key the key used when constructing the object
*
* @return a {@code PooledObject} wrapping an instance that can
* be served by the pool.
*
* @throws Exception if there is a problem creating a new instance,
* this will be propagated to the code requesting an object.
*/
PooledObject<V> makeObject(K key) throws Exception;
/**
* Destroy an instance no longer needed by the pool.
* <p>
* It is important for implementations of this method to be aware that there
* is no guarantee about what state <code>obj</code> will be in and the
* implementation should be prepared to handle unexpected errors.
* <p>
* Also, an implementation must take in to consideration that instances lost
* to the garbage collector may never be destroyed.
*
* @param key the key used when selecting the instance
* @param p a {@code PooledObject} wrapping the instance to be destroyed
*
* @throws Exception should be avoided as it may be swallowed by
* the pool implementation.
*
* @see #validateObject
* @see KeyedObjectPool#invalidateObject
*/
void destroyObject(K key, PooledObject<V> p) throws Exception;
/**
* Ensures that the instance is safe to be returned by the pool.
*
* @param key the key used when selecting the object
* @param p a {@code PooledObject} wrapping the instance to be validated
*
* @return <code>false</code> if <code>obj</code> is not valid and should
* be dropped from the pool, <code>true</code> otherwise.
*/
boolean validateObject(K key, PooledObject<V> p);
/**
* Reinitialize an instance to be returned by the pool.
*
* @param key the key used when selecting the object
* @param p a {@code PooledObject} wrapping the instance to be activated
*
* @throws Exception if there is a problem activating <code>obj</code>,
* this exception may be swallowed by the pool.
*
* @see #destroyObject
*/
void activateObject(K key, PooledObject<V> p) throws Exception;
/**
* Uninitialize an instance to be returned to the idle object pool.
*
* @param key the key used when selecting the object
* @param p a {@code PooledObject} wrapping the instance to be passivated
*
* @throws Exception if there is a problem passivating <code>obj</code>,
* this exception may be swallowed by the pool.
*
* @see #destroyObject
*/
void passivateObject(K key, PooledObject<V> p) throws Exception;
}

178
fine-jedis/src/com/fr/third/org/apache/commons/pool2/ObjectPool.java

@ -0,0 +1,178 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 com.fr.third.org.apache.commons.pool2;
import java.io.Closeable;
import java.util.NoSuchElementException;
/**
* A pooling simple interface.
* <p>
* Example of use:
* <pre style="border:solid thin; padding: 1ex;"
* > Object obj = <code style="color:#00C">null</code>;
*
* <code style="color:#00C">try</code> {
* obj = pool.borrowObject();
* <code style="color:#00C">try</code> {
* <code style="color:#0C0">//...use the object...</code>
* } <code style="color:#00C">catch</code>(Exception e) {
* <code style="color:#0C0">// invalidate the object</code>
* pool.invalidateObject(obj);
* <code style="color:#0C0">// do not return the object to the pool twice</code>
* obj = <code style="color:#00C">null</code>;
* } <code style="color:#00C">finally</code> {
* <code style="color:#0C0">// make sure the object is returned to the pool</code>
* <code style="color:#00C">if</code>(<code style="color:#00C">null</code> != obj) {
* pool.returnObject(obj);
* }
* }
* } <code style="color:#00C">catch</code>(Exception e) {
* <code style="color:#0C0">// failed to borrow an object</code>
* }</pre>
* <p>
* See {@link BaseObjectPool} for a simple base implementation.
*
* @param <T> Type of element pooled in this pool.
*
* @see PooledObjectFactory
* @see KeyedObjectPool
* @see BaseObjectPool
*
* @since 2.0
*/
public interface ObjectPool<T> extends Closeable {
/**
* Obtains an instance from this pool.
* <p>
* Instances returned from this method will have been either newly created
* with {@link PooledObjectFactory#makeObject} or will be a previously
* idle object and have been activated with
* {@link PooledObjectFactory#activateObject} and then validated with
* {@link PooledObjectFactory#validateObject}.
* <p>
* By contract, clients <strong>must</strong> return the borrowed instance
* using {@link #returnObject}, {@link #invalidateObject}, or a related
* method as defined in an implementation or sub-interface.
* <p>
* The behaviour of this method when the pool has been exhausted
* is not strictly specified (although it may be specified by
* implementations).
*
* @return an instance from this pool.
*
* @throws IllegalStateException
* after {@link #close close} has been called on this pool.
* @throws Exception
* when {@link PooledObjectFactory#makeObject} throws an
* exception.
* @throws NoSuchElementException
* when the pool is exhausted and cannot or will not return
* another instance.
*/
T borrowObject() throws Exception, NoSuchElementException,
IllegalStateException;
/**
* Return an instance to the pool. By contract, <code>obj</code>
* <strong>must</strong> have been obtained using {@link #borrowObject()} or
* a related method as defined in an implementation or sub-interface.
*
* @param obj a {@link #borrowObject borrowed} instance to be returned.
*
* @throws IllegalStateException
* if an attempt is made to return an object to the pool that
* is in any state other than allocated (i.e. borrowed).
* Attempting to return an object more than once or attempting
* to return an object that was never borrowed from the pool
* will trigger this exception.
*
* @throws Exception if an instance cannot be returned to the pool
*/
void returnObject(T obj) throws Exception;
/**
* Invalidates an object from the pool.
* <p>
* By contract, <code>obj</code> <strong>must</strong> have been obtained
* using {@link #borrowObject} or a related method as defined in an
* implementation or sub-interface.
* <p>
* This method should be used when an object that has been borrowed is
* determined (due to an exception or other problem) to be invalid.
*
* @param obj a {@link #borrowObject borrowed} instance to be disposed.
*
* @throws Exception if the instance cannot be invalidated
*/
void invalidateObject(T obj) throws Exception;
/**
* Create an object using the {@link PooledObjectFactory factory} or other
* implementation dependent mechanism, passivate it, and then place it in
* the idle object pool. <code>addObject</code> is useful for "pre-loading"
* a pool with idle objects. (Optional operation).
*
* @throws Exception
* when {@link PooledObjectFactory#makeObject} fails.
* @throws IllegalStateException
* after {@link #close} has been called on this pool.
* @throws UnsupportedOperationException
* when this pool cannot add new idle objects.
*/
void addObject() throws Exception, IllegalStateException,
UnsupportedOperationException;
/**
* Return the number of instances currently idle in this pool. This may be
* considered an approximation of the number of objects that can be
* {@link #borrowObject borrowed} without creating any new instances.
* Returns a negative value if this information is not available.
* @return the number of instances currently idle in this pool.
*/
int getNumIdle();
/**
* Return the number of instances currently borrowed from this pool. Returns
* a negative value if this information is not available.
* @return the number of instances currently borrowed from this pool.
*/
int getNumActive();
/**
* Clears any objects sitting idle in the pool, releasing any associated
* resources (optional operation). Idle objects cleared must be
* {@link PooledObjectFactory#destroyObject(PooledObject)}.
*
* @throws UnsupportedOperationException
* if this implementation does not support the operation
*
* @throws Exception if the pool cannot be cleared
*/
void clear() throws Exception, UnsupportedOperationException;
/**
* Close this pool, and free any resources associated with it.
* <p>
* Calling {@link #addObject} or {@link #borrowObject} after invoking this
* method on a pool will cause them to throw an {@link IllegalStateException}.
* <p>
* Implementations should silently fail if not all resources can be freed.
*/
@Override
void close();
}

1824
fine-jedis/src/com/fr/third/org/apache/commons/pool2/PoolUtils.java

File diff suppressed because it is too large Load Diff

218
fine-jedis/src/com/fr/third/org/apache/commons/pool2/PooledObject.java

@ -0,0 +1,218 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 com.fr.third.org.apache.commons.pool2;
import java.io.PrintWriter;
import java.util.Deque;
/**
* Defines the wrapper that is used to track the additional information, such as
* state, for the pooled objects.
* <p>
* Implementations of this class are required to be thread-safe.
*
* @param <T> the type of object in the pool
*
* @since 2.0
*/
public interface PooledObject<T> extends Comparable<PooledObject<T>> {
/**
* Obtain the underlying object that is wrapped by this instance of
* {@link PooledObject}.
*
* @return The wrapped object
*/
T getObject();
/**
* Obtain the time (using the same basis as
* {@link System#currentTimeMillis()}) that this object was created.
*
* @return The creation time for the wrapped object
*/
long getCreateTime();
/**
* Obtain the time in milliseconds that this object last spent in the
* active state (it may still be active in which case subsequent calls will
* return an increased value).
*
* @return The time in milliseconds last spent in the active state
*/
long getActiveTimeMillis();
/**
* Obtain the time in milliseconds that this object last spend in the
* idle state (it may still be idle in which case subsequent calls will
* return an increased value).
*
* @return The time in milliseconds last spent in the idle state
*/
long getIdleTimeMillis();
/**
* Obtain the time the wrapped object was last borrowed.
*
* @return The time the object was last borrowed
*/
long getLastBorrowTime();
/**
* Obtain the time the wrapped object was last returned.
*
* @return The time the object was last returned
*/
long getLastReturnTime();
/**
* Return an estimate of the last time this object was used. If the class
* of the pooled object implements {@link TrackedUse}, what is returned is
* the maximum of {@link TrackedUse#getLastUsed()} and
* {@link #getLastBorrowTime()}; otherwise this method gives the same
* value as {@link #getLastBorrowTime()}.
*
* @return the last time this object was used
*/
long getLastUsedTime();
/**
* Orders instances based on idle time - i.e. the length of time since the
* instance was returned to the pool. Used by the GKOP idle object evictor.
*<p>
* Note: This class has a natural ordering that is inconsistent with
* equals if distinct objects have the same identity hash code.
* <p>
* {@inheritDoc}
*/
@Override
int compareTo(PooledObject<T> other);
@Override
boolean equals(Object obj);
@Override
int hashCode();
/**
* Provides a String form of the wrapper for debug purposes. The format is
* not fixed and may change at any time.
* <p>
* {@inheritDoc}
*/
@Override
String toString();
/**
* Attempt to place the pooled object in the
* {@link PooledObjectState#EVICTION} state.
*
* @return <code>true</code> if the object was placed in the
* {@link PooledObjectState#EVICTION} state otherwise
* <code>false</code>
*/
boolean startEvictionTest();
/**
* Called to inform the object that the eviction test has ended.
*
* @param idleQueue The queue of idle objects to which the object should be
* returned
*
* @return Currently not used
*/
boolean endEvictionTest(Deque<PooledObject<T>> idleQueue);
/**
* Allocates the object.
*
* @return {@code true} if the original state was {@link PooledObjectState#IDLE IDLE}
*/
boolean allocate();
/**
* Deallocates the object and sets it {@link PooledObjectState#IDLE IDLE}
* if it is currently {@link PooledObjectState#ALLOCATED ALLOCATED}.
*
* @return {@code true} if the state was {@link PooledObjectState#ALLOCATED ALLOCATED}
*/
boolean deallocate();
/**
* Sets the state to {@link PooledObjectState#INVALID INVALID}
*/
void invalidate();
/**
* Is abandoned object tracking being used? If this is true the
* implementation will need to record the stack trace of the last caller to
* borrow this object.
*
* @param logAbandoned The new configuration setting for abandoned
* object tracking
*/
void setLogAbandoned(boolean logAbandoned);
// TODO: uncomment in 3.0 (API compatibility)
// /**
// * Configures the stack trace generation strategy based on whether or not fully
// * detailed stack traces are required. When set to false, abandoned logs may
// * only include caller class information rather than method names, line numbers,
// * and other normal metadata available in a full stack trace.
// *
// * @param requireFullStackTrace the new configuration setting for abandoned object
// * logging
// */
// void setRequireFullStackTrace(boolean requireFullStackTrace);
/**
* Record the current stack trace as the last time the object was used.
*/
void use();
/**
* Prints the stack trace of the code that borrowed this pooled object and
* the stack trace of the last code to use this object (if available) to
* the supplied writer.
*
* @param writer The destination for the debug output
*/
void printStackTrace(PrintWriter writer);
/**
* Returns the state of this object.
* @return state
*/
PooledObjectState getState();
/**
* Marks the pooled object as abandoned.
*/
void markAbandoned();
/**
* Marks the object as returning to the pool.
*/
void markReturning();
// TODO: Uncomment this for version 3 (can't add it to 2.x as it will break
// API compatibility)
///**
// * Get the number of times this object has been borrowed.
// */
//long getBorrowedCount();
}

137
fine-jedis/src/com/fr/third/org/apache/commons/pool2/PooledObjectFactory.java

@ -0,0 +1,137 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 com.fr.third.org.apache.commons.pool2;
/**
* An interface defining life-cycle methods for instances to be served by an
* {@link ObjectPool}.
* <p>
* By contract, when an {@link ObjectPool} delegates to a
* {@link PooledObjectFactory},
* <ol>
* <li>
* {@link #makeObject} is called whenever a new instance is needed.
* </li>
* <li>
* {@link #activateObject} is invoked on every instance that has been
* {@link #passivateObject passivated} before it is
* {@link ObjectPool#borrowObject borrowed} from the pool.
* </li>
* <li>
* {@link #validateObject} may be invoked on {@link #activateObject activated}
* instances to make sure they can be {@link ObjectPool#borrowObject borrowed}
* from the pool. {@link #validateObject} may also be used to
* test an instance being {@link ObjectPool#returnObject returned} to the pool
* before it is {@link #passivateObject passivated}. It will only be invoked
* on an activated instance.
* </li>
* <li>
* {@link #passivateObject} is invoked on every instance when it is returned
* to the pool.
* </li>
* <li>
* {@link #destroyObject} is invoked on every instance when it is being
* "dropped" from the pool (whether due to the response from
* {@link #validateObject}, or for reasons specific to the pool
* implementation.) There is no guarantee that the instance being destroyed
* will be considered active, passive or in a generally consistent state.
* </li>
* </ol>
* {@link PooledObjectFactory} must be thread-safe. The only promise
* an {@link ObjectPool} makes is that the same instance of an object will not
* be passed to more than one method of a <code>PoolableObjectFactory</code>
* at a time.
* <p>
* While clients of a {@link KeyedObjectPool} borrow and return instances of
* the underlying value type {@code V}, the factory methods act on instances of
* {@link PooledObject PooledObject&lt;V&gt;}. These are the object wrappers that
* pools use to track and maintain state information about the objects that
* they manage.
*
* @param <T> Type of element managed in this factory.
*
* @see ObjectPool
*
* @since 2.0
*/
public interface PooledObjectFactory<T> {
/**
* Create an instance that can be served by the pool and wrap it in a
* {@link PooledObject} to be managed by the pool.
*
* @return a {@code PooledObject} wrapping an instance that can be served by the pool
*
* @throws Exception if there is a problem creating a new instance,
* this will be propagated to the code requesting an object.
*/
PooledObject<T> makeObject() throws Exception;
/**
* Destroys an instance no longer needed by the pool.
* <p>
* It is important for implementations of this method to be aware that there
* is no guarantee about what state <code>obj</code> will be in and the
* implementation should be prepared to handle unexpected errors.
* <p>
* Also, an implementation must take in to consideration that instances lost
* to the garbage collector may never be destroyed.
* </p>
*
* @param p a {@code PooledObject} wrapping the instance to be destroyed
*
* @throws Exception should be avoided as it may be swallowed by
* the pool implementation.
*
* @see #validateObject
* @see ObjectPool#invalidateObject
*/
void destroyObject(PooledObject<T> p) throws Exception;
/**
* Ensures that the instance is safe to be returned by the pool.
*
* @param p a {@code PooledObject} wrapping the instance to be validated
*
* @return <code>false</code> if <code>obj</code> is not valid and should
* be dropped from the pool, <code>true</code> otherwise.
*/
boolean validateObject(PooledObject<T> p);
/**
* Reinitialize an instance to be returned by the pool.
*
* @param p a {@code PooledObject} wrapping the instance to be activated
*
* @throws Exception if there is a problem activating <code>obj</code>,
* this exception may be swallowed by the pool.
*
* @see #destroyObject
*/
void activateObject(PooledObject<T> p) throws Exception;
/**
* Uninitialize an instance to be returned to the idle object pool.
*
* @param p a {@code PooledObject} wrapping the instance to be passivated
*
* @throws Exception if there is a problem passivating <code>obj</code>,
* this exception may be swallowed by the pool.
*
* @see #destroyObject
*/
void passivateObject(PooledObject<T> p) throws Exception;
}

86
fine-jedis/src/com/fr/third/org/apache/commons/pool2/PooledObjectState.java

@ -0,0 +1,86 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 com.fr.third.org.apache.commons.pool2;
/**
* Provides the possible states that a {@link PooledObject} may be in.
*
* @since 2.0
*/
public enum PooledObjectState {
/**
* In the queue, not in use.
*/
IDLE,
/**
* In use.
*/
ALLOCATED,
/**
* In the queue, currently being tested for possible eviction.
*/
EVICTION,
/**
* Not in the queue, currently being tested for possible eviction. An
* attempt to borrow the object was made while being tested which removed it
* from the queue. It should be returned to the head of the queue once
* eviction testing completes.
* TODO: Consider allocating object and ignoring the result of the eviction
* test.
*/
EVICTION_RETURN_TO_HEAD,
/**
* In the queue, currently being validated.
*/
VALIDATION,
/**
* Not in queue, currently being validated. The object was borrowed while
* being validated and since testOnBorrow was configured, it was removed
* from the queue and pre-allocated. It should be allocated once validation
* completes.
*/
VALIDATION_PREALLOCATED,
/**
* Not in queue, currently being validated. An attempt to borrow the object
* was made while previously being tested for eviction which removed it from
* the queue. It should be returned to the head of the queue once validation
* completes.
*/
VALIDATION_RETURN_TO_HEAD,
/**
* Failed maintenance (e.g. eviction test or validation) and will be / has
* been destroyed
*/
INVALID,
/**
* Deemed abandoned, to be invalidated.
*/
ABANDONED,
/**
* Returning to the pool.
*/
RETURNING
}

36
fine-jedis/src/com/fr/third/org/apache/commons/pool2/SwallowedExceptionListener.java

@ -0,0 +1,36 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 com.fr.third.org.apache.commons.pool2;
/**
* Pools that unavoidably swallow exceptions may be configured with an instance
* of this listener so the user may receive notification of when this happens.
* The listener should not throw an exception when called but pools calling
* listeners should protect themselves against exceptions anyway.
*
* @since 2.0
*/
public interface SwallowedExceptionListener {
/**
* This method is called every time the implementation unavoidably swallows
* an exception.
*
* @param e The exception that was swallowed
*/
void onSwallowException(Exception e);
}

36
fine-jedis/src/com/fr/third/org/apache/commons/pool2/TrackedUse.java

@ -0,0 +1,36 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 com.fr.third.org.apache.commons.pool2;
/**
* This interface allows pooled objects to make information available about when
* and how they were used available to the object pool. The object pool may, but
* is not required, to use this information to make more informed decisions when
* determining the state of a pooled object - for instance whether or not the
* object has been abandoned.
*
* @since 2.0
*/
public interface TrackedUse {
/**
* Get the last time this object was used in ms.
*
* @return long time in ms
*/
long getLastUsed();
}

39
fine-jedis/src/com/fr/third/org/apache/commons/pool2/UsageTracking.java

@ -0,0 +1,39 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 com.fr.third.org.apache.commons.pool2;
/**
* This interface may be implemented by an object pool to enable clients
* (primarily those clients that wrap pools to provide pools with extended
* features) to provide additional information to the pool relating to object
* using allowing more informed decisions and reporting to be made regarding
* abandoned objects.
*
* @param <T> The type of object provided by the pool.
*
* @since 2.0
*/
public interface UsageTracking<T> {
/**
* This method is called every time a pooled object is used to enable the pool to
* better track borrowed objects.
*
* @param pooledObject The object that is being used
*/
void use(T pooledObject);
}

289
fine-jedis/src/com/fr/third/org/apache/commons/pool2/impl/AbandonedConfig.java

@ -0,0 +1,289 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 com.fr.third.org.apache.commons.pool2.impl;
import com.fr.third.org.apache.commons.pool2.TrackedUse;
import com.fr.third.org.apache.commons.pool2.UsageTracking;
import java.io.PrintWriter;
/**
* Configuration settings for abandoned object removal.
*
* @since 2.0
*/
public class AbandonedConfig {
/**
* Whether or not borrowObject performs abandoned object removal.
*/
private boolean removeAbandonedOnBorrow = false;
/**
* <p>Flag to remove abandoned objects if they exceed the
* removeAbandonedTimeout when borrowObject is invoked.</p>
*
* <p>The default value is false.</p>
*
* <p>If set to true, abandoned objects are removed by borrowObject if
* there are fewer than 2 idle objects available in the pool and
* <code>getNumActive() &gt; getMaxTotal() - 3</code></p>
*
* @return true if abandoned objects are to be removed by borrowObject
*/
public boolean getRemoveAbandonedOnBorrow() {
return this.removeAbandonedOnBorrow;
}
/**
* <p>Flag to remove abandoned objects if they exceed the
* removeAbandonedTimeout when borrowObject is invoked.</p>
*
* @param removeAbandonedOnBorrow true means abandoned objects will be
* removed by borrowObject
* @see #getRemoveAbandonedOnBorrow()
*/
public void setRemoveAbandonedOnBorrow(final boolean removeAbandonedOnBorrow) {
this.removeAbandonedOnBorrow = removeAbandonedOnBorrow;
}
/**
* Whether or not pool maintenance (evictor) performs abandoned object
* removal.
*/
private boolean removeAbandonedOnMaintenance = false;
/**
* <p>Flag to remove abandoned objects if they exceed the
* removeAbandonedTimeout when pool maintenance (the "evictor")
* runs.</p>
*
* <p>The default value is false.</p>
*
* <p>If set to true, abandoned objects are removed by the pool
* maintenance thread when it runs. This setting has no effect
* unless maintenance is enabled by setting
*{@link GenericObjectPool#getTimeBetweenEvictionRunsMillis() timeBetweenEvictionRunsMillis}
* to a positive number.</p>
*
* @return true if abandoned objects are to be removed by the evictor
*/
public boolean getRemoveAbandonedOnMaintenance() {
return this.removeAbandonedOnMaintenance;
}
/**
* <p>Flag to remove abandoned objects if they exceed the
* removeAbandonedTimeout when pool maintenance runs.</p>
*
* @param removeAbandonedOnMaintenance true means abandoned objects will be
* removed by pool maintenance
* @see #getRemoveAbandonedOnMaintenance
*/
public void setRemoveAbandonedOnMaintenance(final boolean removeAbandonedOnMaintenance) {
this.removeAbandonedOnMaintenance = removeAbandonedOnMaintenance;
}
/**
* Timeout in seconds before an abandoned object can be removed.
*/
private int removeAbandonedTimeout = 300;
/**
* <p>Timeout in seconds before an abandoned object can be removed.</p>
*
* <p>The time of most recent use of an object is the maximum (latest) of
* {@link TrackedUse#getLastUsed()} (if this class of the object implements
* TrackedUse) and the time when the object was borrowed from the pool.</p>
*
* <p>The default value is 300 seconds.</p>
*
* @return the abandoned object timeout in seconds
*/
public int getRemoveAbandonedTimeout() {
return this.removeAbandonedTimeout;
}
/**
* <p>Sets the timeout in seconds before an abandoned object can be
* removed</p>
*
* <p>Setting this property has no effect if
* {@link #getRemoveAbandonedOnBorrow() removeAbandonedOnBorrow} and
* {@link #getRemoveAbandonedOnMaintenance() removeAbandonedOnMaintenance}
* are both false.</p>
*
* @param removeAbandonedTimeout new abandoned timeout in seconds
* @see #getRemoveAbandonedTimeout()
*/
public void setRemoveAbandonedTimeout(final int removeAbandonedTimeout) {
this.removeAbandonedTimeout = removeAbandonedTimeout;
}
/**
* Determines whether or not to log stack traces for application code
* which abandoned an object.
*/
private boolean logAbandoned = false;
/**
* Flag to log stack traces for application code which abandoned
* an object.
*
* Defaults to false.
* Logging of abandoned objects adds overhead for every object created
* because a stack trace has to be generated.
*
* @return boolean true if stack trace logging is turned on for abandoned
* objects
*
*/
public boolean getLogAbandoned() {
return this.logAbandoned;
}
/**
* Sets the flag to log stack traces for application code which abandoned
* an object.
*
* @param logAbandoned true turns on abandoned stack trace logging
* @see #getLogAbandoned()
*
*/
public void setLogAbandoned(final boolean logAbandoned) {
this.logAbandoned = logAbandoned;
}
/**
* Determines whether or not to log full stack traces when logAbandoned is true.
* If disabled, then a faster method for logging stack traces with only class data
* may be used if possible.
*
* @since 2.5
*/
private boolean requireFullStackTrace = true;
/**
* Indicates if full stack traces are required when {@link #getLogAbandoned() logAbandoned}
* is true. Defaults to true. Logging of abandoned objects requiring a full stack trace will
* generate an entire stack trace to generate for every object created. If this is disabled,
* a faster but less informative stack walking mechanism may be used if available.
*
* @return true if full stack traces are required for logging abandoned connections, or false
* if abbreviated stack traces are acceptable
* @see CallStack
* @since 2.5
*/
public boolean getRequireFullStackTrace() {
return requireFullStackTrace;
}
/**
* Sets the flag to require full stack traces for logging abandoned connections when enabled.
*
* @param requireFullStackTrace indicates whether or not full stack traces are required in
* abandoned connection logs
* @see CallStack
* @see #getRequireFullStackTrace()
* @since 2.5
*/
public void setRequireFullStackTrace(boolean requireFullStackTrace) {
this.requireFullStackTrace = requireFullStackTrace;
}
/**
* PrintWriter to use to log information on abandoned objects.
* Use of default system encoding is deliberate.
*/
private PrintWriter logWriter = new PrintWriter(System.out);
/**
* Returns the log writer being used by this configuration to log
* information on abandoned objects. If not set, a PrintWriter based on
* System.out with the system default encoding is used.
*
* @return log writer in use
*/
public PrintWriter getLogWriter() {
return logWriter;
}
/**
* Sets the log writer to be used by this configuration to log
* information on abandoned objects.
*
* @param logWriter The new log writer
*/
public void setLogWriter(final PrintWriter logWriter) {
this.logWriter = logWriter;
}
/**
* If the pool implements {@link UsageTracking}, should the pool record a
* stack trace every time a method is called on a pooled object and retain
* the most recent stack trace to aid debugging of abandoned objects?
*/
private boolean useUsageTracking = false;
/**
* If the pool implements {@link UsageTracking}, should the pool record a
* stack trace every time a method is called on a pooled object and retain
* the most recent stack trace to aid debugging of abandoned objects?
*
* @return <code>true</code> if usage tracking is enabled
*/
public boolean getUseUsageTracking() {
return useUsageTracking;
}
/**
* If the pool implements {@link UsageTracking}, configure whether the pool
* should record a stack trace every time a method is called on a pooled
* object and retain the most recent stack trace to aid debugging of
* abandoned objects.
*
* @param useUsageTracking A value of <code>true</code> will enable
* the recording of a stack trace on every use
* of a pooled object
*/
public void setUseUsageTracking(final boolean useUsageTracking) {
this.useUsageTracking = useUsageTracking;
}
/**
* @since 2.4.3
*/
@Override
public String toString() {
final StringBuilder builder = new StringBuilder();
builder.append("AbandonedConfig [removeAbandonedOnBorrow=");
builder.append(removeAbandonedOnBorrow);
builder.append(", removeAbandonedOnMaintenance=");
builder.append(removeAbandonedOnMaintenance);
builder.append(", removeAbandonedTimeout=");
builder.append(removeAbandonedTimeout);
builder.append(", logAbandoned=");
builder.append(logAbandoned);
builder.append(", logWriter=");
builder.append(logWriter);
builder.append(", useUsageTracking=");
builder.append(useUsageTracking);
builder.append("]");
return builder.toString();
}
}

1339
fine-jedis/src/com/fr/third/org/apache/commons/pool2/impl/BaseGenericObjectPool.java

File diff suppressed because it is too large Load Diff

718
fine-jedis/src/com/fr/third/org/apache/commons/pool2/impl/BaseObjectPoolConfig.java

@ -0,0 +1,718 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 com.fr.third.org.apache.commons.pool2.impl;
import com.fr.third.org.apache.commons.pool2.BaseObject;
/**
* Provides the implementation for the common attributes shared by the
* sub-classes. New instances of this class will be created using the defaults
* defined by the public constants.
* <p>
* This class is not thread-safe.
*
* @since 2.0
*/
public abstract class BaseObjectPoolConfig extends BaseObject implements Cloneable {
/**
* The default value for the {@code lifo} configuration attribute.
* @see GenericObjectPool#getLifo()
* @see GenericKeyedObjectPool#getLifo()
*/
public static final boolean DEFAULT_LIFO = true;
/**
* The default value for the {@code fairness} configuration attribute.
* @see GenericObjectPool#getFairness()
* @see GenericKeyedObjectPool#getFairness()
*/
public static final boolean DEFAULT_FAIRNESS = false;
/**
* The default value for the {@code maxWait} configuration attribute.
* @see GenericObjectPool#getMaxWaitMillis()
* @see GenericKeyedObjectPool#getMaxWaitMillis()
*/
public static final long DEFAULT_MAX_WAIT_MILLIS = -1L;
/**
* The default value for the {@code minEvictableIdleTimeMillis}
* configuration attribute.
* @see GenericObjectPool#getMinEvictableIdleTimeMillis()
* @see GenericKeyedObjectPool#getMinEvictableIdleTimeMillis()
*/
public static final long DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS =
1000L * 60L * 30L;
/**
* The default value for the {@code softMinEvictableIdleTimeMillis}
* configuration attribute.
* @see GenericObjectPool#getSoftMinEvictableIdleTimeMillis()
* @see GenericKeyedObjectPool#getSoftMinEvictableIdleTimeMillis()
*/
public static final long DEFAULT_SOFT_MIN_EVICTABLE_IDLE_TIME_MILLIS = -1;
/**
* The default value for {@code evictorShutdownTimeoutMillis} configuration
* attribute.
* @see GenericObjectPool#getEvictorShutdownTimeoutMillis()
* @see GenericKeyedObjectPool#getEvictorShutdownTimeoutMillis()
*/
public static final long DEFAULT_EVICTOR_SHUTDOWN_TIMEOUT_MILLIS =
10L * 1000L;
/**
* The default value for the {@code numTestsPerEvictionRun} configuration
* attribute.
* @see GenericObjectPool#getNumTestsPerEvictionRun()
* @see GenericKeyedObjectPool#getNumTestsPerEvictionRun()
*/
public static final int DEFAULT_NUM_TESTS_PER_EVICTION_RUN = 3;
/**
* The default value for the {@code testOnCreate} configuration attribute.
* @see GenericObjectPool#getTestOnCreate()
* @see GenericKeyedObjectPool#getTestOnCreate()
*
* @since 2.2
*/
public static final boolean DEFAULT_TEST_ON_CREATE = false;
/**
* The default value for the {@code testOnBorrow} configuration attribute.
* @see GenericObjectPool#getTestOnBorrow()
* @see GenericKeyedObjectPool#getTestOnBorrow()
*/
public static final boolean DEFAULT_TEST_ON_BORROW = false;
/**
* The default value for the {@code testOnReturn} configuration attribute.
* @see GenericObjectPool#getTestOnReturn()
* @see GenericKeyedObjectPool#getTestOnReturn()
*/
public static final boolean DEFAULT_TEST_ON_RETURN = false;
/**
* The default value for the {@code testWhileIdle} configuration attribute.
* @see GenericObjectPool#getTestWhileIdle()
* @see GenericKeyedObjectPool#getTestWhileIdle()
*/
public static final boolean DEFAULT_TEST_WHILE_IDLE = false;
/**
* The default value for the {@code timeBetweenEvictionRunsMillis}
* configuration attribute.
* @see GenericObjectPool#getTimeBetweenEvictionRunsMillis()
* @see GenericKeyedObjectPool#getTimeBetweenEvictionRunsMillis()
*/
public static final long DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS = -1L;
/**
* The default value for the {@code blockWhenExhausted} configuration
* attribute.
* @see GenericObjectPool#getBlockWhenExhausted()
* @see GenericKeyedObjectPool#getBlockWhenExhausted()
*/
public static final boolean DEFAULT_BLOCK_WHEN_EXHAUSTED = true;
/**
* The default value for enabling JMX for pools created with a configuration
* instance.
*/
public static final boolean DEFAULT_JMX_ENABLE = true;
/**
* The default value for the prefix used to name JMX enabled pools created
* with a configuration instance.
* @see GenericObjectPool#getJmxName()
* @see GenericKeyedObjectPool#getJmxName()
*/
public static final String DEFAULT_JMX_NAME_PREFIX = "pool";
/**
* The default value for the base name to use to name JMX enabled pools
* created with a configuration instance. The default is <code>null</code>
* which means the pool will provide the base name to use.
* @see GenericObjectPool#getJmxName()
* @see GenericKeyedObjectPool#getJmxName()
*/
public static final String DEFAULT_JMX_NAME_BASE = null;
/**
* The default value for the {@code evictionPolicyClassName} configuration
* attribute.
* @see GenericObjectPool#getEvictionPolicyClassName()
* @see GenericKeyedObjectPool#getEvictionPolicyClassName()
*/
public static final String DEFAULT_EVICTION_POLICY_CLASS_NAME =
"org.apache.commons.pool2.impl.DefaultEvictionPolicy";
private boolean lifo = DEFAULT_LIFO;
private boolean fairness = DEFAULT_FAIRNESS;
private long maxWaitMillis = DEFAULT_MAX_WAIT_MILLIS;
private long minEvictableIdleTimeMillis =
DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS;
private long evictorShutdownTimeoutMillis =
DEFAULT_EVICTOR_SHUTDOWN_TIMEOUT_MILLIS;
private long softMinEvictableIdleTimeMillis =
DEFAULT_SOFT_MIN_EVICTABLE_IDLE_TIME_MILLIS;
private int numTestsPerEvictionRun =
DEFAULT_NUM_TESTS_PER_EVICTION_RUN;
private String evictionPolicyClassName = DEFAULT_EVICTION_POLICY_CLASS_NAME;
private boolean testOnCreate = DEFAULT_TEST_ON_CREATE;
private boolean testOnBorrow = DEFAULT_TEST_ON_BORROW;
private boolean testOnReturn = DEFAULT_TEST_ON_RETURN;
private boolean testWhileIdle = DEFAULT_TEST_WHILE_IDLE;
private long timeBetweenEvictionRunsMillis =
DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS;
private boolean blockWhenExhausted = DEFAULT_BLOCK_WHEN_EXHAUSTED;
private boolean jmxEnabled = DEFAULT_JMX_ENABLE;
// TODO Consider changing this to a single property for 3.x
private String jmxNamePrefix = DEFAULT_JMX_NAME_PREFIX;
private String jmxNameBase = DEFAULT_JMX_NAME_BASE;
/**
* Get the value for the {@code lifo} configuration attribute for pools
* created with this configuration instance.
*
* @return The current setting of {@code lifo} for this configuration
* instance
*
* @see GenericObjectPool#getLifo()
* @see GenericKeyedObjectPool#getLifo()
*/
public boolean getLifo() {
return lifo;
}
/**
* Get the value for the {@code fairness} configuration attribute for pools
* created with this configuration instance.
*
* @return The current setting of {@code fairness} for this configuration
* instance
*
* @see GenericObjectPool#getFairness()
* @see GenericKeyedObjectPool#getFairness()
*/
public boolean getFairness() {
return fairness;
}
/**
* Set the value for the {@code lifo} configuration attribute for pools
* created with this configuration instance.
*
* @param lifo The new setting of {@code lifo}
* for this configuration instance
*
* @see GenericObjectPool#getLifo()
* @see GenericKeyedObjectPool#getLifo()
*/
public void setLifo(final boolean lifo) {
this.lifo = lifo;
}
/**
* Set the value for the {@code fairness} configuration attribute for pools
* created with this configuration instance.
*
* @param fairness The new setting of {@code fairness}
* for this configuration instance
*
* @see GenericObjectPool#getFairness()
* @see GenericKeyedObjectPool#getFairness()
*/
public void setFairness(final boolean fairness) {
this.fairness = fairness;
}
/**
* Get the value for the {@code maxWait} configuration attribute for pools
* created with this configuration instance.
*
* @return The current setting of {@code maxWait} for this
* configuration instance
*
* @see GenericObjectPool#getMaxWaitMillis()
* @see GenericKeyedObjectPool#getMaxWaitMillis()
*/
public long getMaxWaitMillis() {
return maxWaitMillis;
}
/**
* Set the value for the {@code maxWait} configuration attribute for pools
* created with this configuration instance.
*
* @param maxWaitMillis The new setting of {@code maxWaitMillis}
* for this configuration instance
*
* @see GenericObjectPool#getMaxWaitMillis()
* @see GenericKeyedObjectPool#getMaxWaitMillis()
*/
public void setMaxWaitMillis(final long maxWaitMillis) {
this.maxWaitMillis = maxWaitMillis;
}
/**
* Get the value for the {@code minEvictableIdleTimeMillis} configuration
* attribute for pools created with this configuration instance.
*
* @return The current setting of {@code minEvictableIdleTimeMillis} for
* this configuration instance
*
* @see GenericObjectPool#getMinEvictableIdleTimeMillis()
* @see GenericKeyedObjectPool#getMinEvictableIdleTimeMillis()
*/
public long getMinEvictableIdleTimeMillis() {
return minEvictableIdleTimeMillis;
}
/**
* Set the value for the {@code minEvictableIdleTimeMillis} configuration
* attribute for pools created with this configuration instance.
*
* @param minEvictableIdleTimeMillis The new setting of
* {@code minEvictableIdleTimeMillis} for this configuration instance
*
* @see GenericObjectPool#getMinEvictableIdleTimeMillis()
* @see GenericKeyedObjectPool#getMinEvictableIdleTimeMillis()
*/
public void setMinEvictableIdleTimeMillis(final long minEvictableIdleTimeMillis) {
this.minEvictableIdleTimeMillis = minEvictableIdleTimeMillis;
}
/**
* Get the value for the {@code softMinEvictableIdleTimeMillis}
* configuration attribute for pools created with this configuration
* instance.
*
* @return The current setting of {@code softMinEvictableIdleTimeMillis}
* for this configuration instance
*
* @see GenericObjectPool#getSoftMinEvictableIdleTimeMillis()
* @see GenericKeyedObjectPool#getSoftMinEvictableIdleTimeMillis()
*/
public long getSoftMinEvictableIdleTimeMillis() {
return softMinEvictableIdleTimeMillis;
}
/**
* Set the value for the {@code softMinEvictableIdleTimeMillis}
* configuration attribute for pools created with this configuration
* instance.
*
* @param softMinEvictableIdleTimeMillis The new setting of
* {@code softMinEvictableIdleTimeMillis} for this configuration
* instance
*
* @see GenericObjectPool#getSoftMinEvictableIdleTimeMillis()
* @see GenericKeyedObjectPool#getSoftMinEvictableIdleTimeMillis()
*/
public void setSoftMinEvictableIdleTimeMillis(
final long softMinEvictableIdleTimeMillis) {
this.softMinEvictableIdleTimeMillis = softMinEvictableIdleTimeMillis;
}
/**
* Get the value for the {@code numTestsPerEvictionRun} configuration
* attribute for pools created with this configuration instance.
*
* @return The current setting of {@code numTestsPerEvictionRun} for this
* configuration instance
*
* @see GenericObjectPool#getNumTestsPerEvictionRun()
* @see GenericKeyedObjectPool#getNumTestsPerEvictionRun()
*/
public int getNumTestsPerEvictionRun() {
return numTestsPerEvictionRun;
}
/**
* Set the value for the {@code numTestsPerEvictionRun} configuration
* attribute for pools created with this configuration instance.
*
* @param numTestsPerEvictionRun The new setting of
* {@code numTestsPerEvictionRun} for this configuration instance
*
* @see GenericObjectPool#getNumTestsPerEvictionRun()
* @see GenericKeyedObjectPool#getNumTestsPerEvictionRun()
*/
public void setNumTestsPerEvictionRun(final int numTestsPerEvictionRun) {
this.numTestsPerEvictionRun = numTestsPerEvictionRun;
}
/**
* Get the value for the {@code evictorShutdownTimeoutMillis} configuration
* attribute for pools created with this configuration instance.
*
* @return The current setting of {@code evictorShutdownTimeoutMillis} for
* this configuration instance
*
* @see GenericObjectPool#getEvictorShutdownTimeoutMillis()
* @see GenericKeyedObjectPool#getEvictorShutdownTimeoutMillis()
*/
public long getEvictorShutdownTimeoutMillis() {
return evictorShutdownTimeoutMillis;
}
/**
* Set the value for the {@code evictorShutdownTimeoutMillis} configuration
* attribute for pools created with this configuration instance.
*
* @param evictorShutdownTimeoutMillis The new setting of
* {@code evictorShutdownTimeoutMillis} for this configuration
* instance
*
* @see GenericObjectPool#getEvictorShutdownTimeoutMillis()
* @see GenericKeyedObjectPool#getEvictorShutdownTimeoutMillis()
*/
public void setEvictorShutdownTimeoutMillis(
final long evictorShutdownTimeoutMillis) {
this.evictorShutdownTimeoutMillis = evictorShutdownTimeoutMillis;
}
/**
* Get the value for the {@code testOnCreate} configuration attribute for
* pools created with this configuration instance.
*
* @return The current setting of {@code testOnCreate} for this
* configuration instance
*
* @see GenericObjectPool#getTestOnCreate()
* @see GenericKeyedObjectPool#getTestOnCreate()
*
* @since 2.2
*/
public boolean getTestOnCreate() {
return testOnCreate;
}
/**
* Set the value for the {@code testOnCreate} configuration attribute for
* pools created with this configuration instance.
*
* @param testOnCreate The new setting of {@code testOnCreate}
* for this configuration instance
*
* @see GenericObjectPool#getTestOnCreate()
* @see GenericKeyedObjectPool#getTestOnCreate()
*
* @since 2.2
*/
public void setTestOnCreate(final boolean testOnCreate) {
this.testOnCreate = testOnCreate;
}
/**
* Get the value for the {@code testOnBorrow} configuration attribute for
* pools created with this configuration instance.
*
* @return The current setting of {@code testOnBorrow} for this
* configuration instance
*
* @see GenericObjectPool#getTestOnBorrow()
* @see GenericKeyedObjectPool#getTestOnBorrow()
*/
public boolean getTestOnBorrow() {
return testOnBorrow;
}
/**
* Set the value for the {@code testOnBorrow} configuration attribute for
* pools created with this configuration instance.
*
* @param testOnBorrow The new setting of {@code testOnBorrow}
* for this configuration instance
*
* @see GenericObjectPool#getTestOnBorrow()
* @see GenericKeyedObjectPool#getTestOnBorrow()
*/
public void setTestOnBorrow(final boolean testOnBorrow) {
this.testOnBorrow = testOnBorrow;
}
/**
* Get the value for the {@code testOnReturn} configuration attribute for
* pools created with this configuration instance.
*
* @return The current setting of {@code testOnReturn} for this
* configuration instance
*
* @see GenericObjectPool#getTestOnReturn()
* @see GenericKeyedObjectPool#getTestOnReturn()
*/
public boolean getTestOnReturn() {
return testOnReturn;
}
/**
* Set the value for the {@code testOnReturn} configuration attribute for
* pools created with this configuration instance.
*
* @param testOnReturn The new setting of {@code testOnReturn}
* for this configuration instance
*
* @see GenericObjectPool#getTestOnReturn()
* @see GenericKeyedObjectPool#getTestOnReturn()
*/
public void setTestOnReturn(final boolean testOnReturn) {
this.testOnReturn = testOnReturn;
}
/**
* Get the value for the {@code testWhileIdle} configuration attribute for
* pools created with this configuration instance.
*
* @return The current setting of {@code testWhileIdle} for this
* configuration instance
*
* @see GenericObjectPool#getTestWhileIdle()
* @see GenericKeyedObjectPool#getTestWhileIdle()
*/
public boolean getTestWhileIdle() {
return testWhileIdle;
}
/**
* Set the value for the {@code testWhileIdle} configuration attribute for
* pools created with this configuration instance.
*
* @param testWhileIdle The new setting of {@code testWhileIdle}
* for this configuration instance
*
* @see GenericObjectPool#getTestWhileIdle()
* @see GenericKeyedObjectPool#getTestWhileIdle()
*/
public void setTestWhileIdle(final boolean testWhileIdle) {
this.testWhileIdle = testWhileIdle;
}
/**
* Get the value for the {@code timeBetweenEvictionRunsMillis} configuration
* attribute for pools created with this configuration instance.
*
* @return The current setting of {@code timeBetweenEvictionRunsMillis} for
* this configuration instance
*
* @see GenericObjectPool#getTimeBetweenEvictionRunsMillis()
* @see GenericKeyedObjectPool#getTimeBetweenEvictionRunsMillis()
*/
public long getTimeBetweenEvictionRunsMillis() {
return timeBetweenEvictionRunsMillis;
}
/**
* Set the value for the {@code timeBetweenEvictionRunsMillis} configuration
* attribute for pools created with this configuration instance.
*
* @param timeBetweenEvictionRunsMillis The new setting of
* {@code timeBetweenEvictionRunsMillis} for this configuration
* instance
*
* @see GenericObjectPool#getTimeBetweenEvictionRunsMillis()
* @see GenericKeyedObjectPool#getTimeBetweenEvictionRunsMillis()
*/
public void setTimeBetweenEvictionRunsMillis(
final long timeBetweenEvictionRunsMillis) {
this.timeBetweenEvictionRunsMillis = timeBetweenEvictionRunsMillis;
}
/**
* Get the value for the {@code evictionPolicyClassName} configuration
* attribute for pools created with this configuration instance.
*
* @return The current setting of {@code evictionPolicyClassName} for this
* configuration instance
*
* @see GenericObjectPool#getEvictionPolicyClassName()
* @see GenericKeyedObjectPool#getEvictionPolicyClassName()
*/
public String getEvictionPolicyClassName() {
return evictionPolicyClassName;
}
/**
* Set the value for the {@code evictionPolicyClassName} configuration
* attribute for pools created with this configuration instance.
*
* @param evictionPolicyClassName The new setting of
* {@code evictionPolicyClassName} for this configuration instance
*
* @see GenericObjectPool#getEvictionPolicyClassName()
* @see GenericKeyedObjectPool#getEvictionPolicyClassName()
*/
public void setEvictionPolicyClassName(final String evictionPolicyClassName) {
this.evictionPolicyClassName = evictionPolicyClassName;
}
/**
* Get the value for the {@code blockWhenExhausted} configuration attribute
* for pools created with this configuration instance.
*
* @return The current setting of {@code blockWhenExhausted} for this
* configuration instance
*
* @see GenericObjectPool#getBlockWhenExhausted()
* @see GenericKeyedObjectPool#getBlockWhenExhausted()
*/
public boolean getBlockWhenExhausted() {
return blockWhenExhausted;
}
/**
* Set the value for the {@code blockWhenExhausted} configuration attribute
* for pools created with this configuration instance.
*
* @param blockWhenExhausted The new setting of {@code blockWhenExhausted}
* for this configuration instance
*
* @see GenericObjectPool#getBlockWhenExhausted()
* @see GenericKeyedObjectPool#getBlockWhenExhausted()
*/
public void setBlockWhenExhausted(final boolean blockWhenExhausted) {
this.blockWhenExhausted = blockWhenExhausted;
}
/**
* Gets the value of the flag that determines if JMX will be enabled for
* pools created with this configuration instance.
*
* @return The current setting of {@code jmxEnabled} for this configuration
* instance
*/
public boolean getJmxEnabled() {
return jmxEnabled;
}
/**
* Sets the value of the flag that determines if JMX will be enabled for
* pools created with this configuration instance.
*
* @param jmxEnabled The new setting of {@code jmxEnabled}
* for this configuration instance
*/
public void setJmxEnabled(final boolean jmxEnabled) {
this.jmxEnabled = jmxEnabled;
}
/**
* Gets the value of the JMX name base that will be used as part of the
* name assigned to JMX enabled pools created with this configuration
* instance. A value of <code>null</code> means that the pool will define
* the JMX name base.
*
* @return The current setting of {@code jmxNameBase} for this
* configuration instance
*/
public String getJmxNameBase() {
return jmxNameBase;
}
/**
* Sets the value of the JMX name base that will be used as part of the
* name assigned to JMX enabled pools created with this configuration
* instance. A value of <code>null</code> means that the pool will define
* the JMX name base.
*
* @param jmxNameBase The new setting of {@code jmxNameBase}
* for this configuration instance
*/
public void setJmxNameBase(final String jmxNameBase) {
this.jmxNameBase = jmxNameBase;
}
/**
* Gets the value of the JMX name prefix that will be used as part of the
* name assigned to JMX enabled pools created with this configuration
* instance.
*
* @return The current setting of {@code jmxNamePrefix} for this
* configuration instance
*/
public String getJmxNamePrefix() {
return jmxNamePrefix;
}
/**
* Sets the value of the JMX name prefix that will be used as part of the
* name assigned to JMX enabled pools created with this configuration
* instance.
*
* @param jmxNamePrefix The new setting of {@code jmxNamePrefix}
* for this configuration instance
*/
public void setJmxNamePrefix(final String jmxNamePrefix) {
this.jmxNamePrefix = jmxNamePrefix;
}
@Override
protected void toStringAppendFields(final StringBuilder builder) {
builder.append("lifo=");
builder.append(lifo);
builder.append(", fairness=");
builder.append(fairness);
builder.append(", maxWaitMillis=");
builder.append(maxWaitMillis);
builder.append(", minEvictableIdleTimeMillis=");
builder.append(minEvictableIdleTimeMillis);
builder.append(", softMinEvictableIdleTimeMillis=");
builder.append(softMinEvictableIdleTimeMillis);
builder.append(", numTestsPerEvictionRun=");
builder.append(numTestsPerEvictionRun);
builder.append(", evictionPolicyClassName=");
builder.append(evictionPolicyClassName);
builder.append(", testOnCreate=");
builder.append(testOnCreate);
builder.append(", testOnBorrow=");
builder.append(testOnBorrow);
builder.append(", testOnReturn=");
builder.append(testOnReturn);
builder.append(", testWhileIdle=");
builder.append(testWhileIdle);
builder.append(", timeBetweenEvictionRunsMillis=");
builder.append(timeBetweenEvictionRunsMillis);
builder.append(", blockWhenExhausted=");
builder.append(blockWhenExhausted);
builder.append(", jmxEnabled=");
builder.append(jmxEnabled);
builder.append(", jmxNamePrefix=");
builder.append(jmxNamePrefix);
builder.append(", jmxNameBase=");
builder.append(jmxNameBase);
}
}

54
fine-jedis/src/com/fr/third/org/apache/commons/pool2/impl/CallStack.java

@ -0,0 +1,54 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 com.fr.third.org.apache.commons.pool2.impl;
import com.fr.third.org.apache.commons.pool2.PooledObject;
import com.fr.third.org.apache.commons.pool2.UsageTracking;
import java.io.PrintWriter;
/**
* Strategy for obtaining and printing the current call stack. This is primarily useful for
* {@linkplain UsageTracking usage tracking} so that different JVMs and configurations can use more efficient strategies
* for obtaining the current call stack depending on metadata needs.
*
* @see CallStackUtils
* @since 2.4.3
*/
public interface CallStack {
/**
* Prints the current stack trace if available to a PrintWriter. The format is undefined and is primarily useful
* for debugging issues with {@link PooledObject} usage in user code.
*
* @param writer a PrintWriter to write the current stack trace to if available
* @return true if a stack trace was available to print or false if nothing was printed
*/
boolean printStackTrace(final PrintWriter writer);
/**
* Takes a snapshot of the current call stack. Subsequent calls to {@link #printStackTrace(PrintWriter)} will print
* out that stack trace until it is {@linkplain #clear() cleared}.
*/
void fillInStackTrace();
/**
* Clears the current stack trace snapshot. Subsequent calls to {@link #printStackTrace(PrintWriter)} will be
* no-ops until another call to {@link #fillInStackTrace()}.
*/
void clear();
}

89
fine-jedis/src/com/fr/third/org/apache/commons/pool2/impl/CallStackUtils.java

@ -0,0 +1,89 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 com.fr.third.org.apache.commons.pool2.impl;
import java.security.AccessControlException;
/**
* Utility methods for {@link CallStack}.
*
* @since 2.4.3
*/
public final class CallStackUtils {
private static final boolean CAN_CREATE_SECURITY_MANAGER;
static {
CAN_CREATE_SECURITY_MANAGER = canCreateSecurityManager();
}
/**
* @return {@code true} if it is able to create a security manager in the current environment, {@code false}
* otherwise.
*/
private static boolean canCreateSecurityManager() {
final SecurityManager manager = System.getSecurityManager();
if (manager == null) {
return true;
}
try {
manager.checkPermission(new RuntimePermission("createSecurityManager"));
return true;
} catch (final AccessControlException ignored) {
return false;
}
}
/**
* Constructs a new {@link CallStack} using the fastest allowed strategy.
*
* @param messageFormat message (or format) to print first in stack traces
* @param useTimestamp if true, interpret message as a SimpleDateFormat and print the created timestamp; otherwise,
* print message format literally
* @return a new CallStack
* @deprecated use {@link #newCallStack(String, boolean, boolean)}
*/
@Deprecated
public static CallStack newCallStack(final String messageFormat, final boolean useTimestamp) {
return newCallStack(messageFormat, useTimestamp, false);
}
/**
* Constructs a new {@link CallStack} using the fasted allowed strategy.
*
* @param messageFormat message (or format) to print first in stack traces
* @param useTimestamp if true, interpret message as a SimpleDateFormat and print the created timestamp;
* otherwise, print message format literally
* @param requireFullStackTrace if true, forces the use of a stack walking mechanism that includes full stack trace
* information; otherwise, uses a faster implementation if possible
* @return a new CallStack
* @since 2.5
*/
public static CallStack newCallStack(final String messageFormat,
final boolean useTimestamp,
final boolean requireFullStackTrace) {
return CAN_CREATE_SECURITY_MANAGER && !requireFullStackTrace
? new SecurityManagerCallStack(messageFormat, useTimestamp)
: new ThrowableCallStack(messageFormat, useTimestamp);
}
/**
* Hidden constructor.
*/
private CallStackUtils() {
}
}

53
fine-jedis/src/com/fr/third/org/apache/commons/pool2/impl/DefaultEvictionPolicy.java

@ -0,0 +1,53 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 com.fr.third.org.apache.commons.pool2.impl;
import com.fr.third.org.apache.commons.pool2.PooledObject;
/**
* Provides the default implementation of {@link EvictionPolicy} used by the
* pools. Objects will be evicted if the following conditions are met:
* <ul>
* <li>the object has been idle longer than
* {@link GenericObjectPool#getMinEvictableIdleTimeMillis()} /
* {@link GenericKeyedObjectPool#getMinEvictableIdleTimeMillis()}</li>
* <li>there are more than {@link GenericObjectPool#getMinIdle()} /
* {@link GenericKeyedObjectPoolConfig#getMinIdlePerKey()} idle objects in
* the pool and the object has been idle for longer than
* {@link GenericObjectPool#getSoftMinEvictableIdleTimeMillis()} /
* {@link GenericKeyedObjectPool#getSoftMinEvictableIdleTimeMillis()}
* </ul>
* This class is immutable and thread-safe.
*
* @param <T> the type of objects in the pool
*
* @since 2.0
*/
public class DefaultEvictionPolicy<T> implements EvictionPolicy<T> {
@Override
public boolean evict(final EvictionConfig config, final PooledObject<T> underTest,
final int idleCount) {
if ((config.getIdleSoftEvictTime() < underTest.getIdleTimeMillis() &&
config.getMinIdle() < idleCount) ||
config.getIdleEvictTime() < underTest.getIdleTimeMillis()) {
return true;
}
return false;
}
}

297
fine-jedis/src/com/fr/third/org/apache/commons/pool2/impl/DefaultPooledObject.java

@ -0,0 +1,297 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 com.fr.third.org.apache.commons.pool2.impl;
import com.fr.third.org.apache.commons.pool2.PooledObject;
import com.fr.third.org.apache.commons.pool2.PooledObjectState;
import com.fr.third.org.apache.commons.pool2.TrackedUse;
import java.io.PrintWriter;
import java.util.Deque;
/**
* This wrapper is used to track the additional information, such as state, for
* the pooled objects.
* <p>
* This class is intended to be thread-safe.
*
* @param <T> the type of object in the pool
*
* @since 2.0
*/
public class DefaultPooledObject<T> implements PooledObject<T> {
private final T object;
private PooledObjectState state = PooledObjectState.IDLE; // @GuardedBy("this") to ensure transitions are valid
private final long createTime = System.currentTimeMillis();
private volatile long lastBorrowTime = createTime;
private volatile long lastUseTime = createTime;
private volatile long lastReturnTime = createTime;
private volatile boolean logAbandoned = false;
private volatile CallStack borrowedBy = NoOpCallStack.INSTANCE;
private volatile CallStack usedBy = NoOpCallStack.INSTANCE;
private volatile long borrowedCount = 0;
/**
* Create a new instance that wraps the provided object so that the pool can
* track the state of the pooled object.
*
* @param object The object to wrap
*/
public DefaultPooledObject(final T object) {
this.object = object;
}
@Override
public T getObject() {
return object;
}
@Override
public long getCreateTime() {
return createTime;
}
@Override
public long getActiveTimeMillis() {
// Take copies to avoid threading issues
final long rTime = lastReturnTime;
final long bTime = lastBorrowTime;
if (rTime > bTime) {
return rTime - bTime;
}
return System.currentTimeMillis() - bTime;
}
@Override
public long getIdleTimeMillis() {
final long elapsed = System.currentTimeMillis() - lastReturnTime;
// elapsed may be negative if:
// - another thread updates lastReturnTime during the calculation window
// - System.currentTimeMillis() is not monotonic (e.g. system time is set back)
return elapsed >= 0 ? elapsed : 0;
}
@Override
public long getLastBorrowTime() {
return lastBorrowTime;
}
@Override
public long getLastReturnTime() {
return lastReturnTime;
}
/**
* Get the number of times this object has been borrowed.
* @return The number of times this object has been borrowed.
* @since 2.1
*/
public long getBorrowedCount() {
return borrowedCount;
}
/**
* Return an estimate of the last time this object was used. If the class
* of the pooled object implements {@link TrackedUse}, what is returned is
* the maximum of {@link TrackedUse#getLastUsed()} and
* {@link #getLastBorrowTime()}; otherwise this method gives the same
* value as {@link #getLastBorrowTime()}.
*
* @return the last time this object was used
*/
@Override
public long getLastUsedTime() {
if (object instanceof TrackedUse) {
return Math.max(((TrackedUse) object).getLastUsed(), lastUseTime);
}
return lastUseTime;
}
@Override
public int compareTo(final PooledObject<T> other) {
final long lastActiveDiff = this.getLastReturnTime() - other.getLastReturnTime();
if (lastActiveDiff == 0) {
// Make sure the natural ordering is broadly consistent with equals
// although this will break down if distinct objects have the same
// identity hash code.
// see java.lang.Comparable Javadocs
return System.identityHashCode(this) - System.identityHashCode(other);
}
// handle int overflow
return (int)Math.min(Math.max(lastActiveDiff, Integer.MIN_VALUE), Integer.MAX_VALUE);
}
@Override
public String toString() {
final StringBuilder result = new StringBuilder();
result.append("Object: ");
result.append(object.toString());
result.append(", State: ");
synchronized (this) {
result.append(state.toString());
}
return result.toString();
// TODO add other attributes
}
@Override
public synchronized boolean startEvictionTest() {
if (state == PooledObjectState.IDLE) {
state = PooledObjectState.EVICTION;
return true;
}
return false;
}
@Override
public synchronized boolean endEvictionTest(
final Deque<PooledObject<T>> idleQueue) {
if (state == PooledObjectState.EVICTION) {
state = PooledObjectState.IDLE;
return true;
} else if (state == PooledObjectState.EVICTION_RETURN_TO_HEAD) {
state = PooledObjectState.IDLE;
if (!idleQueue.offerFirst(this)) {
// TODO - Should never happen
}
}
return false;
}
/**
* Allocates the object.
*
* @return {@code true} if the original state was {@link PooledObjectState#IDLE IDLE}
*/
@Override
public synchronized boolean allocate() {
if (state == PooledObjectState.IDLE) {
state = PooledObjectState.ALLOCATED;
lastBorrowTime = System.currentTimeMillis();
lastUseTime = lastBorrowTime;
borrowedCount++;
if (logAbandoned) {
borrowedBy.fillInStackTrace();
}
return true;
} else if (state == PooledObjectState.EVICTION) {
// TODO Allocate anyway and ignore eviction test
state = PooledObjectState.EVICTION_RETURN_TO_HEAD;
return false;
}
// TODO if validating and testOnBorrow == true then pre-allocate for
// performance
return false;
}
/**
* Deallocates the object and sets it {@link PooledObjectState#IDLE IDLE}
* if it is currently {@link PooledObjectState#ALLOCATED ALLOCATED}.
*
* @return {@code true} if the state was {@link PooledObjectState#ALLOCATED ALLOCATED}
*/
@Override
public synchronized boolean deallocate() {
if (state == PooledObjectState.ALLOCATED ||
state == PooledObjectState.RETURNING) {
state = PooledObjectState.IDLE;
lastReturnTime = System.currentTimeMillis();
borrowedBy.clear();
return true;
}
return false;
}
/**
* Sets the state to {@link PooledObjectState#INVALID INVALID}
*/
@Override
public synchronized void invalidate() {
state = PooledObjectState.INVALID;
}
@Override
public void use() {
lastUseTime = System.currentTimeMillis();
usedBy.fillInStackTrace();
}
@Override
public void printStackTrace(final PrintWriter writer) {
boolean written = borrowedBy.printStackTrace(writer);
written |= usedBy.printStackTrace(writer);
if (written) {
writer.flush();
}
}
/**
* Returns the state of this object.
* @return state
*/
@Override
public synchronized PooledObjectState getState() {
return state;
}
/**
* Marks the pooled object as abandoned.
*/
@Override
public synchronized void markAbandoned() {
state = PooledObjectState.ABANDONED;
}
/**
* Marks the object as returning to the pool.
*/
@Override
public synchronized void markReturning() {
state = PooledObjectState.RETURNING;
}
@Override
public void setLogAbandoned(final boolean logAbandoned) {
this.logAbandoned = logAbandoned;
}
/**
* Configures the stack trace generation strategy based on whether or not fully
* detailed stack traces are required. When set to false, abandoned logs may
* only include caller class information rather than method names, line numbers,
* and other normal metadata available in a full stack trace.
*
* @param requireFullStackTrace the new configuration setting for abandoned object
* logging
* @since 2.5
*/
// TODO: uncomment below in 3.0
// @Override
public void setRequireFullStackTrace(final boolean requireFullStackTrace) {
borrowedBy = CallStackUtils.newCallStack("'Pooled object created' " +
"yyyy-MM-dd HH:mm:ss Z 'by the following code has not been returned to the pool:'",
true, requireFullStackTrace);
usedBy = CallStackUtils.newCallStack("The last code to use this object was:",
false, requireFullStackTrace);
}
}

114
fine-jedis/src/com/fr/third/org/apache/commons/pool2/impl/DefaultPooledObjectInfo.java

@ -0,0 +1,114 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 com.fr.third.org.apache.commons.pool2.impl;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.text.SimpleDateFormat;
import com.fr.third.org.apache.commons.pool2.PooledObject;
/**
* Implementation of object that is used to provide information on pooled
* objects via JMX.
*
* @since 2.0
*/
public class DefaultPooledObjectInfo implements DefaultPooledObjectInfoMBean {
private final PooledObject<?> pooledObject;
/**
* Create a new instance for the given pooled object.
*
* @param pooledObject The pooled object that this instance will represent
*/
public DefaultPooledObjectInfo(final PooledObject<?> pooledObject) {
this.pooledObject = pooledObject;
}
@Override
public long getCreateTime() {
return pooledObject.getCreateTime();
}
@Override
public String getCreateTimeFormatted() {
final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss Z");
return sdf.format(Long.valueOf(pooledObject.getCreateTime()));
}
@Override
public long getLastBorrowTime() {
return pooledObject.getLastBorrowTime();
}
@Override
public String getLastBorrowTimeFormatted() {
final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss Z");
return sdf.format(Long.valueOf(pooledObject.getLastBorrowTime()));
}
@Override
public String getLastBorrowTrace() {
final StringWriter sw = new StringWriter();
pooledObject.printStackTrace(new PrintWriter(sw));
return sw.toString();
}
@Override
public long getLastReturnTime() {
return pooledObject.getLastReturnTime();
}
@Override
public String getLastReturnTimeFormatted() {
final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss Z");
return sdf.format(Long.valueOf(pooledObject.getLastReturnTime()));
}
@Override
public String getPooledObjectType() {
return pooledObject.getObject().getClass().getName();
}
@Override
public String getPooledObjectToString() {
return pooledObject.getObject().toString();
}
@Override
public long getBorrowedCount() {
// TODO Simplify this once getBorrowedCount has been added to PooledObject
if (pooledObject instanceof DefaultPooledObject) {
return ((DefaultPooledObject<?>) pooledObject).getBorrowedCount();
}
return -1;
}
/**
* @since 2.4.3
*/
@Override
public String toString() {
final StringBuilder builder = new StringBuilder();
builder.append("DefaultPooledObjectInfo [pooledObject=");
builder.append(pooledObject);
builder.append("]");
return builder.toString();
}
}

115
fine-jedis/src/com/fr/third/org/apache/commons/pool2/impl/DefaultPooledObjectInfoMBean.java

@ -0,0 +1,115 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 com.fr.third.org.apache.commons.pool2.impl;
/**
* The interface that defines the information about pooled objects that will be
* exposed via JMX.
*
* NOTE: This interface exists only to define those attributes and methods that
* will be made available via JMX. It must not be implemented by clients
* as it is subject to change between major, minor and patch version
* releases of commons pool. Clients that implement this interface may
* not, therefore, be able to upgrade to a new minor or patch release
* without requiring code changes.
*
* @since 2.0
*/
public interface DefaultPooledObjectInfoMBean {
/**
* Obtain the time (using the same basis as
* {@link System#currentTimeMillis()}) that pooled object was created.
*
* @return The creation time for the pooled object
*/
long getCreateTime();
/**
* Obtain the time that pooled object was created.
*
* @return The creation time for the pooled object formatted as
* <code>yyyy-MM-dd HH:mm:ss Z</code>
*/
String getCreateTimeFormatted();
/**
* Obtain the time (using the same basis as
* {@link System#currentTimeMillis()}) the polled object was last borrowed.
*
* @return The time the pooled object was last borrowed
*/
long getLastBorrowTime();
/**
* Obtain the time that pooled object was last borrowed.
*
* @return The last borrowed time for the pooled object formated as
* <code>yyyy-MM-dd HH:mm:ss Z</code>
*/
String getLastBorrowTimeFormatted();
/**
* Obtain the stack trace recorded when the pooled object was last borrowed.
*
* @return The stack trace showing which code last borrowed the pooled
* object
*/
String getLastBorrowTrace();
/**
* Obtain the time (using the same basis as
* {@link System#currentTimeMillis()})the wrapped object was last returned.
*
* @return The time the object was last returned
*/
long getLastReturnTime();
/**
* Obtain the time that pooled object was last returned.
*
* @return The last returned time for the pooled object formated as
* <code>yyyy-MM-dd HH:mm:ss Z</code>
*/
String getLastReturnTimeFormatted();
/**
* Obtain the name of the class of the pooled object.
*
* @return The pooled object's class name
*
* @see Class#getName()
*/
String getPooledObjectType();
/**
* Provides a String form of the wrapper for debug purposes. The format is
* not fixed and may change at any time.
*
* @return A string representation of the pooled object
*
* @see Object#toString()
*/
String getPooledObjectToString();
/**
* Get the number of times this object has been borrowed.
* @return The number of times this object has been borrowed.
* @since 2.1
*/
long getBorrowedCount();
}

114
fine-jedis/src/com/fr/third/org/apache/commons/pool2/impl/EvictionConfig.java

@ -0,0 +1,114 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 com.fr.third.org.apache.commons.pool2.impl;
/**
* This class is used by pool implementations to pass configuration information
* to {@link EvictionPolicy} instances. The {@link EvictionPolicy} may also have
* its own specific configuration attributes.
* <p>
* This class is immutable and thread-safe.
*
* @since 2.0
*/
public class EvictionConfig {
private final long idleEvictTime;
private final long idleSoftEvictTime;
private final int minIdle;
/**
* Create a new eviction configuration with the specified parameters.
* Instances are immutable.
*
* @param poolIdleEvictTime Expected to be provided by
* {@link BaseGenericObjectPool#getMinEvictableIdleTimeMillis()}
* @param poolIdleSoftEvictTime Expected to be provided by
* {@link BaseGenericObjectPool#getSoftMinEvictableIdleTimeMillis()}
* @param minIdle Expected to be provided by
* {@link GenericObjectPool#getMinIdle()} or
* {@link GenericKeyedObjectPool#getMinIdlePerKey()}
*/
public EvictionConfig(final long poolIdleEvictTime, final long poolIdleSoftEvictTime,
final int minIdle) {
if (poolIdleEvictTime > 0) {
idleEvictTime = poolIdleEvictTime;
} else {
idleEvictTime = Long.MAX_VALUE;
}
if (poolIdleSoftEvictTime > 0) {
idleSoftEvictTime = poolIdleSoftEvictTime;
} else {
idleSoftEvictTime = Long.MAX_VALUE;
}
this.minIdle = minIdle;
}
/**
* Obtain the {@code idleEvictTime} for this eviction configuration
* instance.
* <p>
* How the evictor behaves based on this value will be determined by the
* configured {@link EvictionPolicy}.
*
* @return The {@code idleEvictTime} in milliseconds
*/
public long getIdleEvictTime() {
return idleEvictTime;
}
/**
* Obtain the {@code idleSoftEvictTime} for this eviction configuration
* instance.
* <p>
* How the evictor behaves based on this value will be determined by the
* configured {@link EvictionPolicy}.
*
* @return The (@code idleSoftEvictTime} in milliseconds
*/
public long getIdleSoftEvictTime() {
return idleSoftEvictTime;
}
/**
* Obtain the {@code minIdle} for this eviction configuration instance.
* <p>
* How the evictor behaves based on this value will be determined by the
* configured {@link EvictionPolicy}.
*
* @return The {@code minIdle}
*/
public int getMinIdle() {
return minIdle;
}
/**
* @since 2.4
*/
@Override
public String toString() {
final StringBuilder builder = new StringBuilder();
builder.append("EvictionConfig [idleEvictTime=");
builder.append(idleEvictTime);
builder.append(", idleSoftEvictTime=");
builder.append(idleSoftEvictTime);
builder.append(", minIdle=");
builder.append(minIdle);
builder.append("]");
return builder.toString();
}
}

45
fine-jedis/src/com/fr/third/org/apache/commons/pool2/impl/EvictionPolicy.java

@ -0,0 +1,45 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 com.fr.third.org.apache.commons.pool2.impl;
import com.fr.third.org.apache.commons.pool2.PooledObject;
/**
* To provide a custom eviction policy (i.e. something other than {@link
* DefaultEvictionPolicy} for a pool, users must provide an implementation of
* this interface that provides the required eviction policy.
*
* @param <T> the type of objects in the pool
*
* @since 2.0
*/
public interface EvictionPolicy<T> {
/**
* This method is called to test if an idle object in the pool should be
* evicted or not.
*
* @param config The pool configuration settings related to eviction
* @param underTest The pooled object being tested for eviction
* @param idleCount The current number of idle objects in the pool including
* the object under test
* @return <code>true</code> if the object should be evicted, otherwise
* <code>false</code>
*/
boolean evict(EvictionConfig config, PooledObject<T> underTest,
int idleCount);
}

129
fine-jedis/src/com/fr/third/org/apache/commons/pool2/impl/EvictionTimer.java

@ -0,0 +1,129 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 com.fr.third.org.apache.commons.pool2.impl;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.TimerTask;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;
/**
* Provides a shared idle object eviction timer for all pools. This class is
* currently implemented using {@link ScheduledThreadPoolExecutor}. This
* implementation may change in any future release. This class keeps track of
* how many pools are using it. If no pools are using the timer, it is cancelled.
* This prevents a thread being left running which, in application server
* environments, can lead to memory leads and/or prevent applications from
* shutting down or reloading cleanly.
* <p>
* This class has package scope to prevent its inclusion in the pool public API.
* The class declaration below should *not* be changed to public.
* <p>
* This class is intended to be thread-safe.
*
* @since 2.0
*/
class EvictionTimer {
/** Executor instance */
private static ScheduledThreadPoolExecutor executor; //@GuardedBy("EvictionTimer.class")
/** Static usage count tracker */
private static int usageCount; //@GuardedBy("EvictionTimer.class")
/** Prevent instantiation */
private EvictionTimer() {
// Hide the default constructor
}
/**
* @since 2.4.3
*/
@Override
public String toString() {
final StringBuilder builder = new StringBuilder();
builder.append("EvictionTimer []");
return builder.toString();
}
/**
* Add the specified eviction task to the timer. Tasks that are added with a
* call to this method *must* call {@link #cancel(TimerTask)} to cancel the
* task to prevent memory and/or thread leaks in application server
* environments.
* @param task Task to be scheduled
* @param delay Delay in milliseconds before task is executed
* @param period Time in milliseconds between executions
*/
static synchronized void schedule(final Runnable task, final long delay, final long period) {
if (null == executor) {
executor = new ScheduledThreadPoolExecutor(1, new EvictorThreadFactory());
}
usageCount++;
executor.scheduleWithFixedDelay(task, delay, period, TimeUnit.MILLISECONDS);
}
/**
* Remove the specified eviction task from the timer.
*
* @param task Task to be cancelled
* @param timeout If the associated executor is no longer required, how
* long should this thread wait for the executor to
* terminate?
* @param unit The units for the specified timeout
*/
static synchronized void cancel(final TimerTask task, final long timeout, final TimeUnit unit) {
task.cancel();
usageCount--;
if (usageCount == 0) {
executor.shutdown();
try {
executor.awaitTermination(timeout, unit);
} catch (final InterruptedException e) {
// Swallow
// Significant API changes would be required to propagate this
}
executor.setCorePoolSize(0);
executor = null;
}
}
/**
* Thread factory that creates a thread, with the context classloader from this class.
*/
private static class EvictorThreadFactory implements ThreadFactory {
@Override
public Thread newThread(final Runnable r) {
final Thread t = new Thread(null, r, "commons-pool-evictor-thread");
AccessController.doPrivileged(new PrivilegedAction<Void>() {
@Override
public Void run() {
t.setContextClassLoader(EvictorThreadFactory.class.getClassLoader());
return null;
}
});
return t;
}
}
}

1625
fine-jedis/src/com/fr/third/org/apache/commons/pool2/impl/GenericKeyedObjectPool.java

File diff suppressed because it is too large Load Diff

195
fine-jedis/src/com/fr/third/org/apache/commons/pool2/impl/GenericKeyedObjectPoolConfig.java

@ -0,0 +1,195 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 com.fr.third.org.apache.commons.pool2.impl;
/**
* A simple "struct" encapsulating the configuration for a
* {@link GenericKeyedObjectPool}.
*
* <p>
* This class is not thread-safe; it is only intended to be used to provide
* attributes used when creating a pool.
*
* @since 2.0
*/
public class GenericKeyedObjectPoolConfig extends BaseObjectPoolConfig {
/**
* The default value for the {@code maxTotalPerKey} configuration attribute.
* @see GenericKeyedObjectPool#getMaxTotalPerKey()
*/
public static final int DEFAULT_MAX_TOTAL_PER_KEY = 8;
/**
* The default value for the {@code maxTotal} configuration attribute.
* @see GenericKeyedObjectPool#getMaxTotal()
*/
public static final int DEFAULT_MAX_TOTAL = -1;
/**
* The default value for the {@code minIdlePerKey} configuration attribute.
* @see GenericKeyedObjectPool#getMinIdlePerKey()
*/
public static final int DEFAULT_MIN_IDLE_PER_KEY = 0;
/**
* The default value for the {@code maxIdlePerKey} configuration attribute.
* @see GenericKeyedObjectPool#getMaxIdlePerKey()
*/
public static final int DEFAULT_MAX_IDLE_PER_KEY = 8;
private int minIdlePerKey = DEFAULT_MIN_IDLE_PER_KEY;
private int maxIdlePerKey = DEFAULT_MAX_IDLE_PER_KEY;
private int maxTotalPerKey = DEFAULT_MAX_TOTAL_PER_KEY;
private int maxTotal = DEFAULT_MAX_TOTAL;
/**
* Create a new configuration with default settings.
*/
public GenericKeyedObjectPoolConfig() {
}
/**
* Get the value for the {@code maxTotal} configuration attribute
* for pools created with this configuration instance.
*
* @return The current setting of {@code maxTotal} for this
* configuration instance
*
* @see GenericKeyedObjectPool#getMaxTotal()
*/
public int getMaxTotal() {
return maxTotal;
}
/**
* Set the value for the {@code maxTotal} configuration attribute for
* pools created with this configuration instance.
*
* @param maxTotal The new setting of {@code maxTotal}
* for this configuration instance
*
* @see GenericKeyedObjectPool#setMaxTotal(int)
*/
public void setMaxTotal(final int maxTotal) {
this.maxTotal = maxTotal;
}
/**
* Get the value for the {@code maxTotalPerKey} configuration attribute
* for pools created with this configuration instance.
*
* @return The current setting of {@code maxTotalPerKey} for this
* configuration instance
*
* @see GenericKeyedObjectPool#getMaxTotalPerKey()
*/
public int getMaxTotalPerKey() {
return maxTotalPerKey;
}
/**
* Set the value for the {@code maxTotalPerKey} configuration attribute for
* pools created with this configuration instance.
*
* @param maxTotalPerKey The new setting of {@code maxTotalPerKey}
* for this configuration instance
*
* @see GenericKeyedObjectPool#setMaxTotalPerKey(int)
*/
public void setMaxTotalPerKey(final int maxTotalPerKey) {
this.maxTotalPerKey = maxTotalPerKey;
}
/**
* Get the value for the {@code minIdlePerKey} configuration attribute
* for pools created with this configuration instance.
*
* @return The current setting of {@code minIdlePerKey} for this
* configuration instance
*
* @see GenericKeyedObjectPool#getMinIdlePerKey()
*/
public int getMinIdlePerKey() {
return minIdlePerKey;
}
/**
* Set the value for the {@code minIdlePerKey} configuration attribute for
* pools created with this configuration instance.
*
* @param minIdlePerKey The new setting of {@code minIdlePerKey}
* for this configuration instance
*
* @see GenericKeyedObjectPool#setMinIdlePerKey(int)
*/
public void setMinIdlePerKey(final int minIdlePerKey) {
this.minIdlePerKey = minIdlePerKey;
}
/**
* Get the value for the {@code maxIdlePerKey} configuration attribute
* for pools created with this configuration instance.
*
* @return The current setting of {@code maxIdlePerKey} for this
* configuration instance
*
* @see GenericKeyedObjectPool#getMaxIdlePerKey()
*/
public int getMaxIdlePerKey() {
return maxIdlePerKey;
}
/**
* Set the value for the {@code maxIdlePerKey} configuration attribute for
* pools created with this configuration instance.
*
* @param maxIdlePerKey The new setting of {@code maxIdlePerKey}
* for this configuration instance
*
* @see GenericKeyedObjectPool#setMaxIdlePerKey(int)
*/
public void setMaxIdlePerKey(final int maxIdlePerKey) {
this.maxIdlePerKey = maxIdlePerKey;
}
@Override
public GenericKeyedObjectPoolConfig clone() {
try {
return (GenericKeyedObjectPoolConfig) super.clone();
} catch (final CloneNotSupportedException e) {
throw new AssertionError(); // Can't happen
}
}
@Override
protected void toStringAppendFields(final StringBuilder builder) {
super.toStringAppendFields(builder);
builder.append(", minIdlePerKey=");
builder.append(minIdlePerKey);
builder.append(", maxIdlePerKey=");
builder.append(maxIdlePerKey);
builder.append(", maxTotalPerKey=");
builder.append(maxTotalPerKey);
builder.append(", maxTotal=");
builder.append(maxTotal);
}
}

205
fine-jedis/src/com/fr/third/org/apache/commons/pool2/impl/GenericKeyedObjectPoolMXBean.java

@ -0,0 +1,205 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 com.fr.third.org.apache.commons.pool2.impl;
import java.util.List;
import java.util.Map;
/**
* Defines the methods that will be made available via JMX.
*
* NOTE: This interface exists only to define those attributes and methods that
* will be made available via JMX. It must not be implemented by clients
* as it is subject to change between major, minor and patch version
* releases of commons pool. Clients that implement this interface may
* not, therefore, be able to upgrade to a new minor or patch release
* without requiring code changes.
*
* @param <K> The type of keys maintained by the pool.
*
* @since 2.0
*/
public interface GenericKeyedObjectPoolMXBean<K> {
// Expose getters for configuration settings
/**
* See {@link GenericKeyedObjectPool#getBlockWhenExhausted()}
* @return See {@link GenericKeyedObjectPool#getBlockWhenExhausted()}
*/
boolean getBlockWhenExhausted();
/**
* See {@link GenericKeyedObjectPool#getFairness()}
* @return See {@link GenericKeyedObjectPool#getFairness()}
*/
boolean getFairness();
/**
* See {@link GenericKeyedObjectPool#getLifo()}
* @return See {@link GenericKeyedObjectPool#getLifo()}
*/
boolean getLifo();
/**
* See {@link GenericKeyedObjectPool#getMaxIdlePerKey()}
* @return See {@link GenericKeyedObjectPool#getMaxIdlePerKey()}
*/
int getMaxIdlePerKey();
/**
* See {@link GenericKeyedObjectPool#getMaxTotal()}
* @return See {@link GenericKeyedObjectPool#getMaxTotal()}
*/
int getMaxTotal();
/**
* See {@link GenericKeyedObjectPool#getMaxTotalPerKey()}
* @return See {@link GenericKeyedObjectPool#getMaxTotalPerKey()}
*/
int getMaxTotalPerKey();
/**
* See {@link GenericKeyedObjectPool#getMaxWaitMillis()}
* @return See {@link GenericKeyedObjectPool#getMaxWaitMillis()}
*/
long getMaxWaitMillis();
/**
* See {@link GenericKeyedObjectPool#getMinEvictableIdleTimeMillis()}
* @return See {@link GenericKeyedObjectPool#getMinEvictableIdleTimeMillis()}
*/
long getMinEvictableIdleTimeMillis();
/**
* See {@link GenericKeyedObjectPool#getMinIdlePerKey()}
* @return See {@link GenericKeyedObjectPool#getMinIdlePerKey()}
*/
int getMinIdlePerKey();
/**
* See {@link GenericKeyedObjectPool#getNumActive()}
* @return See {@link GenericKeyedObjectPool#getNumActive()}
*/
int getNumActive();
/**
* See {@link GenericKeyedObjectPool#getNumIdle()}
* @return See {@link GenericKeyedObjectPool#getNumIdle()}
*/
int getNumIdle();
/**
* See {@link GenericKeyedObjectPool#getNumTestsPerEvictionRun()}
* @return See {@link GenericKeyedObjectPool#getNumTestsPerEvictionRun()}
*/
int getNumTestsPerEvictionRun();
/**
* See {@link GenericKeyedObjectPool#getTestOnCreate()}
* @return See {@link GenericKeyedObjectPool#getTestOnCreate()}
* @since 2.2
*/
boolean getTestOnCreate();
/**
* See {@link GenericKeyedObjectPool#getTestOnBorrow()}
* @return See {@link GenericKeyedObjectPool#getTestOnBorrow()}
*/
boolean getTestOnBorrow();
/**
* See {@link GenericKeyedObjectPool#getTestOnReturn()}
* @return See {@link GenericKeyedObjectPool#getTestOnReturn()}
*/
boolean getTestOnReturn();
/**
* See {@link GenericKeyedObjectPool#getTestWhileIdle()}
* @return See {@link GenericKeyedObjectPool#getTestWhileIdle()}
*/
boolean getTestWhileIdle();
/**
* See {@link GenericKeyedObjectPool#getTimeBetweenEvictionRunsMillis()}
* @return See {@link GenericKeyedObjectPool#getTimeBetweenEvictionRunsMillis()}
*/
long getTimeBetweenEvictionRunsMillis();
/**
* See {@link GenericKeyedObjectPool#isClosed()}
* @return See {@link GenericKeyedObjectPool#isClosed()}
*/
boolean isClosed();
// Expose getters for monitoring attributes
/**
* See {@link GenericKeyedObjectPool#getNumActivePerKey()}
* @return See {@link GenericKeyedObjectPool#getNumActivePerKey()}
*/
Map<String,Integer> getNumActivePerKey();
/**
* See {@link GenericKeyedObjectPool#getBorrowedCount()}
* @return See {@link GenericKeyedObjectPool#getBorrowedCount()}
*/
long getBorrowedCount();
/**
* See {@link GenericKeyedObjectPool#getReturnedCount()}
* @return See {@link GenericKeyedObjectPool#getReturnedCount()}
*/
long getReturnedCount();
/**
* See {@link GenericKeyedObjectPool#getCreatedCount()}
* @return See {@link GenericKeyedObjectPool#getCreatedCount()}
*/
long getCreatedCount();
/**
* See {@link GenericKeyedObjectPool#getDestroyedCount()}
* @return See {@link GenericKeyedObjectPool#getDestroyedCount()}
*/
long getDestroyedCount();
/**
* See {@link GenericKeyedObjectPool#getDestroyedByEvictorCount()}
* @return See {@link GenericKeyedObjectPool#getDestroyedByEvictorCount()}
*/
long getDestroyedByEvictorCount();
/**
* See {@link GenericKeyedObjectPool#getDestroyedByBorrowValidationCount()}
* @return See {@link GenericKeyedObjectPool#getDestroyedByBorrowValidationCount()}
*/
long getDestroyedByBorrowValidationCount();
/**
* See {@link GenericKeyedObjectPool#getMeanActiveTimeMillis()}
* @return See {@link GenericKeyedObjectPool#getMeanActiveTimeMillis()}
*/
long getMeanActiveTimeMillis();
/**
* See {@link GenericKeyedObjectPool#getMeanIdleTimeMillis()}
* @return See {@link GenericKeyedObjectPool#getMeanIdleTimeMillis()}
*/
long getMeanIdleTimeMillis();
/**
* See {@link GenericKeyedObjectPool#getMaxBorrowWaitTimeMillis()}
* @return See {@link GenericKeyedObjectPool#getMaxBorrowWaitTimeMillis()}
*/
long getMeanBorrowWaitTimeMillis();
/**
* See {@link GenericKeyedObjectPool#getMaxBorrowWaitTimeMillis()}
* @return See {@link GenericKeyedObjectPool#getMaxBorrowWaitTimeMillis()}
*/
long getMaxBorrowWaitTimeMillis();
/**
* See {@link GenericKeyedObjectPool#getCreationStackTrace()}
* @return See {@link GenericKeyedObjectPool#getCreationStackTrace()}
*/
String getCreationStackTrace();
/**
* See {@link GenericKeyedObjectPool#getNumWaiters()}
* @return See {@link GenericKeyedObjectPool#getNumWaiters()}
*/
int getNumWaiters();
/**
* See {@link GenericKeyedObjectPool#getNumWaitersByKey()}
* @return See {@link GenericKeyedObjectPool#getNumWaitersByKey()}
*/
Map<String,Integer> getNumWaitersByKey();
/**
* See {@link GenericKeyedObjectPool#listAllObjects()}
* @return See {@link GenericKeyedObjectPool#listAllObjects()}
*/
Map<String,List<DefaultPooledObjectInfo>> listAllObjects();
}

1203
fine-jedis/src/com/fr/third/org/apache/commons/pool2/impl/GenericObjectPool.java

File diff suppressed because it is too large Load Diff

155
fine-jedis/src/com/fr/third/org/apache/commons/pool2/impl/GenericObjectPoolConfig.java

@ -0,0 +1,155 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 com.fr.third.org.apache.commons.pool2.impl;
/**
* A simple "struct" encapsulating the configuration for a
* {@link GenericObjectPool}.
*
* <p>
* This class is not thread-safe; it is only intended to be used to provide
* attributes used when creating a pool.
*
* @since 2.0
*/
public class GenericObjectPoolConfig extends BaseObjectPoolConfig {
/**
* The default value for the {@code maxTotal} configuration attribute.
* @see GenericObjectPool#getMaxTotal()
*/
public static final int DEFAULT_MAX_TOTAL = 8;
/**
* The default value for the {@code maxIdle} configuration attribute.
* @see GenericObjectPool#getMaxIdle()
*/
public static final int DEFAULT_MAX_IDLE = 8;
/**
* The default value for the {@code minIdle} configuration attribute.
* @see GenericObjectPool#getMinIdle()
*/
public static final int DEFAULT_MIN_IDLE = 0;
private int maxTotal = DEFAULT_MAX_TOTAL;
private int maxIdle = DEFAULT_MAX_IDLE;
private int minIdle = DEFAULT_MIN_IDLE;
/**
* Get the value for the {@code maxTotal} configuration attribute
* for pools created with this configuration instance.
*
* @return The current setting of {@code maxTotal} for this
* configuration instance
*
* @see GenericObjectPool#getMaxTotal()
*/
public int getMaxTotal() {
return maxTotal;
}
/**
* Set the value for the {@code maxTotal} configuration attribute for
* pools created with this configuration instance.
*
* @param maxTotal The new setting of {@code maxTotal}
* for this configuration instance
*
* @see GenericObjectPool#setMaxTotal(int)
*/
public void setMaxTotal(final int maxTotal) {
this.maxTotal = maxTotal;
}
/**
* Get the value for the {@code maxIdle} configuration attribute
* for pools created with this configuration instance.
*
* @return The current setting of {@code maxIdle} for this
* configuration instance
*
* @see GenericObjectPool#getMaxIdle()
*/
public int getMaxIdle() {
return maxIdle;
}
/**
* Set the value for the {@code maxIdle} configuration attribute for
* pools created with this configuration instance.
*
* @param maxIdle The new setting of {@code maxIdle}
* for this configuration instance
*
* @see GenericObjectPool#setMaxIdle(int)
*/
public void setMaxIdle(final int maxIdle) {
this.maxIdle = maxIdle;
}
/**
* Get the value for the {@code minIdle} configuration attribute
* for pools created with this configuration instance.
*
* @return The current setting of {@code minIdle} for this
* configuration instance
*
* @see GenericObjectPool#getMinIdle()
*/
public int getMinIdle() {
return minIdle;
}
/**
* Set the value for the {@code minIdle} configuration attribute for
* pools created with this configuration instance.
*
* @param minIdle The new setting of {@code minIdle}
* for this configuration instance
*
* @see GenericObjectPool#setMinIdle(int)
*/
public void setMinIdle(final int minIdle) {
this.minIdle = minIdle;
}
@Override
public GenericObjectPoolConfig clone() {
try {
return (GenericObjectPoolConfig) super.clone();
} catch (final CloneNotSupportedException e) {
throw new AssertionError(); // Can't happen
}
}
@Override
protected void toStringAppendFields(final StringBuilder builder) {
super.toStringAppendFields(builder);
builder.append(", maxTotal=");
builder.append(maxTotal);
builder.append(", maxIdle=");
builder.append(maxIdle);
builder.append(", minIdle=");
builder.append(minIdle);
}
}

219
fine-jedis/src/com/fr/third/org/apache/commons/pool2/impl/GenericObjectPoolMXBean.java

@ -0,0 +1,219 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 com.fr.third.org.apache.commons.pool2.impl;
import java.util.Set;
/**
* Defines the methods that will be made available via JMX.
*
* NOTE: This interface exists only to define those attributes and methods that
* will be made available via JMX. It must not be implemented by clients
* as it is subject to change between major, minor and patch version
* releases of commons pool. Clients that implement this interface may
* not, therefore, be able to upgrade to a new minor or patch release
* without requiring code changes.
*
* @since 2.0
*/
public interface GenericObjectPoolMXBean {
// Getters for basic configuration settings
/**
* See {@link GenericObjectPool#getBlockWhenExhausted()}
* @return See {@link GenericObjectPool#getBlockWhenExhausted()}
*/
boolean getBlockWhenExhausted();
/**
* See {@link GenericObjectPool#getLifo()}
* @return See {@link GenericObjectPool#getLifo()}
*/
boolean getFairness();
/**
* See {@link GenericObjectPool#getFairness()}
* @return See {@link GenericObjectPool#getFairness()}
*/
boolean getLifo();
/**
* See {@link GenericObjectPool#getMaxIdle()}
* @return See {@link GenericObjectPool#getMaxIdle()}
*/
int getMaxIdle();
/**
* See {@link GenericObjectPool#getMaxTotal()}
* @return See {@link GenericObjectPool#getMaxTotal()}
*/
int getMaxTotal();
/**
* See {@link GenericObjectPool#getMaxWaitMillis()}
* @return See {@link GenericObjectPool#getMaxWaitMillis()}
*/
long getMaxWaitMillis();
/**
* See {@link GenericObjectPool#getMinEvictableIdleTimeMillis()}
* @return See {@link GenericObjectPool#getMinEvictableIdleTimeMillis()}
*/
long getMinEvictableIdleTimeMillis();
/**
* See {@link GenericObjectPool#getMinIdle()}
* @return See {@link GenericObjectPool#getMinIdle()}
*/
int getMinIdle();
/**
* See {@link GenericObjectPool#getNumActive()}
* @return See {@link GenericObjectPool#getNumActive()}
*/
int getNumActive();
/**
* See {@link GenericObjectPool#getNumIdle()}
* @return See {@link GenericObjectPool#getNumIdle()}
*/
int getNumIdle();
/**
* See {@link GenericObjectPool#getNumTestsPerEvictionRun()}
* @return See {@link GenericObjectPool#getNumTestsPerEvictionRun()}
*/
int getNumTestsPerEvictionRun();
/**
* See {@link GenericObjectPool#getTestOnCreate()}
* @return See {@link GenericObjectPool#getTestOnCreate()}
* @since 2.2
*/
boolean getTestOnCreate();
/**
* See {@link GenericObjectPool#getTestOnBorrow()}
* @return See {@link GenericObjectPool#getTestOnBorrow()}
*/
boolean getTestOnBorrow();
/**
* See {@link GenericObjectPool#getTestOnReturn()}
* @return See {@link GenericObjectPool#getTestOnReturn()}
*/
boolean getTestOnReturn();
/**
* See {@link GenericObjectPool#getTestWhileIdle()}
* @return See {@link GenericObjectPool#getTestWhileIdle()}
*/
boolean getTestWhileIdle();
/**
* See {@link GenericObjectPool#getTimeBetweenEvictionRunsMillis()}
* @return See {@link GenericObjectPool#getTimeBetweenEvictionRunsMillis()}
*/
long getTimeBetweenEvictionRunsMillis();
/**
* See {@link GenericObjectPool#isClosed()}
* @return See {@link GenericObjectPool#isClosed()}
*/
boolean isClosed();
// Getters for monitoring attributes
/**
* See {@link GenericObjectPool#getBorrowedCount()}
* @return See {@link GenericObjectPool#getBorrowedCount()}
*/
long getBorrowedCount();
/**
* See {@link GenericObjectPool#getReturnedCount()}
* @return See {@link GenericObjectPool#getReturnedCount()}
*/
long getReturnedCount();
/**
* See {@link GenericObjectPool#getCreatedCount()}
* @return See {@link GenericObjectPool#getCreatedCount()}
*/
long getCreatedCount();
/**
* See {@link GenericObjectPool#getDestroyedCount()}
* @return See {@link GenericObjectPool#getDestroyedCount()}
*/
long getDestroyedCount();
/**
* See {@link GenericObjectPool#getDestroyedByEvictorCount()}
* @return See {@link GenericObjectPool#getDestroyedByEvictorCount()}
*/
long getDestroyedByEvictorCount();
/**
* See {@link GenericObjectPool#getDestroyedByBorrowValidationCount()}
* @return See {@link GenericObjectPool#getDestroyedByBorrowValidationCount()}
*/
long getDestroyedByBorrowValidationCount();
/**
* See {@link GenericObjectPool#getMeanActiveTimeMillis()}
* @return See {@link GenericObjectPool#getMeanActiveTimeMillis()}
*/
long getMeanActiveTimeMillis();
/**
* See {@link GenericObjectPool#getMeanIdleTimeMillis()}
* @return See {@link GenericObjectPool#getMeanIdleTimeMillis()}
*/
long getMeanIdleTimeMillis();
/**
* See {@link GenericObjectPool#getMeanBorrowWaitTimeMillis()}
* @return See {@link GenericObjectPool#getMeanBorrowWaitTimeMillis()}
*/
long getMeanBorrowWaitTimeMillis();
/**
* See {@link GenericObjectPool#getMaxBorrowWaitTimeMillis()}
* @return See {@link GenericObjectPool#getMaxBorrowWaitTimeMillis()}
*/
long getMaxBorrowWaitTimeMillis();
/**
* See {@link GenericObjectPool#getCreationStackTrace()}
* @return See {@link GenericObjectPool#getCreationStackTrace()}
*/
String getCreationStackTrace();
/**
* See {@link GenericObjectPool#getNumWaiters()}
* @return See {@link GenericObjectPool#getNumWaiters()}
*/
int getNumWaiters();
// Getters for abandoned object removal configuration
/**
* See {@link GenericObjectPool#isAbandonedConfig()}
* @return See {@link GenericObjectPool#isAbandonedConfig()}
*/
boolean isAbandonedConfig();
/**
* See {@link GenericObjectPool#getLogAbandoned()}
* @return See {@link GenericObjectPool#getLogAbandoned()}
*/
boolean getLogAbandoned();
/**
* See {@link GenericObjectPool#getRemoveAbandonedOnBorrow()}
* @return See {@link GenericObjectPool#getRemoveAbandonedOnBorrow()}
*/
boolean getRemoveAbandonedOnBorrow();
/**
* See {@link GenericObjectPool#getRemoveAbandonedOnMaintenance()}
* @return See {@link GenericObjectPool#getRemoveAbandonedOnMaintenance()}
*/
boolean getRemoveAbandonedOnMaintenance();
/**
* See {@link GenericObjectPool#getRemoveAbandonedTimeout()}
* @return See {@link GenericObjectPool#getRemoveAbandonedTimeout()}
*/
int getRemoveAbandonedTimeout();
/**
* See {@link GenericObjectPool#getFactoryType()}
* @return See {@link GenericObjectPool#getFactoryType()}
*/
public String getFactoryType();
/**
* See {@link GenericObjectPool#listAllObjects()}
* @return See {@link GenericObjectPool#listAllObjects()}
*/
Set<DefaultPooledObjectInfo> listAllObjects();
}

57
fine-jedis/src/com/fr/third/org/apache/commons/pool2/impl/InterruptibleReentrantLock.java

@ -0,0 +1,57 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 com.fr.third.org.apache.commons.pool2.impl;
import java.util.Collection;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
/**
* This sub-class was created to expose the waiting threads so that they can be
* interrupted when the pool using the queue that uses this lock is closed. The
* class is intended for internal use only.
* <p>
* This class is intended to be thread-safe.
*
* @since 2.0
*/
class InterruptibleReentrantLock extends ReentrantLock {
private static final long serialVersionUID = 1L;
/**
* Create a new InterruptibleReentrantLock with the given fairness policy.
*
* @param fairness true means threads should acquire contended locks as if
* waiting in a FIFO queue
*/
public InterruptibleReentrantLock(final boolean fairness) {
super(fairness);
}
/**
* Interrupt the threads that are waiting on a specific condition
*
* @param condition the condition on which the threads are waiting.
*/
public void interruptWaiters(final Condition condition) {
final Collection<Thread> threads = getWaitingThreads(condition);
for (final Thread thread : threads) {
thread.interrupt();
}
}
}

1425
fine-jedis/src/com/fr/third/org/apache/commons/pool2/impl/LinkedBlockingDeque.java

File diff suppressed because it is too large Load Diff

48
fine-jedis/src/com/fr/third/org/apache/commons/pool2/impl/NoOpCallStack.java

@ -0,0 +1,48 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 com.fr.third.org.apache.commons.pool2.impl;
import java.io.PrintWriter;
/**
* CallStack strategy using no-op implementations of all functionality. Can be used by default when abandoned object
* logging is disabled.
*
* @since 2.5
*/
public class NoOpCallStack implements CallStack {
public static final CallStack INSTANCE = new NoOpCallStack();
private NoOpCallStack() {
}
@Override
public boolean printStackTrace(PrintWriter writer) {
return false;
}
@Override
public void fillInStackTrace() {
// no-op
}
@Override
public void clear() {
// no-op
}
}

126
fine-jedis/src/com/fr/third/org/apache/commons/pool2/impl/PoolImplUtils.java

@ -0,0 +1,126 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 com.fr.third.org.apache.commons.pool2.impl;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import com.fr.third.org.apache.commons.pool2.PooledObjectFactory;
/**
* Implementation specific utilities.
*
* @since 2.0
*/
class PoolImplUtils {
/**
* Identifies the concrete type of object that an object factory creates.
*
* @param factory The factory to examine
*
* @return the type of object the factory creates
*/
@SuppressWarnings("rawtypes")
static Class<?> getFactoryType(final Class<? extends PooledObjectFactory> factory) {
return (Class<?>) getGenericType(PooledObjectFactory.class, factory);
}
/**
* Obtain the concrete type used by an implementation of an interface that
* uses a generic type.
*
* @param type The interface that defines a generic type
* @param clazz The class that implements the interface with a concrete type
* @param <T> The interface type
*
* @return concrete type used by the implementation
*/
private static <T> Object getGenericType(final Class<T> type,
final Class<? extends T> clazz) {
// Look to see if this class implements the generic interface
// Get all the interfaces
final Type[] interfaces = clazz.getGenericInterfaces();
for (final Type iface : interfaces) {
// Only need to check interfaces that use generics
if (iface instanceof ParameterizedType) {
final ParameterizedType pi = (ParameterizedType) iface;
// Look for the generic interface
if (pi.getRawType() instanceof Class) {
if (type.isAssignableFrom((Class<?>) pi.getRawType())) {
return getTypeParameter(
clazz, pi.getActualTypeArguments()[0]);
}
}
}
}
// Interface not found on this class. Look at the superclass.
@SuppressWarnings("unchecked")
final
Class<? extends T> superClazz =
(Class<? extends T>) clazz.getSuperclass();
final Object result = getGenericType(type, superClazz);
if (result instanceof Class<?>) {
// Superclass implements interface and defines explicit type for
// generic
return result;
} else if (result instanceof Integer) {
// Superclass implements interface and defines unknown type for
// generic
// Map that unknown type to the generic types defined in this class
final ParameterizedType superClassType =
(ParameterizedType) clazz.getGenericSuperclass();
return getTypeParameter(clazz,
superClassType.getActualTypeArguments()[
((Integer) result).intValue()]);
} else {
// Error will be logged further up the call stack
return null;
}
}
/**
* For a generic parameter, return either the Class used or if the type
* is unknown, the index for the type in definition of the class
*
* @param clazz defining class
* @param argType the type argument of interest
*
* @return An instance of {@link Class} representing the type used by the
* type parameter or an instance of {@link Integer} representing
* the index for the type in the definition of the defining class
*/
private static Object getTypeParameter(final Class<?> clazz, final Type argType) {
if (argType instanceof Class<?>) {
return argType;
}
final TypeVariable<?>[] tvs = clazz.getTypeParameters();
for (int i = 0; i < tvs.length; i++) {
if (tvs[i].equals(argType)) {
return Integer.valueOf(i);
}
}
return null;
}
}

98
fine-jedis/src/com/fr/third/org/apache/commons/pool2/impl/PooledSoftReference.java

@ -0,0 +1,98 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 com.fr.third.org.apache.commons.pool2.impl;
import java.lang.ref.SoftReference;
/**
* Extension of {@link DefaultPooledObject} to wrap pooled soft references.
*
* <p>This class is intended to be thread-safe.</p>
*
* @param <T> the type of the underlying object that the wrapped SoftReference
* refers to.
*
* @since 2.0
*/
public class PooledSoftReference<T> extends DefaultPooledObject<T> {
/** SoftReference wrapped by this object */
private volatile SoftReference<T> reference;
/**
* Creates a new PooledSoftReference wrapping the provided reference.
*
* @param reference SoftReference to be managed by the pool
*/
public PooledSoftReference(final SoftReference<T> reference) {
super(null); // Null the hard reference in the parent
this.reference = reference;
}
/**
* Returns the object that the wrapped SoftReference refers to.
* <p>
* Note that if the reference has been cleared, this method will return
* null.
*
* @return Object referred to by the SoftReference
*/
@Override
public T getObject() {
return reference.get();
}
/**
* {@inheritDoc}
*/
@Override
public String toString() {
final StringBuilder result = new StringBuilder();
result.append("Referenced Object: ");
result.append(getObject().toString());
result.append(", State: ");
synchronized (this) {
result.append(getState().toString());
}
return result.toString();
// TODO add other attributes
// TODO encapsulate state and other attribute display in parent
}
/**
* Returns the SoftReference wrapped by this object.
*
* @return underlying SoftReference
*/
public synchronized SoftReference<T> getReference() {
return reference;
}
/**
* Sets the wrapped reference.
*
* <p>This method exists to allow a new, non-registered reference to be
* held by the pool to track objects that have been checked out of the pool.
* The actual parameter <strong>should</strong> be a reference to the same
* object that {@link #getObject()} returns before calling this method.</p>
*
* @param reference new reference
*/
public synchronized void setReference(final SoftReference<T> reference) {
this.reference = reference;
}
}

129
fine-jedis/src/com/fr/third/org/apache/commons/pool2/impl/SecurityManagerCallStack.java

@ -0,0 +1,129 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 com.fr.third.org.apache.commons.pool2.impl;
import java.io.PrintWriter;
import java.lang.ref.WeakReference;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
/**
* CallStack strategy using a {@link SecurityManager}. Obtaining the current call stack is much faster via a
* SecurityManger, but access to the underlying method may be restricted by the current SecurityManager. In environments
* where a SecurityManager cannot be created, {@link ThrowableCallStack} should be used instead.
*
* @see RuntimePermission
* @see SecurityManager#getClassContext()
* @since 2.4.3
*/
public class SecurityManagerCallStack implements CallStack {
private final String messageFormat;
//@GuardedBy("dateFormat")
private final DateFormat dateFormat;
private final PrivateSecurityManager securityManager;
private volatile Snapshot snapshot;
/**
* Create a new instance.
*
* @param messageFormat message format
* @param useTimestamp whether to format the dates in the output message or not
*/
public SecurityManagerCallStack(final String messageFormat, final boolean useTimestamp) {
this.messageFormat = messageFormat;
this.dateFormat = useTimestamp ? new SimpleDateFormat(messageFormat) : null;
this.securityManager = AccessController.doPrivileged(new PrivilegedAction<PrivateSecurityManager>() {
@Override
public PrivateSecurityManager run() {
return new PrivateSecurityManager();
}
});
}
@Override
public boolean printStackTrace(final PrintWriter writer) {
final Snapshot snapshotRef = this.snapshot;
if (snapshotRef == null) {
return false;
}
final String message;
if (dateFormat == null) {
message = messageFormat;
} else {
synchronized (dateFormat) {
message = dateFormat.format(Long.valueOf(snapshotRef.timestamp));
}
}
writer.println(message);
for (final WeakReference<Class<?>> reference : snapshotRef.stack) {
writer.println(reference.get());
}
return true;
}
@Override
public void fillInStackTrace() {
snapshot = new Snapshot(securityManager.getCallStack());
}
@Override
public void clear() {
snapshot = null;
}
/**
* A custom security manager.
*/
private static class PrivateSecurityManager extends SecurityManager {
/**
* Get the class stack.
*
* @return class stack
*/
private List<WeakReference<Class<?>>> getCallStack() {
final Class<?>[] classes = getClassContext();
final List<WeakReference<Class<?>>> stack = new ArrayList<WeakReference<Class<?>>>(classes.length);
for (final Class<?> klass : classes) {
stack.add(new WeakReference<Class<?>>(klass));
}
return stack;
}
}
/**
* A snapshot of a class stack.
*/
private static class Snapshot {
private final long timestamp = System.currentTimeMillis();
private final List<WeakReference<Class<?>>> stack;
/**
* Create a new snapshot with a class stack.
*
* @param stack class stack
*/
private Snapshot(final List<WeakReference<Class<?>>> stack) {
this.stack = stack;
}
}
}

453
fine-jedis/src/com/fr/third/org/apache/commons/pool2/impl/SoftReferenceObjectPool.java

@ -0,0 +1,453 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 com.fr.third.org.apache.commons.pool2.impl;
import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.SoftReference;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.NoSuchElementException;
import com.fr.third.org.apache.commons.pool2.BaseObjectPool;
import com.fr.third.org.apache.commons.pool2.ObjectPool;
import com.fr.third.org.apache.commons.pool2.PoolUtils;
import com.fr.third.org.apache.commons.pool2.PooledObjectFactory;
/**
* A {@link SoftReference SoftReference} based {@link ObjectPool}.
* <p>
* This class is intended to be thread-safe.
*
* @param <T>
* Type of element pooled in this pool.
*
* @since 2.0
*/
public class SoftReferenceObjectPool<T> extends BaseObjectPool<T> {
/** Factory to source pooled objects */
private final PooledObjectFactory<T> factory;
/**
* Queue of broken references that might be able to be removed from
* <code>_pool</code>. This is used to help {@link #getNumIdle()} be more
* accurate with minimal performance overhead.
*/
private final ReferenceQueue<T> refQueue = new ReferenceQueue<T>();
/** Count of instances that have been checkout out to pool clients */
private int numActive = 0; // @GuardedBy("this")
/** Total number of instances that have been destroyed */
private long destroyCount = 0; // @GuardedBy("this")
/** Total number of instances that have been created */
private long createCount = 0; // @GuardedBy("this")
/** Idle references - waiting to be borrowed */
private final LinkedBlockingDeque<PooledSoftReference<T>> idleReferences =
new LinkedBlockingDeque<PooledSoftReference<T>>();
/** All references - checked out or waiting to be borrowed. */
private final ArrayList<PooledSoftReference<T>> allReferences =
new ArrayList<PooledSoftReference<T>>();
/**
* Create a <code>SoftReferenceObjectPool</code> with the specified factory.
*
* @param factory object factory to use.
*/
public SoftReferenceObjectPool(final PooledObjectFactory<T> factory) {
this.factory = factory;
}
/**
* Borrow an object from the pool. If there are no idle instances available
* in the pool, the configured factory's
* {@link PooledObjectFactory#makeObject()} method is invoked to create a
* new instance.
* <p>
* All instances are {@link PooledObjectFactory#activateObject(
* org.apache.commons.pool2.PooledObject) activated}
* and {@link PooledObjectFactory#validateObject(
* org.apache.commons.pool2.PooledObject)
* validated} before being returned by this method. If validation fails or
* an exception occurs activating or validating an idle instance, the
* failing instance is {@link PooledObjectFactory#destroyObject(
* org.apache.commons.pool2.PooledObject)
* destroyed} and another instance is retrieved from the pool, validated and
* activated. This process continues until either the pool is empty or an
* instance passes validation. If the pool is empty on activation or it does
* not contain any valid instances, the factory's <code>makeObject</code>
* method is used to create a new instance. If the created instance either
* raises an exception on activation or fails validation,
* <code>NoSuchElementException</code> is thrown. Exceptions thrown by
* <code>MakeObject</code> are propagated to the caller; but other than
* <code>ThreadDeath</code> or <code>VirtualMachineError</code>, exceptions
* generated by activation, validation or destroy methods are swallowed
* silently.
*
* @throws NoSuchElementException
* if a valid object cannot be provided
* @throws IllegalStateException
* if invoked on a {@link #close() closed} pool
* @throws Exception
* if an exception occurs creating a new instance
* @return a valid, activated object instance
*/
@SuppressWarnings("null") // ref cannot be null
@Override
public synchronized T borrowObject() throws Exception {
assertOpen();
T obj = null;
boolean newlyCreated = false;
PooledSoftReference<T> ref = null;
while (null == obj) {
if (idleReferences.isEmpty()) {
if (null == factory) {
throw new NoSuchElementException();
}
newlyCreated = true;
obj = factory.makeObject().getObject();
createCount++;
// Do not register with the queue
ref = new PooledSoftReference<T>(new SoftReference<T>(obj));
allReferences.add(ref);
} else {
ref = idleReferences.pollFirst();
obj = ref.getObject();
// Clear the reference so it will not be queued, but replace with a
// a new, non-registered reference so we can still track this object
// in allReferences
ref.getReference().clear();
ref.setReference(new SoftReference<T>(obj));
}
if (null != factory && null != obj) {
try {
factory.activateObject(ref);
if (!factory.validateObject(ref)) {
throw new Exception("ValidateObject failed");
}
} catch (final Throwable t) {
PoolUtils.checkRethrow(t);
try {
destroy(ref);
} catch (final Throwable t2) {
PoolUtils.checkRethrow(t2);
// Swallowed
} finally {
obj = null;
}
if (newlyCreated) {
throw new NoSuchElementException(
"Could not create a validated object, cause: " +
t.getMessage());
}
}
}
}
numActive++;
ref.allocate();
return obj;
}
/**
* Returns an instance to the pool after successful validation and
* passivation. The returning instance is destroyed if any of the following
* are true:
* <ul>
* <li>the pool is closed</li>
* <li>{@link PooledObjectFactory#validateObject(
* org.apache.commons.pool2.PooledObject) validation} fails
* </li>
* <li>{@link PooledObjectFactory#passivateObject(
* org.apache.commons.pool2.PooledObject) passivation}
* throws an exception</li>
* </ul>
* Exceptions passivating or destroying instances are silently swallowed.
* Exceptions validating instances are propagated to the client.
*
* @param obj
* instance to return to the pool
*/
@Override
public synchronized void returnObject(final T obj) throws Exception {
boolean success = !isClosed();
final PooledSoftReference<T> ref = findReference(obj);
if (ref == null) {
throw new IllegalStateException(
"Returned object not currently part of this pool");
}
if (factory != null) {
if (!factory.validateObject(ref)) {
success = false;
} else {
try {
factory.passivateObject(ref);
} catch (final Exception e) {
success = false;
}
}
}
final boolean shouldDestroy = !success;
numActive--;
if (success) {
// Deallocate and add to the idle instance pool
ref.deallocate();
idleReferences.add(ref);
}
notifyAll(); // numActive has changed
if (shouldDestroy && factory != null) {
try {
destroy(ref);
} catch (final Exception e) {
// ignored
}
}
}
/**
* {@inheritDoc}
*/
@Override
public synchronized void invalidateObject(final T obj) throws Exception {
final PooledSoftReference<T> ref = findReference(obj);
if (ref == null) {
throw new IllegalStateException(
"Object to invalidate is not currently part of this pool");
}
if (factory != null) {
destroy(ref);
}
numActive--;
notifyAll(); // numActive has changed
}
/**
* Create an object, and place it into the pool. addObject() is useful for
* "pre-loading" a pool with idle objects.
* <p>
* Before being added to the pool, the newly created instance is
* {@link PooledObjectFactory#validateObject(
* org.apache.commons.pool2.PooledObject) validated} and
* {@link PooledObjectFactory#passivateObject(
* org.apache.commons.pool2.PooledObject) passivated}. If
* validation fails, the new instance is
* {@link PooledObjectFactory#destroyObject(
* org.apache.commons.pool2.PooledObject) destroyed}. Exceptions
* generated by the factory <code>makeObject</code> or
* <code>passivate</code> are propagated to the caller. Exceptions
* destroying instances are silently swallowed.
*
* @throws IllegalStateException
* if invoked on a {@link #close() closed} pool
* @throws Exception
* when the {@link #getFactory() factory} has a problem creating
* or passivating an object.
*/
@Override
public synchronized void addObject() throws Exception {
assertOpen();
if (factory == null) {
throw new IllegalStateException(
"Cannot add objects without a factory.");
}
final T obj = factory.makeObject().getObject();
createCount++;
// Create and register with the queue
final PooledSoftReference<T> ref = new PooledSoftReference<T>(
new SoftReference<T>(obj, refQueue));
allReferences.add(ref);
boolean success = true;
if (!factory.validateObject(ref)) {
success = false;
} else {
factory.passivateObject(ref);
}
final boolean shouldDestroy = !success;
if (success) {
idleReferences.add(ref);
notifyAll(); // numActive has changed
}
if (shouldDestroy) {
try {
destroy(ref);
} catch (final Exception e) {
// ignored
}
}
}
/**
* Returns an approximation not less than the of the number of idle
* instances in the pool.
*
* @return estimated number of idle instances in the pool
*/
@Override
public synchronized int getNumIdle() {
pruneClearedReferences();
return idleReferences.size();
}
/**
* Return the number of instances currently borrowed from this pool.
*
* @return the number of instances currently borrowed from this pool
*/
@Override
public synchronized int getNumActive() {
return numActive;
}
/**
* Clears any objects sitting idle in the pool.
*/
@Override
public synchronized void clear() {
if (null != factory) {
final Iterator<PooledSoftReference<T>> iter = idleReferences.iterator();
while (iter.hasNext()) {
try {
final PooledSoftReference<T> ref = iter.next();
if (null != ref.getObject()) {
factory.destroyObject(ref);
}
} catch (final Exception e) {
// ignore error, keep destroying the rest
}
}
}
idleReferences.clear();
pruneClearedReferences();
}
/**
* Close this pool, and free any resources associated with it. Invokes
* {@link #clear()} to destroy and remove instances in the pool.
* <p>
* Calling {@link #addObject} or {@link #borrowObject} after invoking this
* method on a pool will cause them to throw an
* {@link IllegalStateException}.
*/
@Override
public void close() {
super.close();
clear();
}
/**
* Returns the {@link PooledObjectFactory} used by this pool to create and
* manage object instances.
*
* @return the factory
*/
public synchronized PooledObjectFactory<T> getFactory() {
return factory;
}
/**
* If any idle objects were garbage collected, remove their
* {@link Reference} wrappers from the idle object pool.
*/
private void pruneClearedReferences() {
// Remove wrappers for enqueued references from idle and allReferences lists
removeClearedReferences(idleReferences.iterator());
removeClearedReferences(allReferences.iterator());
while (refQueue.poll() != null) {
// empty
}
}
/**
* Find the PooledSoftReference in allReferences that points to obj.
*
* @param obj returning object
* @return PooledSoftReference wrapping a soft reference to obj
*/
private PooledSoftReference<T> findReference(final T obj) {
final Iterator<PooledSoftReference<T>> iterator = allReferences.iterator();
while (iterator.hasNext()) {
final PooledSoftReference<T> reference = iterator.next();
if (reference.getObject() != null && reference.getObject().equals(obj)) {
return reference;
}
}
return null;
}
/**
* Destroy a {@code PooledSoftReference} and remove it from the idle and all
* references pools.
*
* @param toDestroy PooledSoftReference to destroy
*
* @throws Exception If an error occurs while trying to destroy the object
*/
private void destroy(final PooledSoftReference<T> toDestroy) throws Exception {
toDestroy.invalidate();
idleReferences.remove(toDestroy);
allReferences.remove(toDestroy);
try {
factory.destroyObject(toDestroy);
} finally {
destroyCount++;
toDestroy.getReference().clear();
}
}
/**
* Clears cleared references from iterator's collection
* @param iterator iterator over idle/allReferences
*/
private void removeClearedReferences(final Iterator<PooledSoftReference<T>> iterator) {
PooledSoftReference<T> ref;
while (iterator.hasNext()) {
ref = iterator.next();
if (ref.getReference() == null || ref.getReference().isEnqueued()) {
iterator.remove();
}
}
}
@Override
protected void toStringAppendFields(final StringBuilder builder) {
super.toStringAppendFields(builder);
builder.append(", factory=");
builder.append(factory);
builder.append(", refQueue=");
builder.append(refQueue);
builder.append(", numActive=");
builder.append(numActive);
builder.append(", destroyCount=");
builder.append(destroyCount);
builder.append(", createCount=");
builder.append(createCount);
builder.append(", idleReferences=");
builder.append(idleReferences);
builder.append(", allReferences=");
builder.append(allReferences);
}
}

86
fine-jedis/src/com/fr/third/org/apache/commons/pool2/impl/ThrowableCallStack.java

@ -0,0 +1,86 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 com.fr.third.org.apache.commons.pool2.impl;
import java.io.PrintWriter;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
/**
* CallStack strategy that uses the stack trace from a {@link Throwable}. This strategy, while slower than the
* SecurityManager implementation, provides call stack method names and other metadata in addition to the call stack
* of classes.
*
* @see Throwable#fillInStackTrace()
* @since 2.4.3
*/
public class ThrowableCallStack implements CallStack {
private final String messageFormat;
//@GuardedBy("dateFormat")
private final DateFormat dateFormat;
private volatile Snapshot snapshot;
/**
* Create a new instance.
*
* @param messageFormat message format
* @param useTimestamp whether to format the dates in the output message or not
*/
public ThrowableCallStack(final String messageFormat, final boolean useTimestamp) {
this.messageFormat = messageFormat;
this.dateFormat = useTimestamp ? new SimpleDateFormat(messageFormat) : null;
}
@Override
public synchronized boolean printStackTrace(final PrintWriter writer) {
final Snapshot snapshotRef = this.snapshot;
if (snapshotRef == null) {
return false;
}
final String message;
if (dateFormat == null) {
message = messageFormat;
} else {
synchronized (dateFormat) {
message = dateFormat.format(Long.valueOf(snapshotRef.timestamp));
}
}
writer.println(message);
snapshotRef.printStackTrace(writer);
return true;
}
@Override
public void fillInStackTrace() {
snapshot = new Snapshot();
}
@Override
public void clear() {
snapshot = null;
}
/**
* A snapshot of a throwable.
*/
private static class Snapshot extends Throwable {
private static final long serialVersionUID = 1L;
private final long timestamp = System.currentTimeMillis();
}
}

42
fine-jedis/src/com/fr/third/org/apache/commons/pool2/impl/package.html

@ -0,0 +1,42 @@
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You 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.
-->
<!-- $Id$ -->
<html>
<head>
<title>Package Documentation for org.apache.commons.pool2.impl</title>
</head>
<body>
<p>
Object pooling API implementations.
</p>
<p>
{@link org.apache.commons.pool2.impl.GenericObjectPool GenericObjectPool}
({@link org.apache.commons.pool2.impl.GenericKeyedObjectPool GenericKeyedObjectPool})
provides a more robust (but also more complicated)
implementation of {@link org.apache.commons.pool2.ObjectPool ObjectPool}
({@link org.apache.commons.pool2.KeyedObjectPool KeyedObjectPool}).
</p>
<p>
{@link org.apache.commons.pool2.impl.SoftReferenceObjectPool SoftReferenceObjectPool}
provides a {@link java.lang.ref.SoftReference SoftReference} based
{@link org.apache.commons.pool2.ObjectPool ObjectPool}.
</p>
<p>
See also the {@link org.apache.commons.pool2} package.
</p>
</body>
</html>

50
fine-jedis/src/com/fr/third/org/apache/commons/pool2/overview.html

@ -0,0 +1,50 @@
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You 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.
-->
<!-- $Id$ -->
<html>
<head>
<title>Overview of the org.apache.commons.pool2 component</title>
</head>
<body>
<p>
Generic Object pooling API with several implementations.
</p>
<p>
The <code>org.apache.commons.pool2</code> package defines a simple
interface for a pool of object instances, and a handful of base
classes that may be useful when creating pool implementations.
The API supports pooling of unique objects which can be requested
via a key as well as pools where all objects are equivalent.
</p>
<p>
The <code>org.apache.commons.pool2.impl</code> package contains
several pool implementations.
{@link org.apache.commons.pool2.impl.GenericObjectPool
GenericObjectPool} has many configuration options and can support
a limited set of objects such as would be useful in a database
connection pool.
{@link org.apache.commons.pool2.impl.SoftReferenceObjectPool
SoftReferenceObjectPool} has no limit on the number of objects in the
pool, but the garbage collector can remove idle objects from the pool
as needed. There is also a keyed version of
{@link org.apache.commons.pool2.impl.GenericObjectPool
GenericObjectPool},
{@link org.apache.commons.pool2.impl.GenericKeyedObjectPool
GenericKeyedObjectPool}
</p>
</body>
</html>

63
fine-jedis/src/com/fr/third/org/apache/commons/pool2/package.html

@ -0,0 +1,63 @@
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You 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.
-->
<!-- $Id$ -->
<html>
<head>
<title>Package Documentation for org.apache.commons.pool2</title>
</head>
<body>
<p>
Object pooling API.
</p>
<p>
The <code>org.apache.commons.pool2</code> package defines a simple
interface for a pool of object instances, and a handful of base
classes that may be useful when creating pool implementations.
</p>
<p>
The <code>pool</code> package itself doesn't define a specific object
pooling implementation, but rather a contract that implementations may
support in order to be fully interchangeable.
</p>
<p>
The <code>pool</code> package separates the way in which instances are
pooled from the way in which they are created, resulting in a pair of
interfaces:
</p>
<dl>
<dt>{@link org.apache.commons.pool2.ObjectPool ObjectPool}</dt>
<dd>
defines a simple object pooling interface, with methods for
borrowing instances from and returning them to the pool.
</dd>
<dt>{@link org.apache.commons.pool2.PooledObjectFactory PooledObjectFactory}</dt>
<dd>
defines lifecycle methods for object instances contained within a pool.
By associating a factory with a pool, the pool can create new object
instances as needed.
</dd>
</dl>
<p>
The <code>pool</code> package also provides a keyed pool interface,
which pools instances of multiple types, accessed according to an
arbitrary key. See
{@link org.apache.commons.pool2.KeyedObjectPool KeyedObjectPool} and
{@link org.apache.commons.pool2.KeyedPooledObjectFactory
KeyedPooledObjectFactory}.
</p>
</body>
</html>

121
fine-jedis/src/com/fr/third/org/apache/commons/pool2/proxy/BaseProxyHandler.java

@ -0,0 +1,121 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 com.fr.third.org.apache.commons.pool2.proxy;
import java.lang.reflect.Method;
import com.fr.third.org.apache.commons.pool2.UsageTracking;
/**
* Base implementation for object wrappers when using a
* {@link ProxiedObjectPool}.
*
* @param <T> type of the wrapped pooled object
*
* @since 2.0
*/
class BaseProxyHandler<T> {
private volatile T pooledObject;
private final UsageTracking<T> usageTracking;
/**
* Create a new wrapper for the given pooled object.
*
* @param pooledObject The object to wrap
* @param usageTracking The instance, if any (usually the object pool) to
* be provided with usage tracking information for this
* wrapped object
*/
BaseProxyHandler(final T pooledObject, final UsageTracking<T> usageTracking) {
this.pooledObject = pooledObject;
this.usageTracking = usageTracking;
}
/**
* Obtain the wrapped, pooled object.
*
* @return the underlying pooled object
*/
T getPooledObject() {
return pooledObject;
}
/**
* Disable the proxy wrapper. Called when the object has been returned to
* the pool. Further use of the wrapper should result in an
* {@link IllegalStateException}.
*
* @return the object that this proxy was wrapping
*/
T disableProxy() {
final T result = pooledObject;
pooledObject = null;
return result;
}
/**
* Check that the proxy is still valid (i.e. that {@link #disableProxy()}
* has not been called).
*
* @throws IllegalStateException if {@link #disableProxy()} has been called
*/
void validateProxiedObject() {
if (pooledObject == null) {
throw new IllegalStateException("This object may no longer be " +
"used as it has been returned to the Object Pool.");
}
}
/**
* Invoke the given method on the wrapped object.
*
* @param method The method to invoke
* @param args The arguments to the method
* @return The result of the method call
* @throws Throwable If the method invocation fails
*/
Object doInvoke(final Method method, final Object[] args) throws Throwable {
validateProxiedObject();
final T object = getPooledObject();
if (usageTracking != null) {
usageTracking.use(object);
}
return method.invoke(object, args);
}
/**
* @since 2.4.3
*/
@Override
public String toString() {
final StringBuilder builder = new StringBuilder();
builder.append(getClass().getName());
builder.append(" [pooledObject=");
builder.append(pooledObject);
builder.append(", usageTracking=");
builder.append(usageTracking);
builder.append("]");
return builder.toString();
}
}

54
fine-jedis/src/com/fr/third/org/apache/commons/pool2/proxy/CglibProxyHandler.java

@ -0,0 +1,54 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 com.fr.third.org.apache.commons.pool2.proxy;
import java.lang.reflect.Method;
import com.fr.third.org.apache.commons.pool2.UsageTracking;
import com.fr.third.net.sf.cglib.proxy.MethodInterceptor;
import com.fr.third.net.sf.cglib.proxy.MethodProxy;
/**
* CGLib implementation of the proxy handler.
*
* @param <T> type of the wrapped pooled object
*
* @since 2.0
*/
class CglibProxyHandler<T> extends BaseProxyHandler<T>
implements MethodInterceptor {
/**
* Create a CGLib proxy instance.
*
* @param pooledObject The object to wrap
* @param usageTracking The instance, if any (usually the object pool) to
* be provided with usage tracking information for this
* wrapped object
*/
CglibProxyHandler(final T pooledObject, final UsageTracking<T> usageTracking) {
super(pooledObject, usageTracking);
}
@Override
public Object intercept(final Object object, final Method method, final Object[] args,
final MethodProxy methodProxy) throws Throwable {
return doInvoke(method, args);
}
}

82
fine-jedis/src/com/fr/third/org/apache/commons/pool2/proxy/CglibProxySource.java

@ -0,0 +1,82 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 com.fr.third.org.apache.commons.pool2.proxy;
import com.fr.third.net.sf.cglib.proxy.Enhancer;
import com.fr.third.net.sf.cglib.proxy.Factory;
import com.fr.third.org.apache.commons.pool2.UsageTracking;
/**
* Provides proxy objects using CGLib.
*
* @param <T> type of the pooled object to be proxied
*
* @since 2.0
*/
public class CglibProxySource<T> implements ProxySource<T> {
private final Class<? extends T> superclass;
/**
* Create a new proxy source for the given class.
*
* @param superclass The class to proxy
*/
public CglibProxySource(final Class<? extends T> superclass) {
this.superclass = superclass;
}
@Override
public T createProxy(final T pooledObject, final UsageTracking<T> usageTracking) {
final Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(superclass);
final CglibProxyHandler<T> proxyInterceptor =
new CglibProxyHandler<T>(pooledObject, usageTracking);
enhancer.setCallback(proxyInterceptor);
@SuppressWarnings("unchecked")
final
T proxy = (T) enhancer.create();
return proxy;
}
@Override
public T resolveProxy(final T proxy) {
@SuppressWarnings("unchecked")
final
CglibProxyHandler<T> cglibProxyHandler =
(CglibProxyHandler<T>) ((Factory) proxy).getCallback(0);
final T pooledObject = cglibProxyHandler.disableProxy();
return pooledObject;
}
/**
* @since 2.4.3
*/
@Override
public String toString() {
final StringBuilder builder = new StringBuilder();
builder.append("CglibProxySource [superclass=");
builder.append(superclass);
builder.append("]");
return builder.toString();
}
}

53
fine-jedis/src/com/fr/third/org/apache/commons/pool2/proxy/JdkProxyHandler.java

@ -0,0 +1,53 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 com.fr.third.org.apache.commons.pool2.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import com.fr.third.org.apache.commons.pool2.UsageTracking;
/**
* Java reflection implementation of the proxy handler.
*
* @param <T> type of the wrapped pooled object
*
* @since 2.0
*/
class JdkProxyHandler<T> extends BaseProxyHandler<T>
implements InvocationHandler {
/**
* Create a Java reflection proxy instance.
*
* @param pooledObject The object to wrap
* @param usageTracking The instance, if any (usually the object pool) to
* be provided with usage tracking information for this
* wrapped object
*/
JdkProxyHandler(final T pooledObject, final UsageTracking<T> usageTracking) {
super(pooledObject, usageTracking);
}
@Override
public Object invoke(final Object proxy, final Method method, final Object[] args)
throws Throwable {
return doInvoke(method, args);
}
}

85
fine-jedis/src/com/fr/third/org/apache/commons/pool2/proxy/JdkProxySource.java

@ -0,0 +1,85 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 com.fr.third.org.apache.commons.pool2.proxy;
import java.lang.reflect.Proxy;
import java.util.Arrays;
import com.fr.third.org.apache.commons.pool2.UsageTracking;
/**
* Provides proxy objects using Java reflection.
*
* @param <T> type of the pooled object to be proxied
*
* @since 2.0
*/
public class JdkProxySource<T> implements ProxySource<T> {
private final ClassLoader classLoader;
private final Class<?>[] interfaces;
/**
* Create a new proxy source for the given interfaces.
*
* @param classLoader The class loader with which to create the proxy
* @param interfaces The interfaces to proxy
*/
public JdkProxySource(final ClassLoader classLoader, final Class<?>[] interfaces) {
this.classLoader = classLoader;
// Defensive copy
this.interfaces = new Class<?>[interfaces.length];
System.arraycopy(interfaces, 0, this.interfaces, 0, interfaces.length);
}
@Override
public T createProxy(final T pooledObject, final UsageTracking<T> usageTracking) {
@SuppressWarnings("unchecked")
final
T proxy = (T) Proxy.newProxyInstance(classLoader, interfaces,
new JdkProxyHandler<T>(pooledObject, usageTracking));
return proxy;
}
@Override
public T resolveProxy(final T proxy) {
@SuppressWarnings("unchecked")
final
JdkProxyHandler<T> jdkProxyHandler =
(JdkProxyHandler<T>) Proxy.getInvocationHandler(proxy);
final T pooledObject = jdkProxyHandler.disableProxy();
return pooledObject;
}
/**
* @since 2.4.3
*/
@Override
public String toString() {
final StringBuilder builder = new StringBuilder();
builder.append("JdkProxySource [classLoader=");
builder.append(classLoader);
builder.append(", interfaces=");
builder.append(Arrays.toString(interfaces));
builder.append("]");
return builder.toString();
}
}

134
fine-jedis/src/com/fr/third/org/apache/commons/pool2/proxy/ProxiedKeyedObjectPool.java

@ -0,0 +1,134 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 com.fr.third.org.apache.commons.pool2.proxy;
import java.util.NoSuchElementException;
import com.fr.third.org.apache.commons.pool2.KeyedObjectPool;
import com.fr.third.org.apache.commons.pool2.UsageTracking;
/**
* Create a new keyed object pool where the pooled objects are wrapped in
* proxies allowing better control of pooled objects and in particular the
* prevention of the continued use of an object by a client after that client
* returns the object to the pool.
*
* @param <K> type of the key
* @param <V> type of the pooled object
*
* @since 2.0
*/
public class ProxiedKeyedObjectPool<K,V> implements KeyedObjectPool<K,V> {
private final KeyedObjectPool<K,V> pool;
private final ProxySource<V> proxySource;
/**
* Create a new proxied object pool.
*
* @param pool The object pool to wrap
* @param proxySource The source of the proxy objects
*/
public ProxiedKeyedObjectPool(final KeyedObjectPool<K,V> pool,
final ProxySource<V> proxySource) {
this.pool = pool;
this.proxySource = proxySource;
}
@SuppressWarnings("unchecked")
@Override
public V borrowObject(final K key) throws Exception, NoSuchElementException,
IllegalStateException {
UsageTracking<V> usageTracking = null;
if (pool instanceof UsageTracking) {
usageTracking = (UsageTracking<V>) pool;
}
final V pooledObject = pool.borrowObject(key);
final V proxy = proxySource.createProxy(pooledObject, usageTracking);
return proxy;
}
@Override
public void returnObject(final K key, final V proxy) throws Exception {
final V pooledObject = proxySource.resolveProxy(proxy);
pool.returnObject(key, pooledObject);
}
@Override
public void invalidateObject(final K key, final V proxy) throws Exception {
final V pooledObject = proxySource.resolveProxy(proxy);
pool.invalidateObject(key, pooledObject);
}
@Override
public void addObject(final K key) throws Exception, IllegalStateException,
UnsupportedOperationException {
pool.addObject(key);
}
@Override
public int getNumIdle(final K key) {
return pool.getNumIdle(key);
}
@Override
public int getNumActive(final K key) {
return pool.getNumActive(key);
}
@Override
public int getNumIdle() {
return pool.getNumIdle();
}
@Override
public int getNumActive() {
return pool.getNumActive();
}
@Override
public void clear() throws Exception, UnsupportedOperationException {
pool.clear();
}
@Override
public void clear(final K key) throws Exception, UnsupportedOperationException {
pool.clear(key);
}
@Override
public void close() {
pool.close();
}
/**
* @since 2.4.3
*/
@Override
public String toString() {
final StringBuilder builder = new StringBuilder();
builder.append("ProxiedKeyedObjectPool [pool=");
builder.append(pool);
builder.append(", proxySource=");
builder.append(proxySource);
builder.append("]");
return builder.toString();
}
}

126
fine-jedis/src/com/fr/third/org/apache/commons/pool2/proxy/ProxiedObjectPool.java

@ -0,0 +1,126 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 com.fr.third.org.apache.commons.pool2.proxy;
import java.util.NoSuchElementException;
import com.fr.third.org.apache.commons.pool2.ObjectPool;
import com.fr.third.org.apache.commons.pool2.UsageTracking;
/**
* Create a new object pool where the pooled objects are wrapped in proxies
* allowing better control of pooled objects and in particular the prevention
* of the continued use of an object by a client after that client returns the
* object to the pool.
*
* @param <T> type of the pooled object
*
* @since 2.0
*/
public class ProxiedObjectPool<T> implements ObjectPool<T> {
private final ObjectPool<T> pool;
private final ProxySource<T> proxySource;
/**
* Create a new proxied object pool.
*
* @param pool The object pool to wrap
* @param proxySource The source of the proxy objects
*/
public ProxiedObjectPool(final ObjectPool<T> pool, final ProxySource<T> proxySource) {
this.pool = pool;
this.proxySource = proxySource;
}
// --------------------------------------------------- ObjectPool<T> methods
@SuppressWarnings("unchecked")
@Override
public T borrowObject() throws Exception, NoSuchElementException,
IllegalStateException {
UsageTracking<T> usageTracking = null;
if (pool instanceof UsageTracking) {
usageTracking = (UsageTracking<T>) pool;
}
final T pooledObject = pool.borrowObject();
final T proxy = proxySource.createProxy(pooledObject, usageTracking);
return proxy;
}
@Override
public void returnObject(final T proxy) throws Exception {
final T pooledObject = proxySource.resolveProxy(proxy);
pool.returnObject(pooledObject);
}
@Override
public void invalidateObject(final T proxy) throws Exception {
final T pooledObject = proxySource.resolveProxy(proxy);
pool.invalidateObject(pooledObject);
}
@Override
public void addObject() throws Exception, IllegalStateException,
UnsupportedOperationException {
pool.addObject();
}
@Override
public int getNumIdle() {
return pool.getNumIdle();
}
@Override
public int getNumActive() {
return pool.getNumActive();
}
@Override
public void clear() throws Exception, UnsupportedOperationException {
pool.clear();
}
@Override
public void close() {
pool.close();
}
/**
* @since 2.4.3
*/
@Override
public String toString() {
final StringBuilder builder = new StringBuilder();
builder.append("ProxiedObjectPool [pool=");
builder.append(pool);
builder.append(", proxySource=");
builder.append(proxySource);
builder.append("]");
return builder.toString();
}
}

51
fine-jedis/src/com/fr/third/org/apache/commons/pool2/proxy/ProxySource.java

@ -0,0 +1,51 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 com.fr.third.org.apache.commons.pool2.proxy;
import com.fr.third.org.apache.commons.pool2.UsageTracking;
/**
* The interface that any provider of proxy instances must implement to allow the
* {@link ProxiedObjectPool} to create proxies as required.
*
* @param <T> type of the pooled object to be proxied
*
* @since 2.0
*/
interface ProxySource<T> {
/**
* Create a new proxy object, wrapping the given pooled object.
*
* @param pooledObject The object to wrap
* @param usageTracking The instance, if any (usually the object pool) to
* be provided with usage tracking information for this
* wrapped object
*
* @return the new proxy object
*/
T createProxy(T pooledObject, UsageTracking<T> usageTracking);
/**
* Obtain the wrapped object from the given proxy.
*
* @param proxy The proxy object
*
* @return The pooled object wrapped by the given proxy
*/
T resolveProxy(T proxy);
}

37
fine-jedis/src/com/fr/third/org/apache/commons/pool2/proxy/package.html

@ -0,0 +1,37 @@
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You 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.
-->
<html>
<head>
<title>Package Documentation for org.apache.commons.pool2.proxy</title>
</head>
<body>
<p>
Object pooling proxy implementation.
</p>
<p>
The <code>org.apache.commons.pool2.proxy</code> package defines a
object pool that wraps all objects returned to clients. This allows it
to disable those proxies when the objects are returned thereby enabling
the continued use of those objects by clients to be detected..
</p>
<p>
Support is provided for <code>java.lang.reflect.Proxy</code> and for
<code>net.sf.cglib.proxy</code> based proxies. The latter, requires the
additional of the optional Code Generation Library (GCLib).
</p>
</body>
</html>

1205
fine-jedis/src/com/fr/third/redis/clients/jedis/BinaryClient.java

File diff suppressed because it is too large Load Diff

3850
fine-jedis/src/com/fr/third/redis/clients/jedis/BinaryJedis.java

File diff suppressed because it is too large Load Diff

1977
fine-jedis/src/com/fr/third/redis/clients/jedis/BinaryJedisCluster.java

File diff suppressed because it is too large Load Diff

127
fine-jedis/src/com/fr/third/redis/clients/jedis/BinaryJedisPubSub.java

@ -0,0 +1,127 @@
package com.fr.third.redis.clients.jedis;
import static com.fr.third.redis.clients.jedis.Protocol.Keyword.MESSAGE;
import static com.fr.third.redis.clients.jedis.Protocol.Keyword.PMESSAGE;
import static com.fr.third.redis.clients.jedis.Protocol.Keyword.PSUBSCRIBE;
import static com.fr.third.redis.clients.jedis.Protocol.Keyword.PUNSUBSCRIBE;
import static com.fr.third.redis.clients.jedis.Protocol.Keyword.SUBSCRIBE;
import static com.fr.third.redis.clients.jedis.Protocol.Keyword.UNSUBSCRIBE;
import java.util.Arrays;
import java.util.List;
import com.fr.third.redis.clients.jedis.exceptions.JedisException;
public abstract class BinaryJedisPubSub {
private int subscribedChannels = 0;
private Client client;
public void onMessage(byte[] channel, byte[] message) {
}
public void onPMessage(byte[] pattern, byte[] channel, byte[] message) {
}
public void onSubscribe(byte[] channel, int subscribedChannels) {
}
public void onUnsubscribe(byte[] channel, int subscribedChannels) {
}
public void onPUnsubscribe(byte[] pattern, int subscribedChannels) {
}
public void onPSubscribe(byte[] pattern, int subscribedChannels) {
}
public void unsubscribe() {
client.unsubscribe();
client.flush();
}
public void unsubscribe(byte[]... channels) {
client.unsubscribe(channels);
client.flush();
}
public void subscribe(byte[]... channels) {
client.subscribe(channels);
client.flush();
}
public void psubscribe(byte[]... patterns) {
client.psubscribe(patterns);
client.flush();
}
public void punsubscribe() {
client.punsubscribe();
client.flush();
}
public void punsubscribe(byte[]... patterns) {
client.punsubscribe(patterns);
client.flush();
}
public boolean isSubscribed() {
return subscribedChannels > 0;
}
public void proceedWithPatterns(Client client, byte[]... patterns) {
this.client = client;
client.psubscribe(patterns);
client.flush();
process(client);
}
public void proceed(Client client, byte[]... channels) {
this.client = client;
client.subscribe(channels);
client.flush();
process(client);
}
private void process(Client client) {
do {
List<Object> reply = client.getRawObjectMultiBulkReply();
final Object firstObj = reply.get(0);
if (!(firstObj instanceof byte[])) {
throw new JedisException("Unknown message type: " + firstObj);
}
final byte[] resp = (byte[]) firstObj;
if (Arrays.equals(SUBSCRIBE.raw, resp)) {
subscribedChannels = ((Long) reply.get(2)).intValue();
final byte[] bchannel = (byte[]) reply.get(1);
onSubscribe(bchannel, subscribedChannels);
} else if (Arrays.equals(UNSUBSCRIBE.raw, resp)) {
subscribedChannels = ((Long) reply.get(2)).intValue();
final byte[] bchannel = (byte[]) reply.get(1);
onUnsubscribe(bchannel, subscribedChannels);
} else if (Arrays.equals(MESSAGE.raw, resp)) {
final byte[] bchannel = (byte[]) reply.get(1);
final byte[] bmesg = (byte[]) reply.get(2);
onMessage(bchannel, bmesg);
} else if (Arrays.equals(PMESSAGE.raw, resp)) {
final byte[] bpattern = (byte[]) reply.get(1);
final byte[] bchannel = (byte[]) reply.get(2);
final byte[] bmesg = (byte[]) reply.get(3);
onPMessage(bpattern, bchannel, bmesg);
} else if (Arrays.equals(PSUBSCRIBE.raw, resp)) {
subscribedChannels = ((Long) reply.get(2)).intValue();
final byte[] bpattern = (byte[]) reply.get(1);
onPSubscribe(bpattern, subscribedChannels);
} else if (Arrays.equals(PUNSUBSCRIBE.raw, resp)) {
subscribedChannels = ((Long) reply.get(2)).intValue();
final byte[] bpattern = (byte[]) reply.get(1);
onPUnsubscribe(bpattern, subscribedChannels);
} else {
throw new JedisException("Unknown message type: " + firstObj);
}
} while (isSubscribed());
}
public int getSubscribedChannels() {
return subscribedChannels;
}
}

925
fine-jedis/src/com/fr/third/redis/clients/jedis/BinaryShardedJedis.java

@ -0,0 +1,925 @@
package com.fr.third.redis.clients.jedis;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Pattern;
import com.fr.third.redis.clients.jedis.commands.BinaryJedisCommands;
import com.fr.third.redis.clients.jedis.exceptions.JedisConnectionException;
import com.fr.third.redis.clients.jedis.params.GeoRadiusParam;
import com.fr.third.redis.clients.jedis.params.SetParams;
import com.fr.third.redis.clients.jedis.params.ZAddParams;
import com.fr.third.redis.clients.jedis.params.ZIncrByParams;
import com.fr.third.redis.clients.jedis.util.Hashing;
import com.fr.third.redis.clients.jedis.util.Sharded;
public class BinaryShardedJedis extends Sharded<Jedis, JedisShardInfo> implements
BinaryJedisCommands {
public BinaryShardedJedis(List<JedisShardInfo> shards) {
super(shards);
}
public BinaryShardedJedis(List<JedisShardInfo> shards, Hashing algo) {
super(shards, algo);
}
public BinaryShardedJedis(List<JedisShardInfo> shards, Pattern keyTagPattern) {
super(shards, keyTagPattern);
}
public BinaryShardedJedis(List<JedisShardInfo> shards, Hashing algo, Pattern keyTagPattern) {
super(shards, algo, keyTagPattern);
}
public void disconnect() {
for (Jedis jedis : getAllShards()) {
if (jedis.isConnected()) {
try {
jedis.quit();
} catch (JedisConnectionException e) {
// ignore the exception node, so that all other normal nodes can release all connections.
}
try {
jedis.disconnect();
} catch (JedisConnectionException e) {
// ignore the exception node, so that all other normal nodes can release all connections.
}
}
}
}
protected Jedis create(JedisShardInfo shard) {
return new Jedis(shard);
}
@Override
public String set(final byte[] key, final byte[] value) {
Jedis j = getShard(key);
return j.set(key, value);
}
@Override
public String set(final byte[] key, final byte[] value, SetParams params) {
Jedis j = getShard(key);
return j.set(key, value, params);
}
@Override
public byte[] get(final byte[] key) {
Jedis j = getShard(key);
return j.get(key);
}
@Override
public Boolean exists(final byte[] key) {
Jedis j = getShard(key);
return j.exists(key);
}
@Override
public String type(final byte[] key) {
Jedis j = getShard(key);
return j.type(key);
}
@Override
public byte[] dump(final byte[] key) {
Jedis j = getShard(key);
return j.dump(key);
}
@Override
public String restore(final byte[] key, final int ttl, final byte[] serializedValue) {
Jedis j = getShard(key);
return j.restore(key, ttl, serializedValue);
}
@Override
public Long expire(final byte[] key, final int seconds) {
Jedis j = getShard(key);
return j.expire(key, seconds);
}
@Override
public Long pexpire(final byte[] key, final long milliseconds) {
Jedis j = getShard(key);
return j.pexpire(key, milliseconds);
}
@Override
public Long expireAt(final byte[] key, final long unixTime) {
Jedis j = getShard(key);
return j.expireAt(key, unixTime);
}
@Override
public Long pexpireAt(final byte[] key, final long millisecondsTimestamp) {
Jedis j = getShard(key);
return j.pexpireAt(key, millisecondsTimestamp);
}
@Override
public Long ttl(final byte[] key) {
Jedis j = getShard(key);
return j.ttl(key);
}
@Override
public Long pttl(final byte[] key) {
Jedis j = getShard(key);
return j.pttl(key);
}
@Override
public Long touch(final byte[] key) {
Jedis j = getShard(key);
return j.touch(key);
}
@Override
public byte[] getSet(final byte[] key, final byte[] value) {
Jedis j = getShard(key);
return j.getSet(key, value);
}
@Override
public Long setnx(final byte[] key, final byte[] value) {
Jedis j = getShard(key);
return j.setnx(key, value);
}
@Override
public String setex(final byte[] key, final int seconds, final byte[] value) {
Jedis j = getShard(key);
return j.setex(key, seconds, value);
}
@Override
public String psetex(final byte[] key, final long milliseconds, final byte[] value) {
Jedis j = getShard(key);
return j.psetex(key, milliseconds, value);
}
@Override
public Long decrBy(final byte[] key, final long decrement) {
Jedis j = getShard(key);
return j.decrBy(key, decrement);
}
@Override
public Long decr(final byte[] key) {
Jedis j = getShard(key);
return j.decr(key);
}
@Override
public Long del(final byte[] key) {
Jedis j = getShard(key);
return j.del(key);
}
@Override
public Long unlink(final byte[] key) {
Jedis j = getShard(key);
return j.unlink(key);
}
@Override
public Long incrBy(final byte[] key, final long increment) {
Jedis j = getShard(key);
return j.incrBy(key, increment);
}
@Override
public Double incrByFloat(final byte[] key, final double increment) {
Jedis j = getShard(key);
return j.incrByFloat(key, increment);
}
@Override
public Long incr(final byte[] key) {
Jedis j = getShard(key);
return j.incr(key);
}
@Override
public Long append(final byte[] key, final byte[] value) {
Jedis j = getShard(key);
return j.append(key, value);
}
@Override
public byte[] substr(final byte[] key, final int start, final int end) {
Jedis j = getShard(key);
return j.substr(key, start, end);
}
@Override
public Long hset(final byte[] key, final byte[] field, final byte[] value) {
Jedis j = getShard(key);
return j.hset(key, field, value);
}
@Override
public Long hset(final byte[] key, final Map<byte[], byte[]> hash) {
Jedis j = getShard(key);
return j.hset(key, hash);
}
@Override
public byte[] hget(final byte[] key, final byte[] field) {
Jedis j = getShard(key);
return j.hget(key, field);
}
@Override
public Long hsetnx(final byte[] key, final byte[] field, final byte[] value) {
Jedis j = getShard(key);
return j.hsetnx(key, field, value);
}
@Override
public String hmset(final byte[] key, final Map<byte[], byte[]> hash) {
Jedis j = getShard(key);
return j.hmset(key, hash);
}
@Override
public List<byte[]> hmget(final byte[] key, final byte[]... fields) {
Jedis j = getShard(key);
return j.hmget(key, fields);
}
@Override
public Long hincrBy(final byte[] key, final byte[] field, final long value) {
Jedis j = getShard(key);
return j.hincrBy(key, field, value);
}
@Override
public Double hincrByFloat(final byte[] key, final byte[] field, final double value) {
Jedis j = getShard(key);
return j.hincrByFloat(key, field, value);
}
@Override
public Boolean hexists(final byte[] key, final byte[] field) {
Jedis j = getShard(key);
return j.hexists(key, field);
}
@Override
public Long hdel(final byte[] key, final byte[]... fields) {
Jedis j = getShard(key);
return j.hdel(key, fields);
}
@Override
public Long hlen(final byte[] key) {
Jedis j = getShard(key);
return j.hlen(key);
}
@Override
public Set<byte[]> hkeys(final byte[] key) {
Jedis j = getShard(key);
return j.hkeys(key);
}
@Override
public Collection<byte[]> hvals(final byte[] key) {
Jedis j = getShard(key);
return j.hvals(key);
}
@Override
public Map<byte[], byte[]> hgetAll(final byte[] key) {
Jedis j = getShard(key);
return j.hgetAll(key);
}
@Override
public Long rpush(final byte[] key, final byte[]... strings) {
Jedis j = getShard(key);
return j.rpush(key, strings);
}
@Override
public Long lpush(final byte[] key, final byte[]... strings) {
Jedis j = getShard(key);
return j.lpush(key, strings);
}
@Override
public Long strlen(final byte[] key) {
Jedis j = getShard(key);
return j.strlen(key);
}
@Override
public Long lpushx(final byte[] key, final byte[]... string) {
Jedis j = getShard(key);
return j.lpushx(key, string);
}
@Override
public Long persist(final byte[] key) {
Jedis j = getShard(key);
return j.persist(key);
}
@Override
public Long rpushx(final byte[] key, final byte[]... string) {
Jedis j = getShard(key);
return j.rpushx(key, string);
}
@Override
public Long llen(final byte[] key) {
Jedis j = getShard(key);
return j.llen(key);
}
@Override
public List<byte[]> lrange(final byte[] key, final long start, final long stop) {
Jedis j = getShard(key);
return j.lrange(key, start, stop);
}
@Override
public String ltrim(final byte[] key, final long start, final long stop) {
Jedis j = getShard(key);
return j.ltrim(key, start, stop);
}
@Override
public byte[] lindex(final byte[] key, final long index) {
Jedis j = getShard(key);
return j.lindex(key, index);
}
@Override
public String lset(final byte[] key, final long index, final byte[] value) {
Jedis j = getShard(key);
return j.lset(key, index, value);
}
@Override
public Long lrem(final byte[] key, final long count, final byte[] value) {
Jedis j = getShard(key);
return j.lrem(key, count, value);
}
@Override
public byte[] lpop(final byte[] key) {
Jedis j = getShard(key);
return j.lpop(key);
}
@Override
public byte[] rpop(final byte[] key) {
Jedis j = getShard(key);
return j.rpop(key);
}
@Override
public Long sadd(final byte[] key, final byte[]... members) {
Jedis j = getShard(key);
return j.sadd(key, members);
}
@Override
public Set<byte[]> smembers(final byte[] key) {
Jedis j = getShard(key);
return j.smembers(key);
}
@Override
public Long srem(final byte[] key, final byte[]... members) {
Jedis j = getShard(key);
return j.srem(key, members);
}
@Override
public byte[] spop(final byte[] key) {
Jedis j = getShard(key);
return j.spop(key);
}
@Override
public Set<byte[]> spop(final byte[] key, final long count) {
Jedis j = getShard(key);
return j.spop(key, count);
}
@Override
public Long scard(final byte[] key) {
Jedis j = getShard(key);
return j.scard(key);
}
@Override
public Boolean sismember(final byte[] key, final byte[] member) {
Jedis j = getShard(key);
return j.sismember(key, member);
}
@Override
public byte[] srandmember(final byte[] key) {
Jedis j = getShard(key);
return j.srandmember(key);
}
@Override
public List srandmember(final byte[] key, final int count) {
Jedis j = getShard(key);
return j.srandmember(key, count);
}
@Override
public Long zadd(final byte[] key, final double score, final byte[] member) {
Jedis j = getShard(key);
return j.zadd(key, score, member);
}
@Override
public Long zadd(final byte[] key, final double score, final byte[] member, final ZAddParams params) {
Jedis j = getShard(key);
return j.zadd(key, score, member, params);
}
@Override
public Long zadd(final byte[] key, final Map<byte[], Double> scoreMembers) {
Jedis j = getShard(key);
return j.zadd(key, scoreMembers);
}
@Override
public Long zadd(final byte[] key, final Map<byte[], Double> scoreMembers, final ZAddParams params) {
Jedis j = getShard(key);
return j.zadd(key, scoreMembers, params);
}
@Override
public Set<byte[]> zrange(final byte[] key, final long start, final long stop) {
Jedis j = getShard(key);
return j.zrange(key, start, stop);
}
@Override
public Long zrem(final byte[] key, final byte[]... members) {
Jedis j = getShard(key);
return j.zrem(key, members);
}
@Override
public Double zincrby(final byte[] key, final double increment, final byte[] member) {
Jedis j = getShard(key);
return j.zincrby(key, increment, member);
}
@Override
public Double zincrby(final byte[] key, final double increment, final byte[] member, ZIncrByParams params) {
Jedis j = getShard(key);
return j.zincrby(key, increment, member, params);
}
@Override
public Long zrank(final byte[] key, final byte[] member) {
Jedis j = getShard(key);
return j.zrank(key, member);
}
@Override
public Long zrevrank(final byte[] key, final byte[] member) {
Jedis j = getShard(key);
return j.zrevrank(key, member);
}
@Override
public Set<byte[]> zrevrange(final byte[] key, final long start, final long stop) {
Jedis j = getShard(key);
return j.zrevrange(key, start, stop);
}
@Override
public Set<Tuple> zrangeWithScores(final byte[] key, final long start, final long stop) {
Jedis j = getShard(key);
return j.zrangeWithScores(key, start, stop);
}
@Override
public Set<Tuple> zrevrangeWithScores(final byte[] key, final long start, final long stop) {
Jedis j = getShard(key);
return j.zrevrangeWithScores(key, start, stop);
}
@Override
public Long zcard(final byte[] key) {
Jedis j = getShard(key);
return j.zcard(key);
}
@Override
public Double zscore(final byte[] key, final byte[] member) {
Jedis j = getShard(key);
return j.zscore(key, member);
}
@Override
public List<byte[]> sort(final byte[] key) {
Jedis j = getShard(key);
return j.sort(key);
}
@Override
public List<byte[]> sort(final byte[] key, SortingParams sortingParameters) {
Jedis j = getShard(key);
return j.sort(key, sortingParameters);
}
@Override
public Long zcount(final byte[] key, final double min, final double max) {
Jedis j = getShard(key);
return j.zcount(key, min, max);
}
@Override
public Long zcount(final byte[] key, final byte[] min, final byte[] max) {
Jedis j = getShard(key);
return j.zcount(key, min, max);
}
@Override
public Set<byte[]> zrangeByScore(final byte[] key, final double min, final double max) {
Jedis j = getShard(key);
return j.zrangeByScore(key, min, max);
}
@Override
public Set<byte[]> zrangeByScore(final byte[] key, final double min, final double max, final int offset, final int count) {
Jedis j = getShard(key);
return j.zrangeByScore(key, min, max, offset, count);
}
@Override
public Set<Tuple> zrangeByScoreWithScores(final byte[] key, final double min, final double max) {
Jedis j = getShard(key);
return j.zrangeByScoreWithScores(key, min, max);
}
@Override
public Set<Tuple> zrangeByScoreWithScores(final byte[] key, final double min, final double max, final int offset,
final int count) {
Jedis j = getShard(key);
return j.zrangeByScoreWithScores(key, min, max, offset, count);
}
@Override
public Set<byte[]> zrangeByScore(final byte[] key, final byte[] min, final byte[] max) {
Jedis j = getShard(key);
return j.zrangeByScore(key, min, max);
}
@Override
public Set<Tuple> zrangeByScoreWithScores(final byte[] key, final byte[] min, final byte[] max) {
Jedis j = getShard(key);
return j.zrangeByScoreWithScores(key, min, max);
}
@Override
public Set<Tuple> zrangeByScoreWithScores(final byte[] key, final byte[] min, final byte[] max, final int offset,
final int count) {
Jedis j = getShard(key);
return j.zrangeByScoreWithScores(key, min, max, offset, count);
}
@Override
public Set<byte[]> zrangeByScore(final byte[] key, final byte[] min, final byte[] max, final int offset, final int count) {
Jedis j = getShard(key);
return j.zrangeByScore(key, min, max, offset, count);
}
@Override
public Set<byte[]> zrevrangeByScore(final byte[] key, final double max, final double min) {
Jedis j = getShard(key);
return j.zrevrangeByScore(key, max, min);
}
@Override
public Set<byte[]> zrevrangeByScore(final byte[] key, final double max, final double min, final int offset, final int count) {
Jedis j = getShard(key);
return j.zrevrangeByScore(key, max, min, offset, count);
}
@Override
public Set<Tuple> zrevrangeByScoreWithScores(final byte[] key, final double max, final double min) {
Jedis j = getShard(key);
return j.zrevrangeByScoreWithScores(key, max, min);
}
@Override
public Set<Tuple> zrevrangeByScoreWithScores(final byte[] key, final double max, final double min, final int offset,
final int count) {
Jedis j = getShard(key);
return j.zrevrangeByScoreWithScores(key, max, min, offset, count);
}
@Override
public Set<byte[]> zrevrangeByScore(final byte[] key, final byte[] max, final byte[] min) {
Jedis j = getShard(key);
return j.zrevrangeByScore(key, max, min);
}
@Override
public Set<byte[]> zrevrangeByScore(final byte[] key, final byte[] max, final byte[] min, final int offset, final int count) {
Jedis j = getShard(key);
return j.zrevrangeByScore(key, max, min, offset, count);
}
@Override
public Set<Tuple> zrevrangeByScoreWithScores(final byte[] key, final byte[] max, final byte[] min) {
Jedis j = getShard(key);
return j.zrevrangeByScoreWithScores(key, max, min);
}
@Override
public Set<Tuple> zrevrangeByScoreWithScores(final byte[] key, final byte[] max, final byte[] min, final int offset,
final int count) {
Jedis j = getShard(key);
return j.zrevrangeByScoreWithScores(key, max, min, offset, count);
}
@Override
public Long zremrangeByRank(final byte[] key, final long start, final long stop) {
Jedis j = getShard(key);
return j.zremrangeByRank(key, start, stop);
}
@Override
public Long zremrangeByScore(final byte[] key, final double min, final double max) {
Jedis j = getShard(key);
return j.zremrangeByScore(key, min, max);
}
@Override
public Long zremrangeByScore(final byte[] key, final byte[] min, final byte[] max) {
Jedis j = getShard(key);
return j.zremrangeByScore(key, min, max);
}
@Override
public Long zlexcount(final byte[] key, final byte[] min, final byte[] max) {
Jedis j = getShard(key);
return j.zlexcount(key, min, max);
}
@Override
public Set<byte[]> zrangeByLex(final byte[] key, final byte[] min, final byte[] max) {
Jedis j = getShard(key);
return j.zrangeByLex(key, min, max);
}
@Override
public Set<byte[]> zrangeByLex(final byte[] key, final byte[] min, final byte[] max,
final int offset, final int count) {
Jedis j = getShard(key);
return j.zrangeByLex(key, min, max, offset, count);
}
@Override
public Set<byte[]> zrevrangeByLex(final byte[] key, final byte[] max, final byte[] min) {
Jedis j = getShard(key);
return j.zrevrangeByLex(key, max, min);
}
@Override
public Set<byte[]> zrevrangeByLex(final byte[] key, final byte[] max, final byte[] min, final int offset, final int count) {
Jedis j = getShard(key);
return j.zrevrangeByLex(key, max, min, offset, count);
}
@Override
public Long zremrangeByLex(final byte[] key, final byte[] min, final byte[] max) {
Jedis j = getShard(key);
return j.zremrangeByLex(key, min, max);
}
@Override
public Long linsert(final byte[] key, final ListPosition where, final byte[] pivot, final byte[] value) {
Jedis j = getShard(key);
return j.linsert(key, where, pivot, value);
}
public ShardedJedisPipeline pipelined() {
ShardedJedisPipeline pipeline = new ShardedJedisPipeline();
pipeline.setShardedJedis(this);
return pipeline;
}
public Long objectRefcount(final byte[] key) {
Jedis j = getShard(key);
return j.objectRefcount(key);
}
public byte[] objectEncoding(final byte[] key) {
Jedis j = getShard(key);
return j.objectEncoding(key);
}
public Long objectIdletime(final byte[] key) {
Jedis j = getShard(key);
return j.objectIdletime(key);
}
@Override
public Boolean setbit(final byte[] key, final long offset, boolean value) {
Jedis j = getShard(key);
return j.setbit(key, offset, value);
}
@Override
public Boolean setbit(final byte[] key, final long offset, final byte[] value) {
Jedis j = getShard(key);
return j.setbit(key, offset, value);
}
@Override
public Boolean getbit(final byte[] key, final long offset) {
Jedis j = getShard(key);
return j.getbit(key, offset);
}
@Override
public Long setrange(final byte[] key, final long offset, final byte[] value) {
Jedis j = getShard(key);
return j.setrange(key, offset, value);
}
@Override
public byte[] getrange(final byte[] key, final long startOffset, final long endOffset) {
Jedis j = getShard(key);
return j.getrange(key, startOffset, endOffset);
}
@Override
public Long move(final byte[] key, final int dbIndex) {
Jedis j = getShard(key);
return j.move(key, dbIndex);
}
@Override
public byte[] echo(final byte[] arg) {
Jedis j = getShard(arg);
return j.echo(arg);
}
public List<byte[]> brpop(final byte[] arg) {
Jedis j = getShard(arg);
return j.brpop(arg);
}
public List<byte[]> blpop(final byte[] arg) {
Jedis j = getShard(arg);
return j.blpop(arg);
}
@Override
public Long bitcount(final byte[] key) {
Jedis j = getShard(key);
return j.bitcount(key);
}
@Override
public Long bitcount(final byte[] key, final long start, final long end) {
Jedis j = getShard(key);
return j.bitcount(key, start, end);
}
@Override
public Long pfadd(final byte[] key, final byte[]... elements) {
Jedis j = getShard(key);
return j.pfadd(key, elements);
}
@Override
public long pfcount(final byte[] key) {
Jedis j = getShard(key);
return j.pfcount(key);
}
@Override
public Long geoadd(final byte[] key, final double longitude, final double latitude, final byte[] member) {
Jedis j = getShard(key);
return j.geoadd(key, longitude, latitude, member);
}
@Override
public Long geoadd(final byte[] key, final Map<byte[], GeoCoordinate> memberCoordinateMap) {
Jedis j = getShard(key);
return j.geoadd(key, memberCoordinateMap);
}
@Override
public Double geodist(final byte[] key, final byte[] member1, final byte[] member2) {
Jedis j = getShard(key);
return j.geodist(key, member1, member2);
}
@Override
public Double geodist(final byte[] key, final byte[] member1, final byte[] member2, final GeoUnit unit) {
Jedis j = getShard(key);
return j.geodist(key, member1, member2, unit);
}
@Override
public List<byte[]> geohash(final byte[] key, final byte[]... members) {
Jedis j = getShard(key);
return j.geohash(key, members);
}
@Override
public List<GeoCoordinate> geopos(final byte[] key, final byte[]... members) {
Jedis j = getShard(key);
return j.geopos(key, members);
}
@Override
public List<GeoRadiusResponse> georadius(final byte[] key, final double longitude, final double latitude,
final double radius, final GeoUnit unit) {
Jedis j = getShard(key);
return j.georadius(key, longitude, latitude, radius, unit);
}
@Override
public List<GeoRadiusResponse> georadius(final byte[] key, final double longitude, final double latitude,
final double radius, final GeoUnit unit, final GeoRadiusParam param) {
Jedis j = getShard(key);
return j.georadius(key, longitude, latitude, radius, unit, param);
}
@Override
public List<GeoRadiusResponse> georadiusByMember(final byte[] key, final byte[] member, final double radius,
final GeoUnit unit) {
Jedis j = getShard(key);
return j.georadiusByMember(key, member, radius, unit);
}
@Override
public List<GeoRadiusResponse> georadiusByMember(final byte[] key, final byte[] member, final double radius,
final GeoUnit unit, final GeoRadiusParam param) {
Jedis j = getShard(key);
return j.georadiusByMember(key, member, radius, unit, param);
}
@Override
public ScanResult<Map.Entry<byte[], byte[]>> hscan(final byte[] key, final byte[] cursor) {
Jedis j = getShard(key);
return j.hscan(key, cursor);
}
@Override
public ScanResult<Map.Entry<byte[], byte[]>> hscan(final byte[] key, final byte[] cursor, final ScanParams params) {
Jedis j = getShard(key);
return j.hscan(key, cursor, params);
}
@Override
public ScanResult<byte[]> sscan(final byte[] key, final byte[] cursor) {
Jedis j = getShard(key);
return j.sscan(key, cursor);
}
@Override
public ScanResult<byte[]> sscan(final byte[] key, final byte[] cursor, final ScanParams params) {
Jedis j = getShard(key);
return j.sscan(key, cursor, params);
}
@Override
public ScanResult<Tuple> zscan(final byte[] key, final byte[] cursor) {
Jedis j = getShard(key);
return j.zscan(key, cursor);
}
@Override
public ScanResult<Tuple> zscan(final byte[] key, final byte[] cursor, final ScanParams params) {
Jedis j = getShard(key);
return j.zscan(key, cursor, params);
}
@Override
public List<Long> bitfield(final byte[] key, final byte[]... arguments) {
Jedis j = getShard(key);
return j.bitfield(key, arguments);
}
@Override
public Long hstrlen(final byte[] key, final byte[] field) {
Jedis j = getShard(key);
return j.hstrlen(key, field);
}
}

11
fine-jedis/src/com/fr/third/redis/clients/jedis/BitOP.java

@ -0,0 +1,11 @@
package com.fr.third.redis.clients.jedis;
public enum BitOP {
AND, OR, XOR, NOT;
public final byte[] raw;
private BitOP() {
this.raw = com.fr.third.redis.clients.jedis.util.SafeEncoder.encode(name());
}
}

27
fine-jedis/src/com/fr/third/redis/clients/jedis/BitPosParams.java

@ -0,0 +1,27 @@
package com.fr.third.redis.clients.jedis;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
public class BitPosParams {
private List<byte[]> params = new ArrayList<byte[]>();
protected BitPosParams() {
}
public BitPosParams(long start) {
params.add(Protocol.toByteArray(start));
}
public BitPosParams(long start, long end) {
this(start);
params.add(Protocol.toByteArray(end));
}
public Collection<byte[]> getParams() {
return Collections.unmodifiableCollection(params);
}
}

5
fine-jedis/src/com/fr/third/redis/clients/jedis/Builder.java

@ -0,0 +1,5 @@
package com.fr.third.redis.clients.jedis;
public abstract class Builder<T> {
public abstract T build(Object data);
}

482
fine-jedis/src/com/fr/third/redis/clients/jedis/BuilderFactory.java

@ -0,0 +1,482 @@
package com.fr.third.redis.clients.jedis;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import com.fr.third.redis.clients.jedis.util.JedisByteHashMap;
import com.fr.third.redis.clients.jedis.util.SafeEncoder;
public final class BuilderFactory {
public static final Builder<Double> DOUBLE = new Builder<Double>() {
@Override
public Double build(Object data) {
String string = STRING.build(data);
if (string == null) return null;
try {
return Double.valueOf(string);
} catch (NumberFormatException e) {
if (string.equals("inf") || string.equals("+inf")) return Double.POSITIVE_INFINITY;
if (string.equals("-inf")) return Double.NEGATIVE_INFINITY;
throw e;
}
}
@Override
public String toString() {
return "double";
}
};
public static final Builder<Boolean> BOOLEAN = new Builder<Boolean>() {
@Override
public Boolean build(Object data) {
return ((Long) data) == 1;
}
@Override
public String toString() {
return "boolean";
}
};
public static final Builder<byte[]> BYTE_ARRAY = new Builder<byte[]>() {
@Override
public byte[] build(Object data) {
return ((byte[]) data); // deleted == 1
}
@Override
public String toString() {
return "byte[]";
}
};
public static final Builder<Long> LONG = new Builder<Long>() {
@Override
public Long build(Object data) {
return (Long) data;
}
@Override
public String toString() {
return "long";
}
};
public static final Builder<String> STRING = new Builder<String>() {
@Override
public String build(Object data) {
return data == null ? null : SafeEncoder.encode((byte[]) data);
}
@Override
public String toString() {
return "string";
}
};
public static final Builder<List<String>> STRING_LIST = new Builder<List<String>>() {
@Override
@SuppressWarnings("unchecked")
public List<String> build(Object data) {
if (null == data) {
return null;
}
List<byte[]> l = (List<byte[]>) data;
final ArrayList<String> result = new ArrayList<String>(l.size());
for (final byte[] barray : l) {
if (barray == null) {
result.add(null);
} else {
result.add(SafeEncoder.encode(barray));
}
}
return result;
}
@Override
public String toString() {
return "List<String>";
}
};
public static final Builder<Map<String, String>> STRING_MAP = new Builder<Map<String, String>>() {
@Override
@SuppressWarnings("unchecked")
public Map<String, String> build(Object data) {
final List<byte[]> flatHash = (List<byte[]>) data;
final Map<String, String> hash = new HashMap<String, String>(flatHash.size()/2, 1);
final Iterator<byte[]> iterator = flatHash.iterator();
while (iterator.hasNext()) {
hash.put(SafeEncoder.encode(iterator.next()), SafeEncoder.encode(iterator.next()));
}
return hash;
}
@Override
public String toString() {
return "Map<String, String>";
}
};
public static final Builder<Map<String, String>> PUBSUB_NUMSUB_MAP = new Builder<Map<String, String>>() {
@Override
@SuppressWarnings("unchecked")
public Map<String, String> build(Object data) {
final List<Object> flatHash = (List<Object>) data;
final Map<String, String> hash = new HashMap<String, String>(flatHash.size()/2, 1);
final Iterator<Object> iterator = flatHash.iterator();
while (iterator.hasNext()) {
hash.put(SafeEncoder.encode((byte[]) iterator.next()),
String.valueOf((Long) iterator.next()));
}
return hash;
}
@Override
public String toString() {
return "PUBSUB_NUMSUB_MAP<String, String>";
}
};
public static final Builder<Set<String>> STRING_SET = new Builder<Set<String>>() {
@Override
@SuppressWarnings("unchecked")
public Set<String> build(Object data) {
if (null == data) {
return null;
}
List<byte[]> l = (List<byte[]>) data;
final Set<String> result = new HashSet<String>(l.size(), 1);
for (final byte[] barray : l) {
if (barray == null) {
result.add(null);
} else {
result.add(SafeEncoder.encode(barray));
}
}
return result;
}
@Override
public String toString() {
return "Set<String>";
}
};
public static final Builder<List<byte[]>> BYTE_ARRAY_LIST = new Builder<List<byte[]>>() {
@Override
@SuppressWarnings("unchecked")
public List<byte[]> build(Object data) {
if (null == data) {
return null;
}
List<byte[]> l = (List<byte[]>) data;
return l;
}
@Override
public String toString() {
return "List<byte[]>";
}
};
public static final Builder<Set<byte[]>> BYTE_ARRAY_ZSET = new Builder<Set<byte[]>>() {
@Override
@SuppressWarnings("unchecked")
public Set<byte[]> build(Object data) {
if (null == data) {
return null;
}
List<byte[]> l = (List<byte[]>) data;
final Set<byte[]> result = new LinkedHashSet<byte[]>(l);
for (final byte[] barray : l) {
if (barray == null) {
result.add(null);
} else {
result.add(barray);
}
}
return result;
}
@Override
public String toString() {
return "ZSet<byte[]>";
}
};
public static final Builder<Map<byte[], byte[]>> BYTE_ARRAY_MAP = new Builder<Map<byte[], byte[]>>() {
@Override
@SuppressWarnings("unchecked")
public Map<byte[], byte[]> build(Object data) {
final List<byte[]> flatHash = (List<byte[]>) data;
final Map<byte[], byte[]> hash = new JedisByteHashMap();
final Iterator<byte[]> iterator = flatHash.iterator();
while (iterator.hasNext()) {
hash.put(iterator.next(), iterator.next());
}
return hash;
}
@Override
public String toString() {
return "Map<byte[], byte[]>";
}
};
public static final Builder<Set<String>> STRING_ZSET = new Builder<Set<String>>() {
@Override
@SuppressWarnings("unchecked")
public Set<String> build(Object data) {
if (null == data) {
return null;
}
List<byte[]> l = (List<byte[]>) data;
final Set<String> result = new LinkedHashSet<String>(l.size(), 1);
for (final byte[] barray : l) {
if (barray == null) {
result.add(null);
} else {
result.add(SafeEncoder.encode(barray));
}
}
return result;
}
@Override
public String toString() {
return "ZSet<String>";
}
};
public static final Builder<Set<Tuple>> TUPLE_ZSET = new Builder<Set<Tuple>>() {
@Override
@SuppressWarnings("unchecked")
public Set<Tuple> build(Object data) {
if (null == data) {
return null;
}
List<byte[]> l = (List<byte[]>) data;
final Set<Tuple> result = new LinkedHashSet<Tuple>(l.size()/2, 1);
Iterator<byte[]> iterator = l.iterator();
while (iterator.hasNext()) {
result.add(new Tuple(iterator.next(), DOUBLE.build(iterator.next())));
}
return result;
}
@Override
public String toString() {
return "ZSet<Tuple>";
}
};
public static final Builder<Object> EVAL_RESULT = new Builder<Object>() {
@Override
public Object build(Object data) {
return evalResult(data);
}
@Override
public String toString() {
return "Eval<Object>";
}
private Object evalResult(Object result) {
if (result instanceof byte[]) return SafeEncoder.encode((byte[]) result);
if (result instanceof List<?>) {
List<?> list = (List<?>) result;
List<Object> listResult = new ArrayList<Object>(list.size());
for (Object bin : list) {
listResult.add(evalResult(bin));
}
return listResult;
}
return result;
}
};
public static final Builder<Object> EVAL_BINARY_RESULT = new Builder<Object>() {
@Override
public Object build(Object data) {
return evalResult(data);
}
@Override
public String toString() {
return "Eval<Object>";
}
private Object evalResult(Object result) {
if (result instanceof List<?>) {
List<?> list = (List<?>) result;
List<Object> listResult = new ArrayList<Object>(list.size());
for (Object bin : list) {
listResult.add(evalResult(bin));
}
return listResult;
}
return result;
}
};
public static final Builder<List<GeoCoordinate>> GEO_COORDINATE_LIST = new Builder<List<GeoCoordinate>>() {
@Override
public List<GeoCoordinate> build(Object data) {
if (null == data) {
return null;
}
return interpretGeoposResult((List<Object>) data);
}
@Override
public String toString() {
return "List<GeoCoordinate>";
}
private List<GeoCoordinate> interpretGeoposResult(List<Object> responses) {
List<GeoCoordinate> responseCoordinate = new ArrayList<GeoCoordinate>(responses.size());
for (Object response : responses) {
if (response == null) {
responseCoordinate.add(null);
} else {
List<Object> respList = (List<Object>) response;
GeoCoordinate coord = new GeoCoordinate(DOUBLE.build(respList.get(0)),
DOUBLE.build(respList.get(1)));
responseCoordinate.add(coord);
}
}
return responseCoordinate;
}
};
public static final Builder<List<GeoRadiusResponse>> GEORADIUS_WITH_PARAMS_RESULT = new Builder<List<GeoRadiusResponse>>() {
@Override
public List<GeoRadiusResponse> build(Object data) {
if (data == null) {
return null;
}
List<Object> objectList = (List<Object>) data;
List<GeoRadiusResponse> responses = new ArrayList<GeoRadiusResponse>(objectList.size());
if (objectList.isEmpty()) {
return responses;
}
if (objectList.get(0) instanceof List<?>) {
// list of members with additional informations
GeoRadiusResponse resp;
for (Object obj : objectList) {
List<Object> informations = (List<Object>) obj;
resp = new GeoRadiusResponse((byte[]) informations.get(0));
int size = informations.size();
for (int idx = 1; idx < size; idx++) {
Object info = informations.get(idx);
if (info instanceof List<?>) {
// coordinate
List<Object> coord = (List<Object>) info;
resp.setCoordinate(new GeoCoordinate(DOUBLE.build(coord.get(0)),
DOUBLE.build(coord.get(1))));
} else {
// distance
resp.setDistance(DOUBLE.build(info));
}
}
responses.add(resp);
}
} else {
// list of members
for (Object obj : objectList) {
responses.add(new GeoRadiusResponse((byte[]) obj));
}
}
return responses;
}
@Override
public String toString() {
return "GeoRadiusWithParamsResult";
}
};
public static final Builder<List<Module>> MODULE_LIST = new Builder<List<Module>>() {
@Override
public List<Module> build(Object data) {
if (data == null) {
return null;
}
List<List<Object>> objectList = (List<List<Object>>) data;
List<Module> responses = new ArrayList<Module>(objectList.size());
if (objectList.isEmpty()) {
return responses;
}
for (List<Object> moduleResp: objectList) {
Module m = new Module(SafeEncoder.encode((byte[]) moduleResp.get(1)), ((Long) moduleResp.get(3)).intValue());
responses.add(m);
}
return responses;
}
@Override
public String toString() {
return "List<Module>";
}
};
public static final Builder<List<Long>> LONG_LIST = new Builder<List<Long>>() {
@Override
@SuppressWarnings("unchecked")
public List<Long> build(Object data) {
if (null == data) {
return null;
}
return (List<Long>) data;
}
@Override
public String toString() {
return "List<Long>";
}
};
private BuilderFactory() {
throw new InstantiationError( "Must not instantiate this class" );
}
}

1123
fine-jedis/src/com/fr/third/redis/clients/jedis/Client.java

File diff suppressed because it is too large Load Diff

5
fine-jedis/src/com/fr/third/redis/clients/jedis/ClusterReset.java

@ -0,0 +1,5 @@
package com.fr.third.redis.clients.jedis;
public enum ClusterReset {
SOFT, HARD
}

328
fine-jedis/src/com/fr/third/redis/clients/jedis/Connection.java

@ -0,0 +1,328 @@
package com.fr.third.redis.clients.jedis;
import java.io.Closeable;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketException;
import java.util.ArrayList;
import java.util.List;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLParameters;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import com.fr.third.redis.clients.jedis.commands.ProtocolCommand;
import com.fr.third.redis.clients.jedis.exceptions.JedisConnectionException;
import com.fr.third.redis.clients.jedis.exceptions.JedisDataException;
import com.fr.third.redis.clients.jedis.util.IOUtils;
import com.fr.third.redis.clients.jedis.util.RedisInputStream;
import com.fr.third.redis.clients.jedis.util.RedisOutputStream;
import com.fr.third.redis.clients.jedis.util.SafeEncoder;
public class Connection implements Closeable {
private static final byte[][] EMPTY_ARGS = new byte[0][];
private String host = Protocol.DEFAULT_HOST;
private int port = Protocol.DEFAULT_PORT;
private Socket socket;
private RedisOutputStream outputStream;
private RedisInputStream inputStream;
private int connectionTimeout = Protocol.DEFAULT_TIMEOUT;
private int soTimeout = Protocol.DEFAULT_TIMEOUT;
private boolean broken = false;
private boolean ssl;
private SSLSocketFactory sslSocketFactory;
private SSLParameters sslParameters;
private HostnameVerifier hostnameVerifier;
public Connection() {
}
public Connection(final String host) {
this.host = host;
}
public Connection(final String host, final int port) {
this.host = host;
this.port = port;
}
public Connection(final String host, final int port, final boolean ssl) {
this.host = host;
this.port = port;
this.ssl = ssl;
}
public Connection(final String host, final int port, final boolean ssl,
SSLSocketFactory sslSocketFactory, SSLParameters sslParameters,
HostnameVerifier hostnameVerifier) {
this.host = host;
this.port = port;
this.ssl = ssl;
this.sslSocketFactory = sslSocketFactory;
this.sslParameters = sslParameters;
this.hostnameVerifier = hostnameVerifier;
}
public Socket getSocket() {
return socket;
}
public int getConnectionTimeout() {
return connectionTimeout;
}
public int getSoTimeout() {
return soTimeout;
}
public void setConnectionTimeout(int connectionTimeout) {
this.connectionTimeout = connectionTimeout;
}
public void setSoTimeout(int soTimeout) {
this.soTimeout = soTimeout;
}
public void setTimeoutInfinite() {
try {
if (!isConnected()) {
connect();
}
socket.setSoTimeout(0);
} catch (SocketException ex) {
broken = true;
throw new JedisConnectionException(ex);
}
}
public void rollbackTimeout() {
try {
socket.setSoTimeout(soTimeout);
} catch (SocketException ex) {
broken = true;
throw new JedisConnectionException(ex);
}
}
public void sendCommand(final ProtocolCommand cmd, final String... args) {
final byte[][] bargs = new byte[args.length][];
for (int i = 0; i < args.length; i++) {
bargs[i] = SafeEncoder.encode(args[i]);
}
sendCommand(cmd, bargs);
}
public void sendCommand(final ProtocolCommand cmd) {
sendCommand(cmd, EMPTY_ARGS);
}
public void sendCommand(final ProtocolCommand cmd, final byte[]... args) {
try {
connect();
Protocol.sendCommand(outputStream, cmd, args);
} catch (JedisConnectionException ex) {
/*
* When client send request which formed by invalid protocol, Redis send back error message
* before close connection. We try to read it to provide reason of failure.
*/
try {
String errorMessage = Protocol.readErrorLineIfPossible(inputStream);
if (errorMessage != null && errorMessage.length() > 0) {
ex = new JedisConnectionException(errorMessage, ex.getCause());
}
} catch (Exception e) {
/*
* Catch any IOException or JedisConnectionException occurred from InputStream#read and just
* ignore. This approach is safe because reading error message is optional and connection
* will eventually be closed.
*/
}
// Any other exceptions related to connection?
broken = true;
throw ex;
}
}
public String getHost() {
return host;
}
public void setHost(final String host) {
this.host = host;
}
public int getPort() {
return port;
}
public void setPort(final int port) {
this.port = port;
}
public void connect() {
if (!isConnected()) {
try {
socket = new Socket();
// ->@wjw_add
socket.setReuseAddress(true);
socket.setKeepAlive(true); // Will monitor the TCP connection is
// valid
socket.setTcpNoDelay(true); // Socket buffer Whetherclosed, to
// ensure timely delivery of data
socket.setSoLinger(true, 0); // Control calls close () method,
// the underlying socket is closed
// immediately
// <-@wjw_add
socket.connect(new InetSocketAddress(host, port), connectionTimeout);
socket.setSoTimeout(soTimeout);
if (ssl) {
if (null == sslSocketFactory) {
sslSocketFactory = (SSLSocketFactory)SSLSocketFactory.getDefault();
}
socket = sslSocketFactory.createSocket(socket, host, port, true);
if (null != sslParameters) {
((SSLSocket) socket).setSSLParameters(sslParameters);
}
if ((null != hostnameVerifier) &&
(!hostnameVerifier.verify(host, ((SSLSocket) socket).getSession()))) {
String message = String.format(
"The connection to '%s' failed ssl/tls hostname verification.", host);
throw new JedisConnectionException(message);
}
}
outputStream = new RedisOutputStream(socket.getOutputStream());
inputStream = new RedisInputStream(socket.getInputStream());
} catch (IOException ex) {
broken = true;
throw new JedisConnectionException("Failed connecting to host "
+ host + ":" + port, ex);
}
}
}
@Override
public void close() {
disconnect();
}
public void disconnect() {
if (isConnected()) {
try {
outputStream.flush();
socket.close();
} catch (IOException ex) {
broken = true;
throw new JedisConnectionException(ex);
} finally {
IOUtils.closeQuietly(socket);
}
}
}
public boolean isConnected() {
return socket != null && socket.isBound() && !socket.isClosed() && socket.isConnected()
&& !socket.isInputShutdown() && !socket.isOutputShutdown();
}
public String getStatusCodeReply() {
flush();
final byte[] resp = (byte[]) readProtocolWithCheckingBroken();
if (null == resp) {
return null;
} else {
return SafeEncoder.encode(resp);
}
}
public String getBulkReply() {
final byte[] result = getBinaryBulkReply();
if (null != result) {
return SafeEncoder.encode(result);
} else {
return null;
}
}
public byte[] getBinaryBulkReply() {
flush();
return (byte[]) readProtocolWithCheckingBroken();
}
public Long getIntegerReply() {
flush();
return (Long) readProtocolWithCheckingBroken();
}
public List<String> getMultiBulkReply() {
return BuilderFactory.STRING_LIST.build(getBinaryMultiBulkReply());
}
@SuppressWarnings("unchecked")
public List<byte[]> getBinaryMultiBulkReply() {
flush();
return (List<byte[]>) readProtocolWithCheckingBroken();
}
@SuppressWarnings("unchecked")
public List<Object> getRawObjectMultiBulkReply() {
flush();
return (List<Object>) readProtocolWithCheckingBroken();
}
public List<Object> getObjectMultiBulkReply() {
return getRawObjectMultiBulkReply();
}
@SuppressWarnings("unchecked")
public List<Long> getIntegerMultiBulkReply() {
flush();
return (List<Long>) readProtocolWithCheckingBroken();
}
public Object getOne() {
flush();
return readProtocolWithCheckingBroken();
}
public boolean isBroken() {
return broken;
}
protected void flush() {
try {
outputStream.flush();
} catch (IOException ex) {
broken = true;
throw new JedisConnectionException(ex);
}
}
protected Object readProtocolWithCheckingBroken() {
try {
return Protocol.read(inputStream);
} catch (JedisConnectionException exc) {
broken = true;
throw exc;
}
}
public List<Object> getMany(final int count) {
flush();
final List<Object> responses = new ArrayList<Object>(count);
for (int i = 0; i < count; i++) {
try {
responses.add(readProtocolWithCheckingBroken());
} catch (JedisDataException e) {
responses.add(e);
}
}
return responses;
}
}

31
fine-jedis/src/com/fr/third/redis/clients/jedis/DebugParams.java

@ -0,0 +1,31 @@
package com.fr.third.redis.clients.jedis;
public class DebugParams {
private String[] command;
private DebugParams() {
}
public String[] getCommand() {
return command;
}
public static DebugParams SEGFAULT() {
DebugParams debugParams = new DebugParams();
debugParams.command = new String[] { "SEGFAULT" };
return debugParams;
}
public static DebugParams OBJECT(String key) {
DebugParams debugParams = new DebugParams();
debugParams.command = new String[] { "OBJECT", key };
return debugParams;
}
public static DebugParams RELOAD() {
DebugParams debugParams = new DebugParams();
debugParams.command = new String[] { "RELOAD" };
return debugParams;
}
}

47
fine-jedis/src/com/fr/third/redis/clients/jedis/GeoCoordinate.java

@ -0,0 +1,47 @@
package com.fr.third.redis.clients.jedis;
public class GeoCoordinate {
private double longitude;
private double latitude;
public GeoCoordinate(double longitude, double latitude) {
this.longitude = longitude;
this.latitude = latitude;
}
public double getLongitude() {
return longitude;
}
public double getLatitude() {
return latitude;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof GeoCoordinate)) return false;
GeoCoordinate that = (GeoCoordinate) o;
if (Double.compare(that.longitude, longitude) != 0) return false;
return Double.compare(that.latitude, latitude) == 0;
}
@Override
public int hashCode() {
// follows IntelliJ default hashCode implementation
int result;
long temp;
temp = Double.doubleToLongBits(longitude);
result = (int) (temp ^ (temp >>> 32));
temp = Double.doubleToLongBits(latitude);
result = 31 * result + (int) (temp ^ (temp >>> 32));
return result;
}
@Override
public String toString() {
return "(" + longitude + "," + latitude + ")";
}
}

37
fine-jedis/src/com/fr/third/redis/clients/jedis/GeoRadiusResponse.java

@ -0,0 +1,37 @@
package com.fr.third.redis.clients.jedis;
import com.fr.third.redis.clients.jedis.util.SafeEncoder;
public class GeoRadiusResponse {
private byte[] member;
private double distance;
private GeoCoordinate coordinate;
public GeoRadiusResponse(byte[] member) {
this.member = member;
}
public void setDistance(double distance) {
this.distance = distance;
}
public void setCoordinate(GeoCoordinate coordinate) {
this.coordinate = coordinate;
}
public byte[] getMember() {
return member;
}
public String getMemberByString() {
return SafeEncoder.encode(member);
}
public double getDistance() {
return distance;
}
public GeoCoordinate getCoordinate() {
return coordinate;
}
}

13
fine-jedis/src/com/fr/third/redis/clients/jedis/GeoUnit.java

@ -0,0 +1,13 @@
package com.fr.third.redis.clients.jedis;
import com.fr.third.redis.clients.jedis.util.SafeEncoder;
public enum GeoUnit {
M, KM, MI, FT;
public final byte[] raw;
GeoUnit() {
raw = SafeEncoder.encode(this.name().toLowerCase());
}
}

153
fine-jedis/src/com/fr/third/redis/clients/jedis/HostAndPort.java

@ -0,0 +1,153 @@
package com.fr.third.redis.clients.jedis;
import java.io.Serializable;
import java.net.InetAddress;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class HostAndPort implements Serializable {
private static final long serialVersionUID = -519876229978427751L;
protected static Logger log = LoggerFactory.getLogger(HostAndPort.class.getName());
public static String localhost;
private String host;
private int port;
public HostAndPort(String host, int port) {
this.host = host;
this.port = port;
}
public String getHost() {
return host;
}
public int getPort() {
return port;
}
@Override
public boolean equals(Object obj) {
if (obj instanceof HostAndPort) {
HostAndPort hp = (HostAndPort) obj;
String thisHost = convertHost(host);
String hpHost = convertHost(hp.host);
return port == hp.port && thisHost.equals(hpHost);
}
return false;
}
@Override
public int hashCode() {
return 31 * convertHost(host).hashCode() + port;
}
@Override
public String toString() {
return host + ":" + port;
}
/**
* Splits String into host and port parts.
* String must be in ( host + ":" + port ) format.
* Port is optional
* @param from String to parse
* @return array of host and port strings
*/
public static String[] extractParts(String from){
int idx = from.lastIndexOf(":");
String host = idx != -1 ? from.substring(0, idx) : from;
String port = idx != -1 ? from.substring(idx + 1) : "";
return new String[] { host, port };
}
/**
* Creates HostAndPort instance from string.
* String must be in ( host + ":" + port ) format.
* Port is mandatory. Can convert host part.
* @see #convertHost(String)
* @param from String to parse
* @return HostAndPort instance
*/
public static HostAndPort parseString(String from){
// NOTE: redis answers with
// '99aa9999aa9a99aa099aaa990aa99a09aa9a9999 9a09:9a9:a090:9a::99a slave 8c88888888cc08088cc8c8c888c88c8888c88cc8 0 1468251272993 37 connected'
// for CLUSTER NODES, ASK and MOVED scenarios. That's why there is no possibility to parse address in 'correct' way.
// Redis should switch to 'bracketized' (RFC 3986) IPv6 address.
try {
String[] parts = extractParts(from);
String host = parts[0];
int port = Integer.parseInt(parts[1]);
return new HostAndPort(convertHost(host), port);
} catch (NumberFormatException ex) {
throw new IllegalArgumentException(ex);
}
}
public static String convertHost(String host) {
try {
/*
* Validate the host name as an IPV4/IPV6 address.
* If this is an AWS ENDPOINT it will not parse.
* In that case accept host as is.
*
* Costs: If this is an IPV4/6 encoding, e.g. 127.0.0.1 then no DNS lookup
* is done. If it is a name then a DNS lookup is done but it is normally cached.
* Secondarily, this class is typically used to create a connection once
* at the beginning of processing and then not used again. So even if the DNS
* lookup needs to be done then the cost is miniscule.
*/
InetAddress inetAddress = InetAddress.getByName(host);
// isLoopbackAddress() handles both IPV4 and IPV6
if (inetAddress.isLoopbackAddress() || host.equals("0.0.0.0") || host.startsWith("169.254"))
return getLocalhost();
else
return host;
} catch (Exception e) {
// Not a valid IP address
log.warn("{}.convertHost '" + host + "' is not a valid IP address. ", HostAndPort.class.getName(), e);
return host;
}
}
public static void setLocalhost(String localhost) {
synchronized (HostAndPort.class) {
HostAndPort.localhost = localhost;
}
}
/**
* This method resolves the localhost in a 'lazy manner'.
*
* @return localhost
*/
public static String getLocalhost() {
if (localhost == null) {
synchronized (HostAndPort.class) {
if (localhost == null) {
return localhost = getLocalHostQuietly();
}
}
}
return localhost;
}
public static String getLocalHostQuietly() {
String localAddress;
try {
localAddress = InetAddress.getLocalHost().getHostAddress();
} catch (Exception ex) {
log.error("{}.getLocalHostQuietly : cant resolve localhost address",
HostAndPort.class.getName(), ex);
localAddress = "localhost";
}
return localAddress;
}
}

3582
fine-jedis/src/com/fr/third/redis/clients/jedis/Jedis.java

File diff suppressed because it is too large Load Diff

1979
fine-jedis/src/com/fr/third/redis/clients/jedis/JedisCluster.java

File diff suppressed because it is too large Load Diff

170
fine-jedis/src/com/fr/third/redis/clients/jedis/JedisClusterCommand.java

@ -0,0 +1,170 @@
package com.fr.third.redis.clients.jedis;
import com.fr.third.redis.clients.jedis.exceptions.JedisAskDataException;
import com.fr.third.redis.clients.jedis.exceptions.JedisClusterMaxAttemptsException;
import com.fr.third.redis.clients.jedis.exceptions.JedisClusterOperationException;
import com.fr.third.redis.clients.jedis.exceptions.JedisConnectionException;
import com.fr.third.redis.clients.jedis.exceptions.JedisMovedDataException;
import com.fr.third.redis.clients.jedis.exceptions.JedisNoReachableClusterNodeException;
import com.fr.third.redis.clients.jedis.exceptions.JedisRedirectionException;
import com.fr.third.redis.clients.jedis.util.JedisClusterCRC16;
public abstract class JedisClusterCommand<T> {
private static final String NO_DISPATCH_MESSAGE = "No way to dispatch this command to Redis Cluster.";
private final JedisClusterConnectionHandler connectionHandler;
private final int maxAttempts;
private final ThreadLocal<Jedis> askConnection = new ThreadLocal<Jedis>();
public JedisClusterCommand(JedisClusterConnectionHandler connectionHandler, int maxAttempts) {
this.connectionHandler = connectionHandler;
this.maxAttempts = maxAttempts;
}
public abstract T execute(Jedis connection);
public T run(String key) {
if (key == null) {
throw new JedisClusterOperationException(NO_DISPATCH_MESSAGE);
}
return runWithRetries(JedisClusterCRC16.getSlot(key), this.maxAttempts, false, false);
}
public T run(int keyCount, String... keys) {
if (keys == null || keys.length == 0) {
throw new JedisClusterOperationException(NO_DISPATCH_MESSAGE);
}
// For multiple keys, only execute if they all share the same connection slot.
int slot = JedisClusterCRC16.getSlot(keys[0]);
if (keys.length > 1) {
for (int i = 1; i < keyCount; i++) {
int nextSlot = JedisClusterCRC16.getSlot(keys[i]);
if (slot != nextSlot) {
throw new JedisClusterOperationException("No way to dispatch this command to Redis "
+ "Cluster because keys have different slots.");
}
}
}
return runWithRetries(slot, this.maxAttempts, false, false);
}
public T runBinary(byte[] key) {
if (key == null) {
throw new JedisClusterOperationException(NO_DISPATCH_MESSAGE);
}
return runWithRetries(JedisClusterCRC16.getSlot(key), this.maxAttempts, false, false);
}
public T runBinary(int keyCount, byte[]... keys) {
if (keys == null || keys.length == 0) {
throw new JedisClusterOperationException(NO_DISPATCH_MESSAGE);
}
// For multiple keys, only execute if they all share the same connection slot.
int slot = JedisClusterCRC16.getSlot(keys[0]);
if (keys.length > 1) {
for (int i = 1; i < keyCount; i++) {
int nextSlot = JedisClusterCRC16.getSlot(keys[i]);
if (slot != nextSlot) {
throw new JedisClusterOperationException("No way to dispatch this command to Redis "
+ "Cluster because keys have different slots.");
}
}
}
return runWithRetries(slot, this.maxAttempts, false, false);
}
public T runWithAnyNode() {
Jedis connection = null;
try {
connection = connectionHandler.getConnection();
return execute(connection);
} catch (JedisConnectionException e) {
throw e;
} finally {
releaseConnection(connection);
}
}
private T runWithRetries(final int slot, int attempts, boolean tryRandomNode, boolean asking) {
if (attempts <= 0) {
throw new JedisClusterMaxAttemptsException("No more cluster attempts left.");
}
Jedis connection = null;
try {
if (asking) {
// TODO: Pipeline asking with the original command to make it
// faster....
connection = askConnection.get();
connection.asking();
// if asking success, reset asking flag
asking = false;
} else {
if (tryRandomNode) {
connection = connectionHandler.getConnection();
} else {
connection = connectionHandler.getConnectionFromSlot(slot);
}
}
return execute(connection);
} catch (JedisNoReachableClusterNodeException jnrcne) {
throw jnrcne;
} catch (JedisConnectionException jce) {
// release current connection before recursion
releaseConnection(connection);
connection = null;
if (attempts <= 1) {
//We need this because if node is not reachable anymore - we need to finally initiate slots renewing,
//or we can stuck with cluster state without one node in opposite case.
//But now if maxAttempts = 1 or 2 we will do it too often. For each time-outed request.
//TODO make tracking of successful/unsuccessful operations for node - do renewing only
//if there were no successful responses from this node last few seconds
this.connectionHandler.renewSlotCache();
}
return runWithRetries(slot, attempts - 1, tryRandomNode, asking);
} catch (JedisRedirectionException jre) {
// if MOVED redirection occurred,
if (jre instanceof JedisMovedDataException) {
// it rebuilds cluster's slot cache
// recommended by Redis cluster specification
this.connectionHandler.renewSlotCache(connection);
}
// release current connection before recursion or renewing
releaseConnection(connection);
connection = null;
if (jre instanceof JedisAskDataException) {
asking = true;
askConnection.set(this.connectionHandler.getConnectionFromNode(jre.getTargetNode()));
} else if (jre instanceof JedisMovedDataException) {
} else {
throw new JedisClusterOperationException(jre);
}
return runWithRetries(slot, attempts - 1, false, asking);
} finally {
releaseConnection(connection);
}
}
private void releaseConnection(Jedis connection) {
if (connection != null) {
connection.close();
}
}
}

73
fine-jedis/src/com/fr/third/redis/clients/jedis/JedisClusterConnectionHandler.java

@ -0,0 +1,73 @@
package com.fr.third.redis.clients.jedis;
import java.io.Closeable;
import java.util.Map;
import java.util.Set;
import com.fr.third.org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import com.fr.third.redis.clients.jedis.exceptions.JedisConnectionException;
public abstract class JedisClusterConnectionHandler implements Closeable {
protected final JedisClusterInfoCache cache;
public JedisClusterConnectionHandler(Set<HostAndPort> nodes,
final GenericObjectPoolConfig poolConfig, int connectionTimeout, int soTimeout, String password) {
this(nodes, poolConfig, connectionTimeout, soTimeout, password, null);
}
public JedisClusterConnectionHandler(Set<HostAndPort> nodes,
final GenericObjectPoolConfig poolConfig, int connectionTimeout, int soTimeout, String password, String clientName) {
this.cache = new JedisClusterInfoCache(poolConfig, connectionTimeout, soTimeout, password, clientName);
initializeSlotsCache(nodes, poolConfig, connectionTimeout, soTimeout, password, clientName);
}
abstract Jedis getConnection();
abstract Jedis getConnectionFromSlot(int slot);
public Jedis getConnectionFromNode(HostAndPort node) {
return cache.setupNodeIfNotExist(node).getResource();
}
public Map<String, JedisPool> getNodes() {
return cache.getNodes();
}
private void initializeSlotsCache(Set<HostAndPort> startNodes, GenericObjectPoolConfig poolConfig,
int connectionTimeout, int soTimeout, String password, String clientName) {
for (HostAndPort hostAndPort : startNodes) {
Jedis jedis = null;
try {
jedis = new Jedis(hostAndPort.getHost(), hostAndPort.getPort(), connectionTimeout, soTimeout);
if (password != null) {
jedis.auth(password);
}
if (clientName != null) {
jedis.clientSetname(clientName);
}
cache.discoverClusterNodesAndSlots(jedis);
break;
} catch (JedisConnectionException e) {
// try next nodes
} finally {
if (jedis != null) {
jedis.close();
}
}
}
}
public void renewSlotCache() {
cache.renewClusterSlots(null);
}
public void renewSlotCache(Jedis jedis) {
cache.renewClusterSlots(jedis);
}
@Override
public void close() {
cache.reset();
}
}

268
fine-jedis/src/com/fr/third/redis/clients/jedis/JedisClusterInfoCache.java

@ -0,0 +1,268 @@
package com.fr.third.redis.clients.jedis;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import com.fr.third.org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import com.fr.third.redis.clients.jedis.exceptions.JedisConnectionException;
import com.fr.third.redis.clients.jedis.exceptions.JedisException;
import com.fr.third.redis.clients.jedis.util.SafeEncoder;
public class JedisClusterInfoCache {
private final Map<String, JedisPool> nodes = new HashMap<String, JedisPool>();
private final Map<Integer, JedisPool> slots = new HashMap<Integer, JedisPool>();
private final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
private final Lock r = rwl.readLock();
private final Lock w = rwl.writeLock();
private volatile boolean rediscovering;
private final GenericObjectPoolConfig poolConfig;
private int connectionTimeout;
private int soTimeout;
private String password;
private String clientName;
private static final int MASTER_NODE_INDEX = 2;
public JedisClusterInfoCache(final GenericObjectPoolConfig poolConfig, int timeout) {
this(poolConfig, timeout, timeout, null, null);
}
public JedisClusterInfoCache(final GenericObjectPoolConfig poolConfig,
final int connectionTimeout, final int soTimeout, final String password, final String clientName) {
this.poolConfig = poolConfig;
this.connectionTimeout = connectionTimeout;
this.soTimeout = soTimeout;
this.password = password;
this.clientName = clientName;
}
public void discoverClusterNodesAndSlots(Jedis jedis) {
w.lock();
try {
reset();
List<Object> slots = jedis.clusterSlots();
for (Object slotInfoObj : slots) {
List<Object> slotInfo = (List<Object>) slotInfoObj;
if (slotInfo.size() <= MASTER_NODE_INDEX) {
continue;
}
List<Integer> slotNums = getAssignedSlotArray(slotInfo);
// hostInfos
int size = slotInfo.size();
for (int i = MASTER_NODE_INDEX; i < size; i++) {
List<Object> hostInfos = (List<Object>) slotInfo.get(i);
if (hostInfos.size() <= 0) {
continue;
}
HostAndPort targetNode = generateHostAndPort(hostInfos);
setupNodeIfNotExist(targetNode);
if (i == MASTER_NODE_INDEX) {
assignSlotsToNode(slotNums, targetNode);
}
}
}
} finally {
w.unlock();
}
}
public void renewClusterSlots(Jedis jedis) {
//If rediscovering is already in process - no need to start one more same rediscovering, just return
if (!rediscovering) {
try {
w.lock();
rediscovering = true;
if (jedis != null) {
try {
discoverClusterSlots(jedis);
return;
} catch (JedisException e) {
//try nodes from all pools
}
}
for (JedisPool jp : getShuffledNodesPool()) {
Jedis j = null;
try {
j = jp.getResource();
discoverClusterSlots(j);
return;
} catch (JedisConnectionException e) {
// try next nodes
} finally {
if (j != null) {
j.close();
}
}
}
} finally {
rediscovering = false;
w.unlock();
}
}
}
private void discoverClusterSlots(Jedis jedis) {
List<Object> slots = jedis.clusterSlots();
this.slots.clear();
for (Object slotInfoObj : slots) {
List<Object> slotInfo = (List<Object>) slotInfoObj;
if (slotInfo.size() <= MASTER_NODE_INDEX) {
continue;
}
List<Integer> slotNums = getAssignedSlotArray(slotInfo);
// hostInfos
List<Object> hostInfos = (List<Object>) slotInfo.get(MASTER_NODE_INDEX);
if (hostInfos.isEmpty()) {
continue;
}
// at this time, we just use master, discard slave information
HostAndPort targetNode = generateHostAndPort(hostInfos);
assignSlotsToNode(slotNums, targetNode);
}
}
private HostAndPort generateHostAndPort(List<Object> hostInfos) {
return new HostAndPort(SafeEncoder.encode((byte[]) hostInfos.get(0)),
((Long) hostInfos.get(1)).intValue());
}
public JedisPool setupNodeIfNotExist(HostAndPort node) {
w.lock();
try {
String nodeKey = getNodeKey(node);
JedisPool existingPool = nodes.get(nodeKey);
if (existingPool != null) return existingPool;
JedisPool nodePool = new JedisPool(poolConfig, node.getHost(), node.getPort(),
connectionTimeout, soTimeout, password, 0, clientName, false, null, null, null);
nodes.put(nodeKey, nodePool);
return nodePool;
} finally {
w.unlock();
}
}
public void assignSlotToNode(int slot, HostAndPort targetNode) {
w.lock();
try {
JedisPool targetPool = setupNodeIfNotExist(targetNode);
slots.put(slot, targetPool);
} finally {
w.unlock();
}
}
public void assignSlotsToNode(List<Integer> targetSlots, HostAndPort targetNode) {
w.lock();
try {
JedisPool targetPool = setupNodeIfNotExist(targetNode);
for (Integer slot : targetSlots) {
slots.put(slot, targetPool);
}
} finally {
w.unlock();
}
}
public JedisPool getNode(String nodeKey) {
r.lock();
try {
return nodes.get(nodeKey);
} finally {
r.unlock();
}
}
public JedisPool getSlotPool(int slot) {
r.lock();
try {
return slots.get(slot);
} finally {
r.unlock();
}
}
public Map<String, JedisPool> getNodes() {
r.lock();
try {
return new HashMap<String, JedisPool>(nodes);
} finally {
r.unlock();
}
}
public List<JedisPool> getShuffledNodesPool() {
r.lock();
try {
List<JedisPool> pools = new ArrayList<JedisPool>(nodes.values());
Collections.shuffle(pools);
return pools;
} finally {
r.unlock();
}
}
/**
* Clear discovered nodes collections and gently release allocated resources
*/
public void reset() {
w.lock();
try {
for (JedisPool pool : nodes.values()) {
try {
if (pool != null) {
pool.destroy();
}
} catch (Exception e) {
// pass
}
}
nodes.clear();
slots.clear();
} finally {
w.unlock();
}
}
public static String getNodeKey(HostAndPort hnp) {
return hnp.getHost() + ":" + hnp.getPort();
}
public static String getNodeKey(Client client) {
return client.getHost() + ":" + client.getPort();
}
public static String getNodeKey(Jedis jedis) {
return getNodeKey(jedis.getClient());
}
private List<Integer> getAssignedSlotArray(List<Object> slotInfo) {
List<Integer> slotNums = new ArrayList<Integer>();
for (int slot = ((Long) slotInfo.get(0)).intValue(); slot <= ((Long) slotInfo.get(1))
.intValue(); slot++) {
slotNums.add(slot);
}
return slotNums;
}
}

157
fine-jedis/src/com/fr/third/redis/clients/jedis/JedisFactory.java

@ -0,0 +1,157 @@
package com.fr.third.redis.clients.jedis;
import java.net.URI;
import java.util.concurrent.atomic.AtomicReference;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLParameters;
import javax.net.ssl.SSLSocketFactory;
import com.fr.third.org.apache.commons.pool2.PooledObject;
import com.fr.third.org.apache.commons.pool2.PooledObjectFactory;
import com.fr.third.org.apache.commons.pool2.impl.DefaultPooledObject;
import com.fr.third.redis.clients.jedis.exceptions.InvalidURIException;
import com.fr.third.redis.clients.jedis.exceptions.JedisException;
import com.fr.third.redis.clients.jedis.util.JedisURIHelper;
/**
* PoolableObjectFactory custom impl.
*/
class JedisFactory implements PooledObjectFactory<Jedis> {
private final AtomicReference<HostAndPort> hostAndPort = new AtomicReference<HostAndPort>();
private final int connectionTimeout;
private final int soTimeout;
private final String password;
private final int database;
private final String clientName;
private final boolean ssl;
private final SSLSocketFactory sslSocketFactory;
private final SSLParameters sslParameters;
private final HostnameVerifier hostnameVerifier;
JedisFactory(final String host, final int port, final int connectionTimeout,
final int soTimeout, final String password, final int database, final String clientName) {
this(host, port, connectionTimeout, soTimeout, password, database, clientName,
false, null, null, null);
}
JedisFactory(final String host, final int port, final int connectionTimeout,
final int soTimeout, final String password, final int database, final String clientName,
final boolean ssl, final SSLSocketFactory sslSocketFactory, final SSLParameters sslParameters,
final HostnameVerifier hostnameVerifier) {
this.hostAndPort.set(new HostAndPort(host, port));
this.connectionTimeout = connectionTimeout;
this.soTimeout = soTimeout;
this.password = password;
this.database = database;
this.clientName = clientName;
this.ssl = ssl;
this.sslSocketFactory = sslSocketFactory;
this.sslParameters = sslParameters;
this.hostnameVerifier = hostnameVerifier;
}
JedisFactory(final URI uri, final int connectionTimeout, final int soTimeout,
final String clientName) {
this(uri, connectionTimeout, soTimeout, clientName, null, null, null);
}
JedisFactory(final URI uri, final int connectionTimeout, final int soTimeout,
final String clientName, final SSLSocketFactory sslSocketFactory,
final SSLParameters sslParameters, final HostnameVerifier hostnameVerifier) {
if (!JedisURIHelper.isValid(uri)) {
throw new InvalidURIException(String.format(
"Cannot open Redis connection due invalid URI. %s", uri.toString()));
}
this.hostAndPort.set(new HostAndPort(uri.getHost(), uri.getPort()));
this.connectionTimeout = connectionTimeout;
this.soTimeout = soTimeout;
this.password = JedisURIHelper.getPassword(uri);
this.database = JedisURIHelper.getDBIndex(uri);
this.clientName = clientName;
this.ssl = JedisURIHelper.isRedisSSLScheme(uri);
this.sslSocketFactory = sslSocketFactory;
this.sslParameters = sslParameters;
this.hostnameVerifier = hostnameVerifier;
}
public void setHostAndPort(final HostAndPort hostAndPort) {
this.hostAndPort.set(hostAndPort);
}
@Override
public void activateObject(PooledObject<Jedis> pooledJedis) throws Exception {
final BinaryJedis jedis = pooledJedis.getObject();
if (jedis.getDB() != database) {
jedis.select(database);
}
}
@Override
public void destroyObject(PooledObject<Jedis> pooledJedis) throws Exception {
final BinaryJedis jedis = pooledJedis.getObject();
if (jedis.isConnected()) {
try {
try {
jedis.quit();
} catch (Exception e) {
}
jedis.disconnect();
} catch (Exception e) {
}
}
}
@Override
public PooledObject<Jedis> makeObject() throws Exception {
final HostAndPort hostAndPort = this.hostAndPort.get();
final Jedis jedis = new Jedis(hostAndPort.getHost(), hostAndPort.getPort(), connectionTimeout,
soTimeout, ssl, sslSocketFactory, sslParameters, hostnameVerifier);
try {
jedis.connect();
if (password != null) {
jedis.auth(password);
}
if (database != 0) {
jedis.select(database);
}
if (clientName != null) {
jedis.clientSetname(clientName);
}
} catch (JedisException je) {
jedis.close();
throw je;
}
return new DefaultPooledObject<Jedis>(jedis);
}
@Override
public void passivateObject(PooledObject<Jedis> pooledJedis) throws Exception {
// TODO maybe should select db 0? Not sure right now.
}
@Override
public boolean validateObject(PooledObject<Jedis> pooledJedis) {
final BinaryJedis jedis = pooledJedis.getObject();
try {
HostAndPort hostAndPort = this.hostAndPort.get();
String connectionHost = jedis.getClient().getHost();
int connectionPort = jedis.getClient().getPort();
return hostAndPort.getHost().equals(connectionHost)
&& hostAndPort.getPort() == connectionPort && jedis.isConnected()
&& jedis.ping().equals("PONG");
} catch (final Exception e) {
return false;
}
}
}

16
fine-jedis/src/com/fr/third/redis/clients/jedis/JedisMonitor.java

@ -0,0 +1,16 @@
package com.fr.third.redis.clients.jedis;
public abstract class JedisMonitor {
protected Client client;
public void proceed(Client client) {
this.client = client;
this.client.setTimeoutInfinite();
do {
String command = client.getBulkReply();
onCommand(command);
} while (client.isConnected());
}
public abstract void onCommand(String command);
}

258
fine-jedis/src/com/fr/third/redis/clients/jedis/JedisPool.java

@ -0,0 +1,258 @@
package com.fr.third.redis.clients.jedis;
import java.net.URI;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLParameters;
import javax.net.ssl.SSLSocketFactory;
import com.fr.third.org.apache.commons.pool2.impl.GenericObjectPool;
import com.fr.third.org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import com.fr.third.redis.clients.jedis.exceptions.JedisException;
import com.fr.third.redis.clients.jedis.util.JedisURIHelper;
public class JedisPool extends JedisPoolAbstract {
public JedisPool() {
this(Protocol.DEFAULT_HOST, Protocol.DEFAULT_PORT);
}
public JedisPool(final GenericObjectPoolConfig poolConfig, final String host) {
this(poolConfig, host, Protocol.DEFAULT_PORT);
}
public JedisPool(String host, int port) {
this(new GenericObjectPoolConfig(), host, port);
}
public JedisPool(final String host) {
URI uri = URI.create(host);
if (JedisURIHelper.isValid(uri)) {
this.internalPool = new GenericObjectPool<Jedis>(new JedisFactory(uri,
Protocol.DEFAULT_TIMEOUT, Protocol.DEFAULT_TIMEOUT, null), new GenericObjectPoolConfig());
} else {
this.internalPool = new GenericObjectPool<Jedis>(new JedisFactory(host,
Protocol.DEFAULT_PORT, Protocol.DEFAULT_TIMEOUT, Protocol.DEFAULT_TIMEOUT, null,
Protocol.DEFAULT_DATABASE, null), new GenericObjectPoolConfig());
}
}
public JedisPool(final String host, final SSLSocketFactory sslSocketFactory,
final SSLParameters sslParameters, final HostnameVerifier hostnameVerifier) {
URI uri = URI.create(host);
if (JedisURIHelper.isValid(uri)) {
this.internalPool = new GenericObjectPool<Jedis>(new JedisFactory(uri,
Protocol.DEFAULT_TIMEOUT, Protocol.DEFAULT_TIMEOUT, null, sslSocketFactory, sslParameters,
hostnameVerifier), new GenericObjectPoolConfig());
} else {
this.internalPool = new GenericObjectPool<Jedis>(new JedisFactory(host,
Protocol.DEFAULT_PORT, Protocol.DEFAULT_TIMEOUT, Protocol.DEFAULT_TIMEOUT, null,
Protocol.DEFAULT_DATABASE, null, false, null, null, null), new GenericObjectPoolConfig());
}
}
public JedisPool(final URI uri) {
this(new GenericObjectPoolConfig(), uri);
}
public JedisPool(final URI uri, final SSLSocketFactory sslSocketFactory,
final SSLParameters sslParameters, final HostnameVerifier hostnameVerifier) {
this(new GenericObjectPoolConfig(), uri, sslSocketFactory, sslParameters, hostnameVerifier);
}
public JedisPool(final URI uri, final int timeout) {
this(new GenericObjectPoolConfig(), uri, timeout);
}
public JedisPool(final URI uri, final int timeout, final SSLSocketFactory sslSocketFactory,
final SSLParameters sslParameters, final HostnameVerifier hostnameVerifier) {
this(new GenericObjectPoolConfig(), uri, timeout, sslSocketFactory, sslParameters,
hostnameVerifier);
}
public JedisPool(final GenericObjectPoolConfig poolConfig, final String host, int port,
int timeout, final String password) {
this(poolConfig, host, port, timeout, password, Protocol.DEFAULT_DATABASE);
}
public JedisPool(final GenericObjectPoolConfig poolConfig, final String host, int port,
int timeout, final String password, final boolean ssl) {
this(poolConfig, host, port, timeout, password, Protocol.DEFAULT_DATABASE, ssl);
}
public JedisPool(final GenericObjectPoolConfig poolConfig, final String host, int port,
int timeout, final String password, final boolean ssl,
final SSLSocketFactory sslSocketFactory, final SSLParameters sslParameters,
final HostnameVerifier hostnameVerifier) {
this(poolConfig, host, port, timeout, password, Protocol.DEFAULT_DATABASE, ssl,
sslSocketFactory, sslParameters, hostnameVerifier);
}
public JedisPool(final GenericObjectPoolConfig poolConfig, final String host, final int port) {
this(poolConfig, host, port, Protocol.DEFAULT_TIMEOUT);
}
public JedisPool(final GenericObjectPoolConfig poolConfig, final String host, final int port,
final boolean ssl) {
this(poolConfig, host, port, Protocol.DEFAULT_TIMEOUT, ssl);
}
public JedisPool(final GenericObjectPoolConfig poolConfig, final String host, final int port,
final boolean ssl, final SSLSocketFactory sslSocketFactory, final SSLParameters sslParameters,
final HostnameVerifier hostnameVerifier) {
this(poolConfig, host, port, Protocol.DEFAULT_TIMEOUT, ssl, sslSocketFactory, sslParameters,
hostnameVerifier);
}
public JedisPool(final GenericObjectPoolConfig poolConfig, final String host, final int port,
final int timeout) {
this(poolConfig, host, port, timeout, null);
}
public JedisPool(final GenericObjectPoolConfig poolConfig, final String host, final int port,
final int timeout, final boolean ssl) {
this(poolConfig, host, port, timeout, null, ssl);
}
public JedisPool(final GenericObjectPoolConfig poolConfig, final String host, final int port,
final int timeout, final boolean ssl, final SSLSocketFactory sslSocketFactory,
final SSLParameters sslParameters, final HostnameVerifier hostnameVerifier) {
this(poolConfig, host, port, timeout, null, ssl, sslSocketFactory, sslParameters,
hostnameVerifier);
}
public JedisPool(final GenericObjectPoolConfig poolConfig, final String host, int port,
int timeout, final String password, final int database) {
this(poolConfig, host, port, timeout, password, database, null);
}
public JedisPool(final GenericObjectPoolConfig poolConfig, final String host, int port,
int timeout, final String password, final int database, final boolean ssl) {
this(poolConfig, host, port, timeout, password, database, null, ssl);
}
public JedisPool(final GenericObjectPoolConfig poolConfig, final String host, int port,
int timeout, final String password, final int database, final boolean ssl,
final SSLSocketFactory sslSocketFactory, final SSLParameters sslParameters,
final HostnameVerifier hostnameVerifier) {
this(poolConfig, host, port, timeout, password, database, null, ssl, sslSocketFactory,
sslParameters, hostnameVerifier);
}
public JedisPool(final GenericObjectPoolConfig poolConfig, final String host, int port,
int timeout, final String password, final int database, final String clientName) {
this(poolConfig, host, port, timeout, timeout, password, database, clientName);
}
public JedisPool(final GenericObjectPoolConfig poolConfig, final String host, int port,
int timeout, final String password, final int database, final String clientName,
final boolean ssl) {
this(poolConfig, host, port, timeout, timeout, password, database, clientName, ssl);
}
public JedisPool(final GenericObjectPoolConfig poolConfig, final String host, int port,
int timeout, final String password, final int database, final String clientName,
final boolean ssl, final SSLSocketFactory sslSocketFactory,
final SSLParameters sslParameters, final HostnameVerifier hostnameVerifier) {
this(poolConfig, host, port, timeout, timeout, password, database, clientName, ssl,
sslSocketFactory, sslParameters, hostnameVerifier);
}
public JedisPool(final GenericObjectPoolConfig poolConfig, final String host, int port,
final int connectionTimeout, final int soTimeout, final String password, final int database,
final String clientName, final boolean ssl, final SSLSocketFactory sslSocketFactory,
final SSLParameters sslParameters, final HostnameVerifier hostnameVerifier) {
super(poolConfig, new JedisFactory(host, port, connectionTimeout, soTimeout, password,
database, clientName, ssl, sslSocketFactory, sslParameters, hostnameVerifier));
}
public JedisPool(final GenericObjectPoolConfig poolConfig) {
this(poolConfig, Protocol.DEFAULT_HOST, Protocol.DEFAULT_PORT);
}
public JedisPool(final String host, final int port, final boolean ssl) {
this(new GenericObjectPoolConfig(), host, port, ssl);
}
public JedisPool(final GenericObjectPoolConfig poolConfig, final String host, int port,
final int connectionTimeout, final int soTimeout, final String password, final int database,
final String clientName) {
super(poolConfig, new JedisFactory(host, port, connectionTimeout, soTimeout, password,
database, clientName));
}
public JedisPool(final String host, final int port, final boolean ssl,
final SSLSocketFactory sslSocketFactory, final SSLParameters sslParameters,
final HostnameVerifier hostnameVerifier) {
this(new GenericObjectPoolConfig(), host, port, ssl, sslSocketFactory, sslParameters,
hostnameVerifier);
}
public JedisPool(final GenericObjectPoolConfig poolConfig, final String host, final int port,
final int connectionTimeout, final int soTimeout, final String password, final int database,
final String clientName, final boolean ssl) {
this(poolConfig, host, port, connectionTimeout, soTimeout, password, database, clientName, ssl,
null, null, null);
}
public JedisPool(final GenericObjectPoolConfig poolConfig, final URI uri) {
this(poolConfig, uri, Protocol.DEFAULT_TIMEOUT);
}
public JedisPool(final GenericObjectPoolConfig poolConfig, final URI uri,
final SSLSocketFactory sslSocketFactory, final SSLParameters sslParameters,
final HostnameVerifier hostnameVerifier) {
this(poolConfig, uri, Protocol.DEFAULT_TIMEOUT, sslSocketFactory, sslParameters,
hostnameVerifier);
}
public JedisPool(final GenericObjectPoolConfig poolConfig, final URI uri, final int timeout) {
this(poolConfig, uri, timeout, timeout);
}
public JedisPool(final GenericObjectPoolConfig poolConfig, final URI uri, final int timeout,
final SSLSocketFactory sslSocketFactory, final SSLParameters sslParameters,
final HostnameVerifier hostnameVerifier) {
this(poolConfig, uri, timeout, timeout, sslSocketFactory, sslParameters, hostnameVerifier);
}
public JedisPool(final GenericObjectPoolConfig poolConfig, final URI uri,
final int connectionTimeout, final int soTimeout) {
super(poolConfig, new JedisFactory(uri, connectionTimeout, soTimeout, null));
}
public JedisPool(final GenericObjectPoolConfig poolConfig, final URI uri,
final int connectionTimeout, final int soTimeout, final SSLSocketFactory sslSocketFactory,
final SSLParameters sslParameters, final HostnameVerifier hostnameVerifier) {
super(poolConfig, new JedisFactory(uri, connectionTimeout, soTimeout, null, sslSocketFactory,
sslParameters, hostnameVerifier));
}
@Override
public Jedis getResource() {
Jedis jedis = super.getResource();
jedis.setDataSource(this);
return jedis;
}
@Override
protected void returnBrokenResource(final Jedis resource) {
if (resource != null) {
returnBrokenResourceObject(resource);
}
}
@Override
protected void returnResource(final Jedis resource) {
if (resource != null) {
try {
resource.resetState();
returnResourceObject(resource);
} catch (Exception e) {
returnBrokenResource(resource);
throw new JedisException("Could not return the resource to the pool", e);
}
}
}
}

27
fine-jedis/src/com/fr/third/redis/clients/jedis/JedisPoolAbstract.java

@ -0,0 +1,27 @@
package com.fr.third.redis.clients.jedis;
import com.fr.third.org.apache.commons.pool2.PooledObjectFactory;
import com.fr.third.org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import com.fr.third.redis.clients.jedis.util.Pool;
public class JedisPoolAbstract extends Pool<Jedis> {
public JedisPoolAbstract() {
super();
}
public JedisPoolAbstract(GenericObjectPoolConfig poolConfig, PooledObjectFactory<Jedis> factory) {
super(poolConfig, factory);
}
@Override
protected void returnBrokenResource(Jedis resource) {
super.returnBrokenResource(resource);
}
@Override
protected void returnResource(Jedis resource) {
super.returnResource(resource);
}
}

13
fine-jedis/src/com/fr/third/redis/clients/jedis/JedisPoolConfig.java

@ -0,0 +1,13 @@
package com.fr.third.redis.clients.jedis;
import com.fr.third.org.apache.commons.pool2.impl.GenericObjectPoolConfig;
public class JedisPoolConfig extends GenericObjectPoolConfig {
public JedisPoolConfig() {
// defaults to make your life with connection pool easier :)
setTestWhileIdle(true);
setMinEvictableIdleTimeMillis(60000);
setTimeBetweenEvictionRunsMillis(30000);
setNumTestsPerEvictionRun(-1);
}
}

179
fine-jedis/src/com/fr/third/redis/clients/jedis/JedisPubSub.java

@ -0,0 +1,179 @@
package com.fr.third.redis.clients.jedis;
import static com.fr.third.redis.clients.jedis.Protocol.Keyword.MESSAGE;
import static com.fr.third.redis.clients.jedis.Protocol.Keyword.PMESSAGE;
import static com.fr.third.redis.clients.jedis.Protocol.Keyword.PSUBSCRIBE;
import static com.fr.third.redis.clients.jedis.Protocol.Keyword.PUNSUBSCRIBE;
import static com.fr.third.redis.clients.jedis.Protocol.Keyword.SUBSCRIBE;
import static com.fr.third.redis.clients.jedis.Protocol.Keyword.UNSUBSCRIBE;
import static com.fr.third.redis.clients.jedis.Protocol.Keyword.PONG;
import java.util.Arrays;
import java.util.List;
import com.fr.third.redis.clients.jedis.exceptions.JedisConnectionException;
import com.fr.third.redis.clients.jedis.exceptions.JedisException;
import com.fr.third.redis.clients.jedis.util.SafeEncoder;
public abstract class JedisPubSub {
private static final String JEDIS_SUBSCRIPTION_MESSAGE = "JedisPubSub is not subscribed to a Jedis instance.";
private int subscribedChannels = 0;
private volatile Client client;
public void onMessage(String channel, String message) {
}
public void onPMessage(String pattern, String channel, String message) {
}
public void onSubscribe(String channel, int subscribedChannels) {
}
public void onUnsubscribe(String channel, int subscribedChannels) {
}
public void onPUnsubscribe(String pattern, int subscribedChannels) {
}
public void onPSubscribe(String pattern, int subscribedChannels) {
}
public void onPong(String pattern) {
}
public void unsubscribe() {
if (client == null) {
throw new JedisConnectionException(JEDIS_SUBSCRIPTION_MESSAGE);
}
client.unsubscribe();
client.flush();
}
public void unsubscribe(String... channels) {
if (client == null) {
throw new JedisConnectionException(JEDIS_SUBSCRIPTION_MESSAGE);
}
client.unsubscribe(channels);
client.flush();
}
public void subscribe(String... channels) {
if (client == null) {
throw new JedisConnectionException(JEDIS_SUBSCRIPTION_MESSAGE);
}
client.subscribe(channels);
client.flush();
}
public void psubscribe(String... patterns) {
if (client == null) {
throw new JedisConnectionException(JEDIS_SUBSCRIPTION_MESSAGE);
}
client.psubscribe(patterns);
client.flush();
}
public void punsubscribe() {
if (client == null) {
throw new JedisConnectionException(JEDIS_SUBSCRIPTION_MESSAGE);
}
client.punsubscribe();
client.flush();
}
public void punsubscribe(String... patterns) {
if (client == null) {
throw new JedisConnectionException(JEDIS_SUBSCRIPTION_MESSAGE);
}
client.punsubscribe(patterns);
client.flush();
}
public void ping() {
if (client == null) {
throw new JedisConnectionException(JEDIS_SUBSCRIPTION_MESSAGE);
}
client.ping();
client.flush();
}
public boolean isSubscribed() {
return subscribedChannels > 0;
}
public void proceedWithPatterns(Client client, String... patterns) {
this.client = client;
client.psubscribe(patterns);
client.flush();
process(client);
}
public void proceed(Client client, String... channels) {
this.client = client;
client.subscribe(channels);
client.flush();
process(client);
}
private void process(Client client) {
do {
List<Object> reply = client.getRawObjectMultiBulkReply();
final Object firstObj = reply.get(0);
if (!(firstObj instanceof byte[])) {
throw new JedisException("Unknown message type: " + firstObj);
}
final byte[] resp = (byte[]) firstObj;
if (Arrays.equals(SUBSCRIBE.raw, resp)) {
subscribedChannels = ((Long) reply.get(2)).intValue();
final byte[] bchannel = (byte[]) reply.get(1);
final String strchannel = (bchannel == null) ? null : SafeEncoder.encode(bchannel);
onSubscribe(strchannel, subscribedChannels);
} else if (Arrays.equals(UNSUBSCRIBE.raw, resp)) {
subscribedChannels = ((Long) reply.get(2)).intValue();
final byte[] bchannel = (byte[]) reply.get(1);
final String strchannel = (bchannel == null) ? null : SafeEncoder.encode(bchannel);
onUnsubscribe(strchannel, subscribedChannels);
} else if (Arrays.equals(MESSAGE.raw, resp)) {
final byte[] bchannel = (byte[]) reply.get(1);
final byte[] bmesg = (byte[]) reply.get(2);
final String strchannel = (bchannel == null) ? null : SafeEncoder.encode(bchannel);
final String strmesg = (bmesg == null) ? null : SafeEncoder.encode(bmesg);
onMessage(strchannel, strmesg);
} else if (Arrays.equals(PMESSAGE.raw, resp)) {
final byte[] bpattern = (byte[]) reply.get(1);
final byte[] bchannel = (byte[]) reply.get(2);
final byte[] bmesg = (byte[]) reply.get(3);
final String strpattern = (bpattern == null) ? null : SafeEncoder.encode(bpattern);
final String strchannel = (bchannel == null) ? null : SafeEncoder.encode(bchannel);
final String strmesg = (bmesg == null) ? null : SafeEncoder.encode(bmesg);
onPMessage(strpattern, strchannel, strmesg);
} else if (Arrays.equals(PSUBSCRIBE.raw, resp)) {
subscribedChannels = ((Long) reply.get(2)).intValue();
final byte[] bpattern = (byte[]) reply.get(1);
final String strpattern = (bpattern == null) ? null : SafeEncoder.encode(bpattern);
onPSubscribe(strpattern, subscribedChannels);
} else if (Arrays.equals(PUNSUBSCRIBE.raw, resp)) {
subscribedChannels = ((Long) reply.get(2)).intValue();
final byte[] bpattern = (byte[]) reply.get(1);
final String strpattern = (bpattern == null) ? null : SafeEncoder.encode(bpattern);
onPUnsubscribe(strpattern, subscribedChannels);
} else if (Arrays.equals(PONG.raw, resp)) {
final byte[] bpattern = (byte[]) reply.get(1);
final String strpattern = (bpattern == null) ? null : SafeEncoder.encode(bpattern);
onPong(strpattern);
} else {
throw new JedisException("Unknown message type: " + firstObj);
}
} while (isSubscribed());
/* Invalidate instance since this thread is no longer listening */
this.client = null;
}
public int getSubscribedChannels() {
return subscribedChannels;
}
}

348
fine-jedis/src/com/fr/third/redis/clients/jedis/JedisSentinelPool.java

@ -0,0 +1,348 @@
package com.fr.third.redis.clients.jedis;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
import com.fr.third.org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.fr.third.redis.clients.jedis.exceptions.JedisConnectionException;
import com.fr.third.redis.clients.jedis.exceptions.JedisException;
public class JedisSentinelPool extends JedisPoolAbstract {
protected GenericObjectPoolConfig poolConfig;
protected int connectionTimeout = Protocol.DEFAULT_TIMEOUT;
protected int soTimeout = Protocol.DEFAULT_TIMEOUT;
protected String password;
protected int database = Protocol.DEFAULT_DATABASE;
protected String clientName;
protected Set<MasterListener> masterListeners = new HashSet<MasterListener>();
protected Logger log = LoggerFactory.getLogger(getClass().getName());
private volatile JedisFactory factory;
private volatile HostAndPort currentHostMaster;
public JedisSentinelPool(String masterName, Set<String> sentinels,
final GenericObjectPoolConfig poolConfig) {
this(masterName, sentinels, poolConfig, Protocol.DEFAULT_TIMEOUT, null,
Protocol.DEFAULT_DATABASE);
}
public JedisSentinelPool(String masterName, Set<String> sentinels) {
this(masterName, sentinels, new GenericObjectPoolConfig(), Protocol.DEFAULT_TIMEOUT, null,
Protocol.DEFAULT_DATABASE);
}
public JedisSentinelPool(String masterName, Set<String> sentinels, String password) {
this(masterName, sentinels, new GenericObjectPoolConfig(), Protocol.DEFAULT_TIMEOUT, password);
}
public JedisSentinelPool(String masterName, Set<String> sentinels,
final GenericObjectPoolConfig poolConfig, int timeout, final String password) {
this(masterName, sentinels, poolConfig, timeout, password, Protocol.DEFAULT_DATABASE);
}
public JedisSentinelPool(String masterName, Set<String> sentinels,
final GenericObjectPoolConfig poolConfig, final int timeout) {
this(masterName, sentinels, poolConfig, timeout, null, Protocol.DEFAULT_DATABASE);
}
public JedisSentinelPool(String masterName, Set<String> sentinels,
final GenericObjectPoolConfig poolConfig, final String password) {
this(masterName, sentinels, poolConfig, Protocol.DEFAULT_TIMEOUT, password);
}
public JedisSentinelPool(String masterName, Set<String> sentinels,
final GenericObjectPoolConfig poolConfig, int timeout, final String password,
final int database) {
this(masterName, sentinels, poolConfig, timeout, timeout, password, database);
}
public JedisSentinelPool(String masterName, Set<String> sentinels,
final GenericObjectPoolConfig poolConfig, int timeout, final String password,
final int database, final String clientName) {
this(masterName, sentinels, poolConfig, timeout, timeout, password, database, clientName);
}
public JedisSentinelPool(String masterName, Set<String> sentinels,
final GenericObjectPoolConfig poolConfig, final int timeout, final int soTimeout,
final String password, final int database) {
this(masterName, sentinels, poolConfig, timeout, soTimeout, password, database, null);
}
public JedisSentinelPool(String masterName, Set<String> sentinels,
final GenericObjectPoolConfig poolConfig, final int connectionTimeout, final int soTimeout,
final String password, final int database, final String clientName) {
this.poolConfig = poolConfig;
this.connectionTimeout = connectionTimeout;
this.soTimeout = soTimeout;
this.password = password;
this.database = database;
this.clientName = clientName;
HostAndPort master = initSentinels(sentinels, masterName);
initPool(master);
}
@Override
public void destroy() {
for (MasterListener m : masterListeners) {
m.shutdown();
}
super.destroy();
}
public HostAndPort getCurrentHostMaster() {
return currentHostMaster;
}
private void initPool(HostAndPort master) {
if (!master.equals(currentHostMaster)) {
currentHostMaster = master;
if (factory == null) {
factory = new JedisFactory(master.getHost(), master.getPort(), connectionTimeout,
soTimeout, password, database, clientName);
initPool(poolConfig, factory);
} else {
factory.setHostAndPort(currentHostMaster);
// although we clear the pool, we still have to check the
// returned object
// in getResource, this call only clears idle instances, not
// borrowed instances
internalPool.clear();
}
log.info("Created JedisPool to master at " + master);
}
}
private HostAndPort initSentinels(Set<String> sentinels, final String masterName) {
HostAndPort master = null;
boolean sentinelAvailable = false;
log.info("Trying to find master from available Sentinels...");
for (String sentinel : sentinels) {
final HostAndPort hap = HostAndPort.parseString(sentinel);
log.debug("Connecting to Sentinel {}", hap);
Jedis jedis = null;
try {
jedis = new Jedis(hap);
List<String> masterAddr = jedis.sentinelGetMasterAddrByName(masterName);
// connected to sentinel...
sentinelAvailable = true;
if (masterAddr == null || masterAddr.size() != 2) {
log.warn("Can not get master addr, master name: {}. Sentinel: {}", masterName, hap);
continue;
}
master = toHostAndPort(masterAddr);
log.debug("Found Redis master at {}", master);
break;
} catch (JedisException e) {
// resolves #1036, it should handle JedisException there's another chance
// of raising JedisDataException
log.warn(
"Cannot get master address from sentinel running @ {}. Reason: {}. Trying next one.", hap,
e.toString());
} finally {
if (jedis != null) {
jedis.close();
}
}
}
if (master == null) {
if (sentinelAvailable) {
// can connect to sentinel, but master name seems to not
// monitored
throw new JedisException("Can connect to sentinel, but " + masterName
+ " seems to be not monitored...");
} else {
throw new JedisConnectionException("All sentinels down, cannot determine where is "
+ masterName + " master is running...");
}
}
log.info("Redis master running at " + master + ", starting Sentinel listeners...");
for (String sentinel : sentinels) {
final HostAndPort hap = HostAndPort.parseString(sentinel);
MasterListener masterListener = new MasterListener(masterName, hap.getHost(), hap.getPort());
// whether MasterListener threads are alive or not, process can be stopped
masterListener.setDaemon(true);
masterListeners.add(masterListener);
masterListener.start();
}
return master;
}
private HostAndPort toHostAndPort(List<String> getMasterAddrByNameResult) {
String host = getMasterAddrByNameResult.get(0);
int port = Integer.parseInt(getMasterAddrByNameResult.get(1));
return new HostAndPort(host, port);
}
@Override
public Jedis getResource() {
while (true) {
Jedis jedis = super.getResource();
jedis.setDataSource(this);
// get a reference because it can change concurrently
final HostAndPort master = currentHostMaster;
final HostAndPort connection = new HostAndPort(jedis.getClient().getHost(), jedis.getClient()
.getPort());
if (master.equals(connection)) {
// connected to the correct master
return jedis;
} else {
returnBrokenResource(jedis);
}
}
}
@Override
protected void returnBrokenResource(final Jedis resource) {
if (resource != null) {
returnBrokenResourceObject(resource);
}
}
@Override
protected void returnResource(final Jedis resource) {
if (resource != null) {
resource.resetState();
returnResourceObject(resource);
}
}
protected class MasterListener extends Thread {
protected String masterName;
protected String host;
protected int port;
protected long subscribeRetryWaitTimeMillis = 5000;
protected volatile Jedis j;
protected AtomicBoolean running = new AtomicBoolean(false);
protected MasterListener() {
}
public MasterListener(String masterName, String host, int port) {
super(String.format("MasterListener-%s-[%s:%d]", masterName, host, port));
this.masterName = masterName;
this.host = host;
this.port = port;
}
public MasterListener(String masterName, String host, int port,
long subscribeRetryWaitTimeMillis) {
this(masterName, host, port);
this.subscribeRetryWaitTimeMillis = subscribeRetryWaitTimeMillis;
}
@Override
public void run() {
running.set(true);
while (running.get()) {
j = new Jedis(host, port);
try {
// double check that it is not being shutdown
if (!running.get()) {
break;
}
/*
* Added code for active refresh
*/
List<String> masterAddr = j.sentinelGetMasterAddrByName(masterName);
if (masterAddr == null || masterAddr.size() != 2) {
log.warn("Can not get master addr, master name: {}. Sentinel: {}:{}.",masterName,host,port);
}else{
initPool(toHostAndPort(masterAddr));
}
j.subscribe(new JedisPubSub() {
@Override
public void onMessage(String channel, String message) {
log.debug("Sentinel {}:{} published: {}.", host, port, message);
String[] switchMasterMsg = message.split(" ");
if (switchMasterMsg.length > 3) {
if (masterName.equals(switchMasterMsg[0])) {
initPool(toHostAndPort(Arrays.asList(switchMasterMsg[3], switchMasterMsg[4])));
} else {
log.debug(
"Ignoring message on +switch-master for master name {}, our master name is {}",
switchMasterMsg[0], masterName);
}
} else {
log.error(
"Invalid message received on Sentinel {}:{} on channel +switch-master: {}", host,
port, message);
}
}
}, "+switch-master");
} catch (JedisException e) {
if (running.get()) {
log.error("Lost connection to Sentinel at {}:{}. Sleeping 5000ms and retrying.", host,
port, e);
try {
Thread.sleep(subscribeRetryWaitTimeMillis);
} catch (InterruptedException e1) {
log.error("Sleep interrupted: ", e1);
}
} else {
log.debug("Unsubscribing from Sentinel at {}:{}", host, port);
}
} finally {
j.close();
}
}
}
public void shutdown() {
try {
log.debug("Shutting down listener on {}:{}", host, port);
running.set(false);
// This isn't good, the Jedis object is not thread safe
if (j != null) {
j.disconnect();
}
} catch (Exception e) {
log.error("Caught exception while shutting down: ", e);
}
}
}
}

252
fine-jedis/src/com/fr/third/redis/clients/jedis/JedisShardInfo.java

@ -0,0 +1,252 @@
package com.fr.third.redis.clients.jedis;
import java.net.URI;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLParameters;
import javax.net.ssl.SSLSocketFactory;
import com.fr.third.redis.clients.jedis.exceptions.InvalidURIException;
import com.fr.third.redis.clients.jedis.util.JedisURIHelper;
import com.fr.third.redis.clients.jedis.util.ShardInfo;
import com.fr.third.redis.clients.jedis.util.Sharded;
public class JedisShardInfo extends ShardInfo<Jedis> {
private int connectionTimeout;
private int soTimeout;
private String host;
private int port;
private String password = null;
private String name = null;
// Default Redis DB
private int db = 0;
private boolean ssl;
private SSLSocketFactory sslSocketFactory;
private SSLParameters sslParameters;
private HostnameVerifier hostnameVerifier;
public JedisShardInfo(String host) {
super(Sharded.DEFAULT_WEIGHT);
URI uri = URI.create(host);
if (JedisURIHelper.isValid(uri)) {
this.host = uri.getHost();
this.port = uri.getPort();
this.password = JedisURIHelper.getPassword(uri);
this.db = JedisURIHelper.getDBIndex(uri);
this.ssl = JedisURIHelper.isRedisSSLScheme(uri);
} else {
this.host = host;
this.port = Protocol.DEFAULT_PORT;
}
}
public JedisShardInfo(String host, SSLSocketFactory sslSocketFactory,
SSLParameters sslParameters, HostnameVerifier hostnameVerifier) {
this(host);
this.sslSocketFactory = sslSocketFactory;
this.sslParameters = sslParameters;
this.hostnameVerifier = hostnameVerifier;
}
public JedisShardInfo(String host, String name) {
this(host, Protocol.DEFAULT_PORT, name);
}
public JedisShardInfo(HostAndPort hp) {
this(hp.getHost(), hp.getPort());
}
public JedisShardInfo(String host, int port) {
this(host, port, Protocol.DEFAULT_TIMEOUT);
}
public JedisShardInfo(String host, int port, boolean ssl) {
this(host, port, Protocol.DEFAULT_TIMEOUT, ssl);
}
public JedisShardInfo(String host, int port, boolean ssl, SSLSocketFactory sslSocketFactory,
SSLParameters sslParameters, HostnameVerifier hostnameVerifier) {
this(host, port, Protocol.DEFAULT_TIMEOUT, ssl, sslSocketFactory, sslParameters,
hostnameVerifier);
}
public JedisShardInfo(String host, int port, String name) {
this(host, port, Protocol.DEFAULT_TIMEOUT, name);
}
public JedisShardInfo(String host, int port, String name, boolean ssl) {
this(host, port, Protocol.DEFAULT_TIMEOUT, name, ssl);
}
public JedisShardInfo(String host, int port, String name, boolean ssl, SSLSocketFactory sslSocketFactory,
SSLParameters sslParameters, HostnameVerifier hostnameVerifier) {
this(host, port, Protocol.DEFAULT_TIMEOUT, name, ssl, sslSocketFactory, sslParameters, hostnameVerifier);
}
public JedisShardInfo(String host, int port, int timeout) {
this(host, port, timeout, timeout, Sharded.DEFAULT_WEIGHT);
}
public JedisShardInfo(String host, int port, int timeout, boolean ssl) {
this(host, port, timeout, timeout, Sharded.DEFAULT_WEIGHT, ssl);
}
public JedisShardInfo(String host, int port, int timeout, boolean ssl,
SSLSocketFactory sslSocketFactory, SSLParameters sslParameters,
HostnameVerifier hostnameVerifier) {
this(host, port, timeout, timeout, Sharded.DEFAULT_WEIGHT, ssl, sslSocketFactory,
sslParameters, hostnameVerifier);
}
public JedisShardInfo(String host, int port, int timeout, String name) {
this(host, port, timeout, timeout, Sharded.DEFAULT_WEIGHT);
this.name = name;
}
public JedisShardInfo(String host, int port, int timeout, String name, boolean ssl) {
this(host, port, timeout, timeout, Sharded.DEFAULT_WEIGHT, ssl);
this.name = name;
}
public JedisShardInfo(String host, int port, int timeout, String name, boolean ssl,
SSLSocketFactory sslSocketFactory, SSLParameters sslParameters,
HostnameVerifier hostnameVerifier) {
this(host, port, timeout, ssl, sslSocketFactory, sslParameters, hostnameVerifier);
this.name = name;
}
public JedisShardInfo(String host, int port, int connectionTimeout, int soTimeout, int weight) {
super(weight);
this.host = host;
this.port = port;
this.connectionTimeout = connectionTimeout;
this.soTimeout = soTimeout;
}
public JedisShardInfo(String host, int port, int connectionTimeout, int soTimeout, int weight,
boolean ssl) {
super(weight);
this.host = host;
this.port = port;
this.connectionTimeout = connectionTimeout;
this.soTimeout = soTimeout;
this.ssl = ssl;
}
public JedisShardInfo(String host, int port, int connectionTimeout, int soTimeout, int weight,
boolean ssl, SSLSocketFactory sslSocketFactory, SSLParameters sslParameters,
HostnameVerifier hostnameVerifier) {
this(host, port, connectionTimeout, soTimeout, weight, ssl);
this.sslSocketFactory = sslSocketFactory;
this.sslParameters = sslParameters;
this.hostnameVerifier = hostnameVerifier;
}
public JedisShardInfo(String host, String name, int port, int timeout, int weight) {
this(host, port, timeout, timeout, weight);
this.name = name;
}
public JedisShardInfo(String host, String name, int port, int timeout, int weight, boolean ssl) {
this(host, port, timeout, timeout, weight, ssl);
this.name = name;
}
public JedisShardInfo(String host, String name, int port, int timeout, int weight,
boolean ssl, SSLSocketFactory sslSocketFactory, SSLParameters sslParameters,
HostnameVerifier hostnameVerifier) {
this(host, port, timeout, timeout, weight, ssl, sslSocketFactory, sslParameters, hostnameVerifier);
this.name = name;
}
public JedisShardInfo(URI uri) {
super(Sharded.DEFAULT_WEIGHT);
if (!JedisURIHelper.isValid(uri)) {
throw new InvalidURIException(String.format(
"Cannot open Redis connection due invalid URI. %s", uri.toString()));
}
this.host = uri.getHost();
this.port = uri.getPort();
this.password = JedisURIHelper.getPassword(uri);
this.db = JedisURIHelper.getDBIndex(uri);
this.ssl = JedisURIHelper.isRedisSSLScheme(uri);
}
public JedisShardInfo(URI uri, SSLSocketFactory sslSocketFactory, SSLParameters sslParameters,
HostnameVerifier hostnameVerifier) {
this(uri);
this.sslSocketFactory = sslSocketFactory;
this.sslParameters = sslParameters;
this.hostnameVerifier = hostnameVerifier;
}
@Override
public String toString() {
return host + ":" + port + "*" + getWeight();
}
public String getHost() {
return host;
}
public int getPort() {
return port;
}
public String getPassword() {
return password;
}
public void setPassword(String auth) {
this.password = auth;
}
public int getConnectionTimeout() {
return connectionTimeout;
}
public void setConnectionTimeout(int connectionTimeout) {
this.connectionTimeout = connectionTimeout;
}
public int getSoTimeout() {
return soTimeout;
}
public void setSoTimeout(int soTimeout) {
this.soTimeout = soTimeout;
}
@Override
public String getName() {
return name;
}
public int getDb() {
return db;
}
public boolean getSsl() {
return ssl;
}
public SSLSocketFactory getSslSocketFactory() {
return sslSocketFactory;
}
public SSLParameters getSslParameters() {
return sslParameters;
}
public HostnameVerifier getHostnameVerifier() {
return hostnameVerifier;
}
@Override
public Jedis createResource() {
return new Jedis(this);
}
}

82
fine-jedis/src/com/fr/third/redis/clients/jedis/JedisSlotBasedConnectionHandler.java

@ -0,0 +1,82 @@
package com.fr.third.redis.clients.jedis;
import java.util.List;
import java.util.Set;
import com.fr.third.org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import com.fr.third.redis.clients.jedis.exceptions.JedisException;
import com.fr.third.redis.clients.jedis.exceptions.JedisNoReachableClusterNodeException;
public class JedisSlotBasedConnectionHandler extends JedisClusterConnectionHandler {
public JedisSlotBasedConnectionHandler(Set<HostAndPort> nodes,
final GenericObjectPoolConfig poolConfig, int timeout) {
this(nodes, poolConfig, timeout, timeout);
}
public JedisSlotBasedConnectionHandler(Set<HostAndPort> nodes,
final GenericObjectPoolConfig poolConfig, int connectionTimeout, int soTimeout) {
super(nodes, poolConfig, connectionTimeout, soTimeout, null);
}
public JedisSlotBasedConnectionHandler(Set<HostAndPort> nodes, GenericObjectPoolConfig poolConfig, int connectionTimeout, int soTimeout, String password) {
super(nodes, poolConfig, connectionTimeout, soTimeout, password);
}
public JedisSlotBasedConnectionHandler(Set<HostAndPort> nodes, GenericObjectPoolConfig poolConfig, int connectionTimeout, int soTimeout, String password, String clientName) {
super(nodes, poolConfig, connectionTimeout, soTimeout, password, clientName);
}
@Override
public Jedis getConnection() {
// In antirez's redis-rb-cluster implementation,
// getRandomConnection always return valid connection (able to
// ping-pong)
// or exception if all connections are invalid
List<JedisPool> pools = cache.getShuffledNodesPool();
for (JedisPool pool : pools) {
Jedis jedis = null;
try {
jedis = pool.getResource();
if (jedis == null) {
continue;
}
String result = jedis.ping();
if (result.equalsIgnoreCase("pong")) return jedis;
jedis.close();
} catch (JedisException ex) {
if (jedis != null) {
jedis.close();
}
}
}
throw new JedisNoReachableClusterNodeException("No reachable node in cluster");
}
@Override
public Jedis getConnectionFromSlot(int slot) {
JedisPool connectionPool = cache.getSlotPool(slot);
if (connectionPool != null) {
// It can't guaranteed to get valid connection because of node
// assignment
return connectionPool.getResource();
} else {
renewSlotCache(); //It's abnormal situation for cluster mode, that we have just nothing for slot, try to rediscover state
connectionPool = cache.getSlotPool(slot);
if (connectionPool != null) {
return connectionPool.getResource();
} else {
//no choice, fallback to new connection to random node
return getConnection();
}
}
}
}

12
fine-jedis/src/com/fr/third/redis/clients/jedis/ListPosition.java

@ -0,0 +1,12 @@
package com.fr.third.redis.clients.jedis;
import com.fr.third.redis.clients.jedis.util.SafeEncoder;
public enum ListPosition {
BEFORE, AFTER;
public final byte[] raw;
private ListPosition() {
raw = SafeEncoder.encode(name());
}
}

41
fine-jedis/src/com/fr/third/redis/clients/jedis/Module.java

@ -0,0 +1,41 @@
package com.fr.third.redis.clients.jedis;
public class Module {
private String name;
private int version;
public Module(String name, int version) {
this.name = name;
this.version = version;
}
public String getName() {
return name;
}
public int getVersion() {
return version;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Module module = (Module) o;
if (version != module.version) return false;
return !(name != null ? !name.equals(module.name) : module.name != null);
}
@Override
public int hashCode() {
int result = name != null ? name.hashCode() : 0;
result = 31 * result + version;
return result;
}
}

692
fine-jedis/src/com/fr/third/redis/clients/jedis/MultiKeyPipelineBase.java

@ -0,0 +1,692 @@
package com.fr.third.redis.clients.jedis;
import com.fr.third.redis.clients.jedis.commands.*;
import java.util.List;
import java.util.Map;
import java.util.Set;
public abstract class MultiKeyPipelineBase extends PipelineBase implements
MultiKeyBinaryRedisPipeline, MultiKeyCommandsPipeline, ClusterPipeline,
BinaryScriptingCommandsPipeline, ScriptingCommandsPipeline, BasicRedisPipeline {
protected Client client = null;
@Override
public Response<List<String>> brpop(String... args) {
client.brpop(args);
return getResponse(BuilderFactory.STRING_LIST);
}
public Response<List<String>> brpop(int timeout, String... keys) {
client.brpop(timeout, keys);
return getResponse(BuilderFactory.STRING_LIST);
}
@Override
public Response<List<String>> blpop(String... args) {
client.blpop(args);
return getResponse(BuilderFactory.STRING_LIST);
}
public Response<List<String>> blpop(int timeout, String... keys) {
client.blpop(timeout, keys);
return getResponse(BuilderFactory.STRING_LIST);
}
public Response<Map<String, String>> blpopMap(int timeout, String... keys) {
client.blpop(timeout, keys);
return getResponse(BuilderFactory.STRING_MAP);
}
@Override
public Response<List<byte[]>> brpop(byte[]... args) {
client.brpop(args);
return getResponse(BuilderFactory.BYTE_ARRAY_LIST);
}
public Response<List<String>> brpop(int timeout, byte[]... keys) {
client.brpop(timeout, keys);
return getResponse(BuilderFactory.STRING_LIST);
}
public Response<Map<String, String>> brpopMap(int timeout, String... keys) {
client.blpop(timeout, keys);
return getResponse(BuilderFactory.STRING_MAP);
}
@Override
public Response<List<byte[]>> blpop(byte[]... args) {
client.blpop(args);
return getResponse(BuilderFactory.BYTE_ARRAY_LIST);
}
public Response<List<String>> blpop(int timeout, byte[]... keys) {
client.blpop(timeout, keys);
return getResponse(BuilderFactory.STRING_LIST);
}
@Override
public Response<Long> del(String... keys) {
client.del(keys);
return getResponse(BuilderFactory.LONG);
}
@Override
public Response<Long> del(byte[]... keys) {
client.del(keys);
return getResponse(BuilderFactory.LONG);
}
@Override
public Response<Long> unlink(String... keys) {
client.unlink(keys);
return getResponse(BuilderFactory.LONG);
}
@Override
public Response<Long> unlink(byte[]... keys) {
client.unlink(keys);
return getResponse(BuilderFactory.LONG);
}
@Override
public Response<Long> exists(String... keys) {
client.exists(keys);
return getResponse(BuilderFactory.LONG);
}
@Override
public Response<Long> exists(byte[]... keys) {
client.exists(keys);
return getResponse(BuilderFactory.LONG);
}
@Override
public Response<Set<String>> keys(String pattern) {
getClient(pattern).keys(pattern);
return getResponse(BuilderFactory.STRING_SET);
}
@Override
public Response<Set<byte[]>> keys(byte[] pattern) {
getClient(pattern).keys(pattern);
return getResponse(BuilderFactory.BYTE_ARRAY_ZSET);
}
@Override
public Response<List<String>> mget(String... keys) {
client.mget(keys);
return getResponse(BuilderFactory.STRING_LIST);
}
@Override
public Response<List<byte[]>> mget(byte[]... keys) {
client.mget(keys);
return getResponse(BuilderFactory.BYTE_ARRAY_LIST);
}
@Override
public Response<String> mset(String... keysvalues) {
client.mset(keysvalues);
return getResponse(BuilderFactory.STRING);
}
@Override
public Response<String> mset(byte[]... keysvalues) {
client.mset(keysvalues);
return getResponse(BuilderFactory.STRING);
}
@Override
public Response<Long> msetnx(String... keysvalues) {
client.msetnx(keysvalues);
return getResponse(BuilderFactory.LONG);
}
@Override
public Response<Long> msetnx(byte[]... keysvalues) {
client.msetnx(keysvalues);
return getResponse(BuilderFactory.LONG);
}
@Override
public Response<String> rename(String oldkey, String newkey) {
client.rename(oldkey, newkey);
return getResponse(BuilderFactory.STRING);
}
@Override
public Response<String> rename(byte[] oldkey, byte[] newkey) {
client.rename(oldkey, newkey);
return getResponse(BuilderFactory.STRING);
}
@Override
public Response<Long> renamenx(String oldkey, String newkey) {
client.renamenx(oldkey, newkey);
return getResponse(BuilderFactory.LONG);
}
@Override
public Response<Long> renamenx(byte[] oldkey, byte[] newkey) {
client.renamenx(oldkey, newkey);
return getResponse(BuilderFactory.LONG);
}
@Override
public Response<String> rpoplpush(String srckey, String dstkey) {
client.rpoplpush(srckey, dstkey);
return getResponse(BuilderFactory.STRING);
}
@Override
public Response<byte[]> rpoplpush(byte[] srckey, byte[] dstkey) {
client.rpoplpush(srckey, dstkey);
return getResponse(BuilderFactory.BYTE_ARRAY);
}
@Override
public Response<Set<String>> sdiff(String... keys) {
client.sdiff(keys);
return getResponse(BuilderFactory.STRING_SET);
}
@Override
public Response<Set<byte[]>> sdiff(byte[]... keys) {
client.sdiff(keys);
return getResponse(BuilderFactory.BYTE_ARRAY_ZSET);
}
@Override
public Response<Long> sdiffstore(String dstkey, String... keys) {
client.sdiffstore(dstkey, keys);
return getResponse(BuilderFactory.LONG);
}
@Override
public Response<Long> sdiffstore(byte[] dstkey, byte[]... keys) {
client.sdiffstore(dstkey, keys);
return getResponse(BuilderFactory.LONG);
}
@Override
public Response<Set<String>> sinter(String... keys) {
client.sinter(keys);
return getResponse(BuilderFactory.STRING_SET);
}
@Override
public Response<Set<byte[]>> sinter(byte[]... keys) {
client.sinter(keys);
return getResponse(BuilderFactory.BYTE_ARRAY_ZSET);
}
@Override
public Response<Long> sinterstore(String dstkey, String... keys) {
client.sinterstore(dstkey, keys);
return getResponse(BuilderFactory.LONG);
}
@Override
public Response<Long> sinterstore(byte[] dstkey, byte[]... keys) {
client.sinterstore(dstkey, keys);
return getResponse(BuilderFactory.LONG);
}
@Override
public Response<Long> smove(String srckey, String dstkey, String member) {
client.smove(srckey, dstkey, member);
return getResponse(BuilderFactory.LONG);
}
@Override
public Response<Long> smove(byte[] srckey, byte[] dstkey, byte[] member) {
client.smove(srckey, dstkey, member);
return getResponse(BuilderFactory.LONG);
}
@Override
public Response<Long> sort(String key, SortingParams sortingParameters, String dstkey) {
client.sort(key, sortingParameters, dstkey);
return getResponse(BuilderFactory.LONG);
}
@Override
public Response<Long> sort(byte[] key, SortingParams sortingParameters, byte[] dstkey) {
client.sort(key, sortingParameters, dstkey);
return getResponse(BuilderFactory.LONG);
}
@Override
public Response<Long> sort(String key, String dstkey) {
client.sort(key, dstkey);
return getResponse(BuilderFactory.LONG);
}
@Override
public Response<Long> sort(byte[] key, byte[] dstkey) {
client.sort(key, dstkey);
return getResponse(BuilderFactory.LONG);
}
@Override
public Response<Set<String>> sunion(String... keys) {
client.sunion(keys);
return getResponse(BuilderFactory.STRING_SET);
}
@Override
public Response<Set<byte[]>> sunion(byte[]... keys) {
client.sunion(keys);
return getResponse(BuilderFactory.BYTE_ARRAY_ZSET);
}
@Override
public Response<Long> sunionstore(String dstkey, String... keys) {
client.sunionstore(dstkey, keys);
return getResponse(BuilderFactory.LONG);
}
@Override
public Response<Long> sunionstore(byte[] dstkey, byte[]... keys) {
client.sunionstore(dstkey, keys);
return getResponse(BuilderFactory.LONG);
}
@Override
public Response<String> watch(String... keys) {
client.watch(keys);
return getResponse(BuilderFactory.STRING);
}
@Override
public Response<String> watch(byte[]... keys) {
client.watch(keys);
return getResponse(BuilderFactory.STRING);
}
@Override
public Response<Long> zinterstore(String dstkey, String... sets) {
client.zinterstore(dstkey, sets);
return getResponse(BuilderFactory.LONG);
}
@Override
public Response<Long> zinterstore(byte[] dstkey, byte[]... sets) {
client.zinterstore(dstkey, sets);
return getResponse(BuilderFactory.LONG);
}
@Override
public Response<Long> zinterstore(String dstkey, ZParams params, String... sets) {
client.zinterstore(dstkey, params, sets);
return getResponse(BuilderFactory.LONG);
}
@Override
public Response<Long> zinterstore(byte[] dstkey, ZParams params, byte[]... sets) {
client.zinterstore(dstkey, params, sets);
return getResponse(BuilderFactory.LONG);
}
@Override
public Response<Long> zunionstore(String dstkey, String... sets) {
client.zunionstore(dstkey, sets);
return getResponse(BuilderFactory.LONG);
}
@Override
public Response<Long> zunionstore(byte[] dstkey, byte[]... sets) {
client.zunionstore(dstkey, sets);
return getResponse(BuilderFactory.LONG);
}
@Override
public Response<Long> zunionstore(String dstkey, ZParams params, String... sets) {
client.zunionstore(dstkey, params, sets);
return getResponse(BuilderFactory.LONG);
}
@Override
public Response<Long> zunionstore(byte[] dstkey, ZParams params, byte[]... sets) {
client.zunionstore(dstkey, params, sets);
return getResponse(BuilderFactory.LONG);
}
@Override
public Response<String> bgrewriteaof() {
client.bgrewriteaof();
return getResponse(BuilderFactory.STRING);
}
@Override
public Response<String> bgsave() {
client.bgsave();
return getResponse(BuilderFactory.STRING);
}
@Override
public Response<List<String>> configGet(String pattern) {
client.configGet(pattern);
return getResponse(BuilderFactory.STRING_LIST);
}
@Override
public Response<String> configSet(String parameter, String value) {
client.configSet(parameter, value);
return getResponse(BuilderFactory.STRING);
}
@Override
public Response<String> brpoplpush(String source, String destination, int timeout) {
client.brpoplpush(source, destination, timeout);
return getResponse(BuilderFactory.STRING);
}
@Override
public Response<byte[]> brpoplpush(byte[] source, byte[] destination, int timeout) {
client.brpoplpush(source, destination, timeout);
return getResponse(BuilderFactory.BYTE_ARRAY);
}
@Override
public Response<String> configResetStat() {
client.configResetStat();
return getResponse(BuilderFactory.STRING);
}
@Override
public Response<String> save() {
client.save();
return getResponse(BuilderFactory.STRING);
}
@Override
public Response<Long> lastsave() {
client.lastsave();
return getResponse(BuilderFactory.LONG);
}
@Override
public Response<Long> publish(String channel, String message) {
client.publish(channel, message);
return getResponse(BuilderFactory.LONG);
}
@Override
public Response<Long> publish(byte[] channel, byte[] message) {
client.publish(channel, message);
return getResponse(BuilderFactory.LONG);
}
@Override
public Response<String> randomKey() {
client.randomKey();
return getResponse(BuilderFactory.STRING);
}
@Override
public Response<byte[]> randomKeyBinary() {
client.randomKey();
return getResponse(BuilderFactory.BYTE_ARRAY);
}
@Override
public Response<String> flushDB() {
client.flushDB();
return getResponse(BuilderFactory.STRING);
}
@Override
public Response<String> flushAll() {
client.flushAll();
return getResponse(BuilderFactory.STRING);
}
@Override
public Response<String> info() {
client.info();
return getResponse(BuilderFactory.STRING);
}
public Response<String> info(final String section) {
client.info(section);
return getResponse(BuilderFactory.STRING);
}
@Override
public Response<Long> dbSize() {
client.dbSize();
return getResponse(BuilderFactory.LONG);
}
@Override
public Response<String> shutdown() {
client.shutdown();
return getResponse(BuilderFactory.STRING);
}
@Override
public Response<String> ping() {
client.ping();
return getResponse(BuilderFactory.STRING);
}
@Override
public Response<String> select(int index) {
client.select(index);
Response<String> response = getResponse(BuilderFactory.STRING);
client.setDb(index);
return response;
}
@Override
public Response<String> swapDB(int index1, int index2) {
client.swapDB(index1, index2);
return getResponse(BuilderFactory.STRING);
}
@Override
public Response<Long> bitop(BitOP op, byte[] destKey, byte[]... srcKeys) {
client.bitop(op, destKey, srcKeys);
return getResponse(BuilderFactory.LONG);
}
@Override
public Response<Long> bitop(BitOP op, String destKey, String... srcKeys) {
client.bitop(op, destKey, srcKeys);
return getResponse(BuilderFactory.LONG);
}
@Override
public Response<String> clusterNodes() {
client.clusterNodes();
return getResponse(BuilderFactory.STRING);
}
@Override
public Response<String> clusterMeet(final String ip, final int port) {
client.clusterMeet(ip, port);
return getResponse(BuilderFactory.STRING);
}
@Override
public Response<String> clusterAddSlots(final int... slots) {
client.clusterAddSlots(slots);
return getResponse(BuilderFactory.STRING);
}
@Override
public Response<String> clusterDelSlots(final int... slots) {
client.clusterDelSlots(slots);
return getResponse(BuilderFactory.STRING);
}
@Override
public Response<String> clusterInfo() {
client.clusterInfo();
return getResponse(BuilderFactory.STRING);
}
@Override
public Response<List<String>> clusterGetKeysInSlot(final int slot, final int count) {
client.clusterGetKeysInSlot(slot, count);
return getResponse(BuilderFactory.STRING_LIST);
}
@Override
public Response<String> clusterSetSlotNode(final int slot, final String nodeId) {
client.clusterSetSlotNode(slot, nodeId);
return getResponse(BuilderFactory.STRING);
}
@Override
public Response<String> clusterSetSlotMigrating(final int slot, final String nodeId) {
client.clusterSetSlotMigrating(slot, nodeId);
return getResponse(BuilderFactory.STRING);
}
@Override
public Response<String> clusterSetSlotImporting(final int slot, final String nodeId) {
client.clusterSetSlotImporting(slot, nodeId);
return getResponse(BuilderFactory.STRING);
}
@Override
public Response<Object> eval(String script) {
return this.eval(script, 0, new String[0]);
}
@Override
public Response<Object> eval(String script, List<String> keys, List<String> args) {
String[] argv = Jedis.getParams(keys, args);
return this.eval(script, keys.size(), argv);
}
@Override
public Response<Object> eval(String script, int keyCount, String... params) {
getClient(script).eval(script, keyCount, params);
return getResponse(BuilderFactory.EVAL_RESULT);
}
@Override
public Response<Object> evalsha(String sha1) {
return this.evalsha(sha1, 0, new String[0]);
}
@Override
public Response<Object> evalsha(String sha1, List<String> keys, List<String> args) {
String[] argv = Jedis.getParams(keys, args);
return this.evalsha(sha1, keys.size(), argv);
}
@Override
public Response<Object> evalsha(String sha1, int keyCount, String... params) {
getClient(sha1).evalsha(sha1, keyCount, params);
return getResponse(BuilderFactory.EVAL_RESULT);
}
@Override
public Response<Object> eval(byte[] script) {
return this.eval(script, 0);
}
@Override
public Response<Object> eval(byte[] script, byte[] keyCount, byte[]... params) {
getClient(script).eval(script, keyCount, params);
return getResponse(BuilderFactory.EVAL_BINARY_RESULT);
}
@Override
public Response<Object> eval(byte[] script, List<byte[]> keys, List<byte[]> args) {
byte[][] argv = BinaryJedis.getParamsWithBinary(keys, args);
return this.eval(script, keys.size(), argv);
}
@Override
public Response<Object> eval(byte[] script, int keyCount, byte[]... params) {
getClient(script).eval(script, keyCount, params);
return getResponse(BuilderFactory.EVAL_BINARY_RESULT);
}
@Override
public Response<Object> evalsha(byte[] sha1) {
return this.evalsha(sha1, 0);
}
@Override
public Response<Object> evalsha(byte[] sha1, List<byte[]> keys, List<byte[]> args) {
byte[][] argv = BinaryJedis.getParamsWithBinary(keys, args);
return this.evalsha(sha1, keys.size(), argv);
}
@Override
public Response<Object> evalsha(byte[] sha1, int keyCount, byte[]... params) {
getClient(sha1).evalsha(sha1, keyCount, params);
return getResponse(BuilderFactory.EVAL_BINARY_RESULT);
}
@Override
public Response<Long> pfcount(String... keys) {
client.pfcount(keys);
return getResponse(BuilderFactory.LONG);
}
@Override
public Response<Long> pfcount(final byte[]... keys) {
client.pfcount(keys);
return getResponse(BuilderFactory.LONG);
}
@Override
public Response<String> pfmerge(byte[] destkey, byte[]... sourcekeys) {
client.pfmerge(destkey, sourcekeys);
return getResponse(BuilderFactory.STRING);
}
@Override
public Response<String> pfmerge(String destkey, String... sourcekeys) {
client.pfmerge(destkey, sourcekeys);
return getResponse(BuilderFactory.STRING);
}
@Override
public Response<List<String>> time() {
client.time();
return getResponse(BuilderFactory.STRING_LIST);
}
@Override
public Response<Long> touch(String... keys) {
client.touch(keys);
return getResponse(BuilderFactory.LONG);
}
@Override
public Response<Long> touch(byte[]... keys) {
client.touch(keys);
return getResponse(BuilderFactory.LONG);
}
@Override
public Response<String> moduleUnload(String name) {
client.moduleUnload(name);
return getResponse(BuilderFactory.STRING);
}
@Override
public Response<List<Module>> moduleList() {
client.moduleList();
return getResponse(BuilderFactory.MODULE_LIST);
}
@Override
public Response<String> moduleLoad(String path) {
client.moduleLoad(path);
return getResponse(BuilderFactory.STRING);
}
}

160
fine-jedis/src/com/fr/third/redis/clients/jedis/Pipeline.java

@ -0,0 +1,160 @@
package com.fr.third.redis.clients.jedis;
import java.io.Closeable;
import java.util.ArrayList;
import java.util.List;
import com.fr.third.redis.clients.jedis.exceptions.JedisDataException;
public class Pipeline extends MultiKeyPipelineBase implements Closeable {
private MultiResponseBuilder currentMulti;
private class MultiResponseBuilder extends Builder<List<Object>> {
private List<Response<?>> responses = new ArrayList<Response<?>>();
@Override
public List<Object> build(Object data) {
@SuppressWarnings("unchecked")
List<Object> list = (List<Object>) data;
List<Object> values = new ArrayList<Object>();
if (list.size() != responses.size()) {
throw new JedisDataException("Expected data size " + responses.size() + " but was "
+ list.size());
}
for (int i = 0; i < list.size(); i++) {
Response<?> response = responses.get(i);
response.set(list.get(i));
Object builtResponse;
try {
builtResponse = response.get();
} catch (JedisDataException e) {
builtResponse = e;
}
values.add(builtResponse);
}
return values;
}
public void setResponseDependency(Response<?> dependency) {
for (Response<?> response : responses) {
response.setDependency(dependency);
}
}
public void addResponse(Response<?> response) {
responses.add(response);
}
}
@Override
protected <T> Response<T> getResponse(Builder<T> builder) {
if (currentMulti != null) {
super.getResponse(BuilderFactory.STRING); // Expected QUEUED
Response<T> lr = new Response<T>(builder);
currentMulti.addResponse(lr);
return lr;
} else {
return super.getResponse(builder);
}
}
public void setClient(Client client) {
this.client = client;
}
@Override
protected Client getClient(byte[] key) {
return client;
}
@Override
protected Client getClient(String key) {
return client;
}
public void clear() {
if (isInMulti()) {
discard();
}
sync();
}
public boolean isInMulti() {
return currentMulti != null;
}
/**
* Synchronize pipeline by reading all responses. This operation close the pipeline. In order to
* get return values from pipelined commands, capture the different Response&lt;?&gt; of the
* commands you execute.
*/
public void sync() {
if (getPipelinedResponseLength() > 0) {
List<Object> unformatted = client.getMany(getPipelinedResponseLength());
for (Object o : unformatted) {
generateResponse(o);
}
}
}
/**
* Synchronize pipeline by reading all responses. This operation close the pipeline. Whenever
* possible try to avoid using this version and use Pipeline.sync() as it won't go through all the
* responses and generate the right response type (usually it is a waste of time).
* @return A list of all the responses in the order you executed them.
*/
public List<Object> syncAndReturnAll() {
if (getPipelinedResponseLength() > 0) {
List<Object> unformatted = client.getMany(getPipelinedResponseLength());
List<Object> formatted = new ArrayList<Object>();
for (Object o : unformatted) {
try {
formatted.add(generateResponse(o).get());
} catch (JedisDataException e) {
formatted.add(e);
}
}
return formatted;
} else {
return java.util.Collections.<Object> emptyList();
}
}
public Response<String> discard() {
if (currentMulti == null) throw new JedisDataException("DISCARD without MULTI");
client.discard();
currentMulti = null;
return getResponse(BuilderFactory.STRING);
}
public Response<List<Object>> exec() {
if (currentMulti == null) throw new JedisDataException("EXEC without MULTI");
client.exec();
Response<List<Object>> response = super.getResponse(currentMulti);
currentMulti.setResponseDependency(response);
currentMulti = null;
return response;
}
public Response<String> multi() {
if (currentMulti != null) throw new JedisDataException("MULTI calls can not be nested");
client.multi();
Response<String> response = getResponse(BuilderFactory.STRING); // Expecting
// OK
currentMulti = new MultiResponseBuilder();
return response;
}
@Override
public void close() {
clear();
}
}

1692
fine-jedis/src/com/fr/third/redis/clients/jedis/PipelineBase.java

File diff suppressed because it is too large Load Diff

281
fine-jedis/src/com/fr/third/redis/clients/jedis/Protocol.java

@ -0,0 +1,281 @@
package com.fr.third.redis.clients.jedis;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import com.fr.third.redis.clients.jedis.commands.ProtocolCommand;
import com.fr.third.redis.clients.jedis.exceptions.JedisAskDataException;
import com.fr.third.redis.clients.jedis.exceptions.JedisBusyException;
import com.fr.third.redis.clients.jedis.exceptions.JedisClusterException;
import com.fr.third.redis.clients.jedis.exceptions.JedisConnectionException;
import com.fr.third.redis.clients.jedis.exceptions.JedisDataException;
import com.fr.third.redis.clients.jedis.exceptions.JedisMovedDataException;
import com.fr.third.redis.clients.jedis.exceptions.JedisNoScriptException;
import com.fr.third.redis.clients.jedis.util.RedisInputStream;
import com.fr.third.redis.clients.jedis.util.RedisOutputStream;
import com.fr.third.redis.clients.jedis.util.SafeEncoder;
public final class Protocol {
private static final String ASK_RESPONSE = "ASK";
private static final String MOVED_RESPONSE = "MOVED";
private static final String CLUSTERDOWN_RESPONSE = "CLUSTERDOWN";
private static final String BUSY_RESPONSE = "BUSY";
private static final String NOSCRIPT_RESPONSE = "NOSCRIPT";
public static final String DEFAULT_HOST = "localhost";
public static final int DEFAULT_PORT = 6379;
public static final int DEFAULT_SENTINEL_PORT = 26379;
public static final int DEFAULT_TIMEOUT = 2000;
public static final int DEFAULT_DATABASE = 0;
public static final String CHARSET = "UTF-8";
public static final byte DOLLAR_BYTE = '$';
public static final byte ASTERISK_BYTE = '*';
public static final byte PLUS_BYTE = '+';
public static final byte MINUS_BYTE = '-';
public static final byte COLON_BYTE = ':';
public static final String SENTINEL_MASTERS = "masters";
public static final String SENTINEL_GET_MASTER_ADDR_BY_NAME = "get-master-addr-by-name";
public static final String SENTINEL_RESET = "reset";
public static final String SENTINEL_SLAVES = "slaves";
public static final String SENTINEL_FAILOVER = "failover";
public static final String SENTINEL_MONITOR = "monitor";
public static final String SENTINEL_REMOVE = "remove";
public static final String SENTINEL_SET = "set";
public static final String CLUSTER_NODES = "nodes";
public static final String CLUSTER_MEET = "meet";
public static final String CLUSTER_RESET = "reset";
public static final String CLUSTER_ADDSLOTS = "addslots";
public static final String CLUSTER_DELSLOTS = "delslots";
public static final String CLUSTER_INFO = "info";
public static final String CLUSTER_GETKEYSINSLOT = "getkeysinslot";
public static final String CLUSTER_SETSLOT = "setslot";
public static final String CLUSTER_SETSLOT_NODE = "node";
public static final String CLUSTER_SETSLOT_MIGRATING = "migrating";
public static final String CLUSTER_SETSLOT_IMPORTING = "importing";
public static final String CLUSTER_SETSLOT_STABLE = "stable";
public static final String CLUSTER_FORGET = "forget";
public static final String CLUSTER_FLUSHSLOT = "flushslots";
public static final String CLUSTER_KEYSLOT = "keyslot";
public static final String CLUSTER_COUNTKEYINSLOT = "countkeysinslot";
public static final String CLUSTER_SAVECONFIG = "saveconfig";
public static final String CLUSTER_REPLICATE = "replicate";
public static final String CLUSTER_SLAVES = "slaves";
public static final String CLUSTER_FAILOVER = "failover";
public static final String CLUSTER_SLOTS = "slots";
public static final String PUBSUB_CHANNELS = "channels";
public static final String PUBSUB_NUMSUB = "numsub";
public static final String PUBSUB_NUM_PAT = "numpat";
public static final byte[] BYTES_TRUE = toByteArray(1);
public static final byte[] BYTES_FALSE = toByteArray(0);
public static final byte[] POSITIVE_INFINITY_BYTES = "+inf".getBytes();
public static final byte[] NEGATIVE_INFINITY_BYTES = "-inf".getBytes();
private Protocol() {
// this prevent the class from instantiation
}
public static void sendCommand(final RedisOutputStream os, final ProtocolCommand command,
final byte[]... args) {
sendCommand(os, command.getRaw(), args);
}
private static void sendCommand(final RedisOutputStream os, final byte[] command,
final byte[]... args) {
try {
os.write(ASTERISK_BYTE);
os.writeIntCrLf(args.length + 1);
os.write(DOLLAR_BYTE);
os.writeIntCrLf(command.length);
os.write(command);
os.writeCrLf();
for (final byte[] arg : args) {
os.write(DOLLAR_BYTE);
os.writeIntCrLf(arg.length);
os.write(arg);
os.writeCrLf();
}
} catch (IOException e) {
throw new JedisConnectionException(e);
}
}
private static void processError(final RedisInputStream is) {
String message = is.readLine();
// TODO: I'm not sure if this is the best way to do this.
// Maybe Read only first 5 bytes instead?
if (message.startsWith(MOVED_RESPONSE)) {
String[] movedInfo = parseTargetHostAndSlot(message);
throw new JedisMovedDataException(message, new HostAndPort(movedInfo[1],
Integer.parseInt(movedInfo[2])), Integer.parseInt(movedInfo[0]));
} else if (message.startsWith(ASK_RESPONSE)) {
String[] askInfo = parseTargetHostAndSlot(message);
throw new JedisAskDataException(message, new HostAndPort(askInfo[1],
Integer.parseInt(askInfo[2])), Integer.parseInt(askInfo[0]));
} else if (message.startsWith(CLUSTERDOWN_RESPONSE)) {
throw new JedisClusterException(message);
} else if (message.startsWith(BUSY_RESPONSE)) {
throw new JedisBusyException(message);
} else if (message.startsWith(NOSCRIPT_RESPONSE) ) {
throw new JedisNoScriptException(message);
}
throw new JedisDataException(message);
}
public static String readErrorLineIfPossible(RedisInputStream is) {
final byte b = is.readByte();
// if buffer contains other type of response, just ignore.
if (b != MINUS_BYTE) {
return null;
}
return is.readLine();
}
private static String[] parseTargetHostAndSlot(String clusterRedirectResponse) {
String[] response = new String[3];
String[] messageInfo = clusterRedirectResponse.split(" ");
String[] targetHostAndPort = HostAndPort.extractParts(messageInfo[2]);
response[0] = messageInfo[1];
response[1] = targetHostAndPort[0];
response[2] = targetHostAndPort[1];
return response;
}
private static Object process(final RedisInputStream is) {
final byte b = is.readByte();
if (b == PLUS_BYTE) {
return processStatusCodeReply(is);
} else if (b == DOLLAR_BYTE) {
return processBulkReply(is);
} else if (b == ASTERISK_BYTE) {
return processMultiBulkReply(is);
} else if (b == COLON_BYTE) {
return processInteger(is);
} else if (b == MINUS_BYTE) {
processError(is);
return null;
} else {
throw new JedisConnectionException("Unknown reply: " + (char) b);
}
}
private static byte[] processStatusCodeReply(final RedisInputStream is) {
return is.readLineBytes();
}
private static byte[] processBulkReply(final RedisInputStream is) {
final int len = is.readIntCrLf();
if (len == -1) {
return null;
}
final byte[] read = new byte[len];
int offset = 0;
while (offset < len) {
final int size = is.read(read, offset, (len - offset));
if (size == -1) throw new JedisConnectionException(
"It seems like server has closed the connection.");
offset += size;
}
// read 2 more bytes for the command delimiter
is.readByte();
is.readByte();
return read;
}
private static Long processInteger(final RedisInputStream is) {
return is.readLongCrLf();
}
private static List<Object> processMultiBulkReply(final RedisInputStream is) {
final int num = is.readIntCrLf();
if (num == -1) {
return null;
}
final List<Object> ret = new ArrayList<Object>(num);
for (int i = 0; i < num; i++) {
try {
ret.add(process(is));
} catch (JedisDataException e) {
ret.add(e);
}
}
return ret;
}
public static Object read(final RedisInputStream is) {
return process(is);
}
public static final byte[] toByteArray(final boolean value) {
return value ? BYTES_TRUE : BYTES_FALSE;
}
public static final byte[] toByteArray(final int value) {
return SafeEncoder.encode(String.valueOf(value));
}
public static final byte[] toByteArray(final long value) {
return SafeEncoder.encode(String.valueOf(value));
}
public static final byte[] toByteArray(final double value) {
if (value == Double.POSITIVE_INFINITY) {
return POSITIVE_INFINITY_BYTES;
} else if (value == Double.NEGATIVE_INFINITY) {
return NEGATIVE_INFINITY_BYTES;
} else {
return SafeEncoder.encode(String.valueOf(value));
}
}
public static enum Command implements ProtocolCommand {
PING, SET, GET, QUIT, EXISTS, DEL, UNLINK, TYPE, FLUSHDB, KEYS, RANDOMKEY, RENAME, RENAMENX, RENAMEX,
DBSIZE, EXPIRE, EXPIREAT, TTL, SELECT, MOVE, FLUSHALL, GETSET, MGET, SETNX, SETEX, MSET, MSETNX,
DECRBY, DECR, INCRBY, INCR, APPEND, SUBSTR, HSET, HGET, HSETNX, HMSET, HMGET, HINCRBY, HEXISTS,
HDEL, HLEN, HKEYS, HVALS, HGETALL, RPUSH, LPUSH, LLEN, LRANGE, LTRIM, LINDEX, LSET, LREM, LPOP, RPOP,
RPOPLPUSH, SADD, SMEMBERS, SREM, SPOP, SMOVE, SCARD, SISMEMBER, SINTER, SINTERSTORE, SUNION,
SUNIONSTORE, SDIFF, SDIFFSTORE, SRANDMEMBER, ZADD, ZRANGE, ZREM, ZINCRBY, ZRANK, ZREVRANK,
ZREVRANGE, ZCARD, ZSCORE, MULTI, DISCARD, EXEC, WATCH, UNWATCH, SORT, BLPOP, BRPOP, AUTH,
SUBSCRIBE, PUBLISH, UNSUBSCRIBE, PSUBSCRIBE, PUNSUBSCRIBE, PUBSUB, ZCOUNT, ZRANGEBYSCORE,
ZREVRANGEBYSCORE, ZREMRANGEBYRANK, ZREMRANGEBYSCORE, ZUNIONSTORE, ZINTERSTORE, ZLEXCOUNT,
ZRANGEBYLEX, ZREVRANGEBYLEX, ZREMRANGEBYLEX, SAVE, BGSAVE, BGREWRITEAOF, LASTSAVE, SHUTDOWN,
INFO, MONITOR, SLAVEOF, CONFIG, STRLEN, SYNC, LPUSHX, PERSIST, RPUSHX, ECHO, LINSERT, DEBUG, BRPOPLPUSH,
SETBIT, GETBIT, BITPOS, SETRANGE, GETRANGE, EVAL, EVALSHA, SCRIPT, SLOWLOG, OBJECT, BITCOUNT, BITOP,
SENTINEL, DUMP, RESTORE, PEXPIRE, PEXPIREAT, PTTL, INCRBYFLOAT, PSETEX, CLIENT, TIME, MIGRATE, HINCRBYFLOAT,
SCAN, HSCAN, SSCAN, ZSCAN, WAIT, CLUSTER, ASKING, PFADD, PFCOUNT, PFMERGE, READONLY, GEOADD, GEODIST,
GEOHASH, GEOPOS, GEORADIUS, GEORADIUSBYMEMBER, MODULE, BITFIELD, HSTRLEN, TOUCH, SWAPDB;
private final byte[] raw;
Command() {
raw = SafeEncoder.encode(this.name());
}
@Override
public byte[] getRaw() {
return raw;
}
}
public static enum Keyword {
AGGREGATE, ALPHA, ASC, BY, DESC, GET, LIMIT, MESSAGE, NO, NOSORT, PMESSAGE, PSUBSCRIBE, PUNSUBSCRIBE, OK, ONE, QUEUED, SET, STORE, SUBSCRIBE, UNSUBSCRIBE, WEIGHTS, WITHSCORES, RESETSTAT, REWRITE, RESET, FLUSH, EXISTS, LOAD, KILL, LEN, REFCOUNT, ENCODING, IDLETIME, GETNAME, SETNAME, LIST, MATCH, COUNT, PING, PONG, UNLOAD;
public final byte[] raw;
Keyword() {
raw = SafeEncoder.encode(this.name().toLowerCase(Locale.ENGLISH));
}
}
}

34
fine-jedis/src/com/fr/third/redis/clients/jedis/Queable.java

@ -0,0 +1,34 @@
package com.fr.third.redis.clients.jedis;
import java.util.LinkedList;
import java.util.Queue;
public class Queable {
private Queue<Response<?>> pipelinedResponses = new LinkedList<Response<?>>();
protected void clean() {
pipelinedResponses.clear();
}
protected Response<?> generateResponse(Object data) {
Response<?> response = pipelinedResponses.poll();
if (response != null) {
response.set(data);
}
return response;
}
protected <T> Response<T> getResponse(Builder<T> builder) {
Response<T> lr = new Response<T>(builder);
pipelinedResponses.add(lr);
return lr;
}
protected boolean hasPipelinedResponse() {
return !pipelinedResponses.isEmpty();
}
protected int getPipelinedResponseLength() {
return pipelinedResponses.size();
}
}

77
fine-jedis/src/com/fr/third/redis/clients/jedis/Response.java

@ -0,0 +1,77 @@
package com.fr.third.redis.clients.jedis;
import com.fr.third.redis.clients.jedis.exceptions.JedisDataException;
public class Response<T> {
protected T response = null;
protected JedisDataException exception = null;
private boolean building = false;
private boolean built = false;
private boolean set = false;
private Builder<T> builder;
private Object data;
private Response<?> dependency = null;
public Response(Builder<T> b) {
this.builder = b;
}
public void set(Object data) {
this.data = data;
set = true;
}
public T get() {
// if response has dependency response and dependency is not built,
// build it first and no more!!
if (dependency != null && dependency.set && !dependency.built) {
dependency.build();
}
if (!set) {
throw new JedisDataException(
"Please close pipeline or multi block before calling this method.");
}
if (!built) {
build();
}
if (exception != null) {
throw exception;
}
return response;
}
public void setDependency(Response<?> dependency) {
this.dependency = dependency;
}
private void build() {
// check build state to prevent recursion
if (building) {
return;
}
building = true;
try {
if (data != null) {
if (data instanceof JedisDataException) {
exception = (JedisDataException) data;
} else {
response = builder.build(data);
}
}
data = null;
} finally {
building = false;
built = true;
}
}
@Override
public String toString() {
return "Response " + builder.toString();
}
}

78
fine-jedis/src/com/fr/third/redis/clients/jedis/ScanParams.java

@ -0,0 +1,78 @@
package com.fr.third.redis.clients.jedis;
import static com.fr.third.redis.clients.jedis.Protocol.Keyword.COUNT;
import static com.fr.third.redis.clients.jedis.Protocol.Keyword.MATCH;
import com.fr.third.redis.clients.jedis.Protocol.Keyword;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.EnumMap;
import java.util.List;
import java.util.Map;
import com.fr.third.redis.clients.jedis.util.SafeEncoder;
public class ScanParams {
private final Map<Keyword, ByteBuffer> params = new EnumMap<Keyword, ByteBuffer>(Keyword.class);
public final static String SCAN_POINTER_START = String.valueOf(0);
public final static byte[] SCAN_POINTER_START_BINARY = SafeEncoder.encode(SCAN_POINTER_START);
public ScanParams match(final byte[] pattern) {
params.put(MATCH, ByteBuffer.wrap(pattern));
return this;
}
/**
* @see <a href="https://redis.io/commands/scan#the-match-option">MATCH option in Redis documentation</a>
*/
public ScanParams match(final String pattern) {
params.put(MATCH, ByteBuffer.wrap(SafeEncoder.encode(pattern)));
return this;
}
/**
* @see <a href="https://redis.io/commands/scan#the-count-option">COUNT option in Redis documentation</a>
*/
public ScanParams count(final Integer count) {
params.put(COUNT, ByteBuffer.wrap(Protocol.toByteArray(count)));
return this;
}
public Collection<byte[]> getParams() {
List<byte[]> paramsList = new ArrayList<byte[]>(params.size());
for (Map.Entry<Keyword, ByteBuffer> param : params.entrySet()) {
paramsList.add(param.getKey().raw);
paramsList.add(param.getValue().array());
}
return Collections.unmodifiableCollection(paramsList);
}
byte[] binaryMatch() {
if (params.containsKey(MATCH)) {
return params.get(MATCH).array();
} else {
return null;
}
}
String match() {
if (params.containsKey(MATCH)) {
return new String(params.get(MATCH).array());
} else {
return null;
}
}
Integer count() {
if (params.containsKey(COUNT)) {
return params.get(COUNT).getInt();
} else {
return null;
}
}
}

48
fine-jedis/src/com/fr/third/redis/clients/jedis/ScanResult.java

@ -0,0 +1,48 @@
package com.fr.third.redis.clients.jedis;
import java.util.List;
import com.fr.third.redis.clients.jedis.util.SafeEncoder;
public class ScanResult<T> {
private byte[] cursor;
private List<T> results;
public ScanResult(String cursor, List<T> results) {
this(SafeEncoder.encode(cursor), results);
}
public ScanResult(byte[] cursor, List<T> results) {
this.cursor = cursor;
this.results = results;
}
/**
* Returns the new value of the cursor
* @return the new cursor value. {@link ScanParams#SCAN_POINTER_START} when a complete iteration has finished
*/
public String getCursor() {
return SafeEncoder.encode(cursor);
}
/**
* Is the iteration complete. I.e. was the complete dataset scanned.
*
* @return true if the iteration is complete
*/
public boolean isCompleteIteration() {
return ScanParams.SCAN_POINTER_START.equals(getCursor());
}
public byte[] getCursorAsBytes() {
return cursor;
}
/**
* The scan results from the current call.
* @return the scan results
*/
public List<T> getResult() {
return results;
}
}

934
fine-jedis/src/com/fr/third/redis/clients/jedis/ShardedJedis.java

@ -0,0 +1,934 @@
package com.fr.third.redis.clients.jedis;
import java.io.Closeable;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.regex.Pattern;
import com.fr.third.redis.clients.jedis.commands.JedisCommands;
import com.fr.third.redis.clients.jedis.params.GeoRadiusParam;
import com.fr.third.redis.clients.jedis.params.SetParams;
import com.fr.third.redis.clients.jedis.params.ZAddParams;
import com.fr.third.redis.clients.jedis.params.ZIncrByParams;
import com.fr.third.redis.clients.jedis.util.Hashing;
public class ShardedJedis extends BinaryShardedJedis implements JedisCommands, Closeable {
protected ShardedJedisPool dataSource = null;
public ShardedJedis(List<JedisShardInfo> shards) {
super(shards);
}
public ShardedJedis(List<JedisShardInfo> shards, Hashing algo) {
super(shards, algo);
}
public ShardedJedis(List<JedisShardInfo> shards, Pattern keyTagPattern) {
super(shards, keyTagPattern);
}
public ShardedJedis(List<JedisShardInfo> shards, Hashing algo, Pattern keyTagPattern) {
super(shards, algo, keyTagPattern);
}
@Override
public String set(final String key, final String value) {
Jedis j = getShard(key);
return j.set(key, value);
}
@Override
public String set(final String key, final String value, SetParams params) {
Jedis j = getShard(key);
return j.set(key, value, params);
}
@Override
public String get(final String key) {
Jedis j = getShard(key);
return j.get(key);
}
@Override
public String echo(final String string) {
Jedis j = getShard(string);
return j.echo(string);
}
@Override
public Boolean exists(final String key) {
Jedis j = getShard(key);
return j.exists(key);
}
@Override
public String type(final String key) {
Jedis j = getShard(key);
return j.type(key);
}
@Override
public byte[] dump(final String key) {
Jedis j = getShard(key);
return j.dump(key);
}
@Override
public String restore(final String key, final int ttl, final byte[] serializedValue) {
Jedis j = getShard(key);
return j.restore(key, ttl, serializedValue);
}
@Override
public Long expire(final String key, final int seconds) {
Jedis j = getShard(key);
return j.expire(key, seconds);
}
@Override
public Long pexpire(final String key, final long milliseconds) {
Jedis j = getShard(key);
return j.pexpire(key, milliseconds);
}
@Override
public Long expireAt(final String key, final long unixTime) {
Jedis j = getShard(key);
return j.expireAt(key, unixTime);
}
@Override
public Long pexpireAt(final String key, final long millisecondsTimestamp) {
Jedis j = getShard(key);
return j.pexpireAt(key, millisecondsTimestamp);
}
@Override
public Long ttl(final String key) {
Jedis j = getShard(key);
return j.ttl(key);
}
@Override
public Long pttl(final String key) {
Jedis j = getShard(key);
return j.pttl(key);
}
@Override
public Boolean setbit(final String key, final long offset, boolean value) {
Jedis j = getShard(key);
return j.setbit(key, offset, value);
}
@Override
public Boolean setbit(final String key, final long offset, final String value) {
Jedis j = getShard(key);
return j.setbit(key, offset, value);
}
@Override
public Boolean getbit(final String key, final long offset) {
Jedis j = getShard(key);
return j.getbit(key, offset);
}
@Override
public Long setrange(final String key, final long offset, final String value) {
Jedis j = getShard(key);
return j.setrange(key, offset, value);
}
@Override
public String getrange(final String key, final long startOffset, final long endOffset) {
Jedis j = getShard(key);
return j.getrange(key, startOffset, endOffset);
}
@Override
public String getSet(final String key, final String value) {
Jedis j = getShard(key);
return j.getSet(key, value);
}
@Override
public Long setnx(final String key, final String value) {
Jedis j = getShard(key);
return j.setnx(key, value);
}
@Override
public String setex(final String key, final int seconds, final String value) {
Jedis j = getShard(key);
return j.setex(key, seconds, value);
}
@Override
public String psetex(final String key, final long milliseconds, final String value) {
Jedis j = getShard(key);
return j.psetex(key, milliseconds, value);
}
public List<String> blpop(final String arg) {
Jedis j = getShard(arg);
return j.blpop(arg);
}
@Override
public List<String> blpop(final int timeout, final String key) {
Jedis j = getShard(key);
return j.blpop(timeout, key);
}
public List<String> brpop(final String arg) {
Jedis j = getShard(arg);
return j.brpop(arg);
}
@Override
public List<String> brpop(final int timeout, final String key) {
Jedis j = getShard(key);
return j.brpop(timeout, key);
}
@Override
public Long decrBy(final String key, final long decrement) {
Jedis j = getShard(key);
return j.decrBy(key, decrement);
}
@Override
public Long decr(final String key) {
Jedis j = getShard(key);
return j.decr(key);
}
@Override
public Long incrBy(final String key, final long increment) {
Jedis j = getShard(key);
return j.incrBy(key, increment);
}
@Override
public Double incrByFloat(final String key, final double increment) {
Jedis j = getShard(key);
return j.incrByFloat(key, increment);
}
@Override
public Long incr(final String key) {
Jedis j = getShard(key);
return j.incr(key);
}
@Override
public Long append(final String key, final String value) {
Jedis j = getShard(key);
return j.append(key, value);
}
@Override
public String substr(final String key, final int start, final int end) {
Jedis j = getShard(key);
return j.substr(key, start, end);
}
@Override
public Long hset(final String key, final String field, final String value) {
Jedis j = getShard(key);
return j.hset(key, field, value);
}
@Override
public Long hset(final String key, final Map<String, String> hash) {
Jedis j = getShard(key);
return j.hset(key, hash);
}
@Override
public String hget(final String key, final String field) {
Jedis j = getShard(key);
return j.hget(key, field);
}
@Override
public Long hsetnx(final String key, final String field, final String value) {
Jedis j = getShard(key);
return j.hsetnx(key, field, value);
}
@Override
public String hmset(final String key, final Map<String, String> hash) {
Jedis j = getShard(key);
return j.hmset(key, hash);
}
@Override
public List<String> hmget(final String key, String... fields) {
Jedis j = getShard(key);
return j.hmget(key, fields);
}
@Override
public Long hincrBy(final String key, final String field, final long value) {
Jedis j = getShard(key);
return j.hincrBy(key, field, value);
}
@Override
public Double hincrByFloat(final String key, final String field, final double value) {
Jedis j = getShard(key);
return j.hincrByFloat(key, field, value);
}
@Override
public Boolean hexists(final String key, final String field) {
Jedis j = getShard(key);
return j.hexists(key, field);
}
@Override
public Long del(final String key) {
Jedis j = getShard(key);
return j.del(key);
}
@Override
public Long unlink(final String key) {
Jedis j = getShard(key);
return j.unlink(key);
}
@Override
public Long hdel(final String key, String... fields) {
Jedis j = getShard(key);
return j.hdel(key, fields);
}
@Override
public Long hlen(final String key) {
Jedis j = getShard(key);
return j.hlen(key);
}
@Override
public Set<String> hkeys(final String key) {
Jedis j = getShard(key);
return j.hkeys(key);
}
@Override
public List<String> hvals(final String key) {
Jedis j = getShard(key);
return j.hvals(key);
}
@Override
public Map<String, String> hgetAll(final String key) {
Jedis j = getShard(key);
return j.hgetAll(key);
}
@Override
public Long rpush(final String key, String... strings) {
Jedis j = getShard(key);
return j.rpush(key, strings);
}
@Override
public Long lpush(final String key, String... strings) {
Jedis j = getShard(key);
return j.lpush(key, strings);
}
@Override
public Long lpushx(final String key, String... string) {
Jedis j = getShard(key);
return j.lpushx(key, string);
}
@Override
public Long strlen(final String key) {
Jedis j = getShard(key);
return j.strlen(key);
}
@Override
public Long move(final String key, final int dbIndex) {
Jedis j = getShard(key);
return j.move(key, dbIndex);
}
@Override
public Long rpushx(final String key, String... string) {
Jedis j = getShard(key);
return j.rpushx(key, string);
}
@Override
public Long persist(final String key) {
Jedis j = getShard(key);
return j.persist(key);
}
@Override
public Long llen(final String key) {
Jedis j = getShard(key);
return j.llen(key);
}
@Override
public List<String> lrange(final String key, final long start, final long stop) {
Jedis j = getShard(key);
return j.lrange(key, start, stop);
}
@Override
public String ltrim(final String key, final long start, final long stop) {
Jedis j = getShard(key);
return j.ltrim(key, start, stop);
}
@Override
public String lindex(final String key, final long index) {
Jedis j = getShard(key);
return j.lindex(key, index);
}
@Override
public String lset(final String key, final long index, final String value) {
Jedis j = getShard(key);
return j.lset(key, index, value);
}
@Override
public Long lrem(final String key, final long count, final String value) {
Jedis j = getShard(key);
return j.lrem(key, count, value);
}
@Override
public String lpop(final String key) {
Jedis j = getShard(key);
return j.lpop(key);
}
@Override
public String rpop(final String key) {
Jedis j = getShard(key);
return j.rpop(key);
}
@Override
public Long sadd(final String key, String... members) {
Jedis j = getShard(key);
return j.sadd(key, members);
}
@Override
public Set<String> smembers(final String key) {
Jedis j = getShard(key);
return j.smembers(key);
}
@Override
public Long srem(final String key, String... members) {
Jedis j = getShard(key);
return j.srem(key, members);
}
@Override
public String spop(final String key) {
Jedis j = getShard(key);
return j.spop(key);
}
@Override
public Set<String> spop(final String key, final long count) {
Jedis j = getShard(key);
return j.spop(key, count);
}
@Override
public Long scard(final String key) {
Jedis j = getShard(key);
return j.scard(key);
}
@Override
public Boolean sismember(final String key, final String member) {
Jedis j = getShard(key);
return j.sismember(key, member);
}
@Override
public String srandmember(final String key) {
Jedis j = getShard(key);
return j.srandmember(key);
}
@Override
public List<String> srandmember(final String key, final int count) {
Jedis j = getShard(key);
return j.srandmember(key, count);
}
@Override
public Long zadd(final String key, final double score, final String member) {
Jedis j = getShard(key);
return j.zadd(key, score, member);
}
@Override
public Long zadd(final String key, final double score, final String member, final ZAddParams params) {
Jedis j = getShard(key);
return j.zadd(key, score, member, params);
}
@Override
public Long zadd(final String key, final Map<String, Double> scoreMembers) {
Jedis j = getShard(key);
return j.zadd(key, scoreMembers);
}
@Override
public Long zadd(final String key, final Map<String, Double> scoreMembers, final ZAddParams params) {
Jedis j = getShard(key);
return j.zadd(key, scoreMembers, params);
}
@Override
public Set<String> zrange(final String key, final long start, final long stop) {
Jedis j = getShard(key);
return j.zrange(key, start, stop);
}
@Override
public Long zrem(final String key, String... members) {
Jedis j = getShard(key);
return j.zrem(key, members);
}
@Override
public Double zincrby(final String key, final double increment, final String member) {
Jedis j = getShard(key);
return j.zincrby(key, increment, member);
}
@Override
public Double zincrby(final String key, final double increment, final String member, ZIncrByParams params) {
Jedis j = getShard(key);
return j.zincrby(key, increment, member, params);
}
@Override
public Long zrank(final String key, final String member) {
Jedis j = getShard(key);
return j.zrank(key, member);
}
@Override
public Long zrevrank(final String key, final String member) {
Jedis j = getShard(key);
return j.zrevrank(key, member);
}
@Override
public Set<String> zrevrange(final String key, final long start, final long stop) {
Jedis j = getShard(key);
return j.zrevrange(key, start, stop);
}
@Override
public Set<Tuple> zrangeWithScores(final String key, final long start, final long stop) {
Jedis j = getShard(key);
return j.zrangeWithScores(key, start, stop);
}
@Override
public Set<Tuple> zrevrangeWithScores(final String key, final long start, final long stop) {
Jedis j = getShard(key);
return j.zrevrangeWithScores(key, start, stop);
}
@Override
public Long zcard(final String key) {
Jedis j = getShard(key);
return j.zcard(key);
}
@Override
public Double zscore(final String key, final String member) {
Jedis j = getShard(key);
return j.zscore(key, member);
}
@Override
public List<String> sort(final String key) {
Jedis j = getShard(key);
return j.sort(key);
}
@Override
public List<String> sort(final String key, final SortingParams sortingParameters) {
Jedis j = getShard(key);
return j.sort(key, sortingParameters);
}
@Override
public Long zcount(final String key, final double min, final double max) {
Jedis j = getShard(key);
return j.zcount(key, min, max);
}
@Override
public Long zcount(final String key, final String min, final String max) {
Jedis j = getShard(key);
return j.zcount(key, min, max);
}
@Override
public Set<String> zrangeByScore(final String key, final double min, final double max) {
Jedis j = getShard(key);
return j.zrangeByScore(key, min, max);
}
@Override
public Set<String> zrevrangeByScore(final String key, final double max, final double min) {
Jedis j = getShard(key);
return j.zrevrangeByScore(key, max, min);
}
@Override
public Set<String> zrangeByScore(final String key, final double min, final double max, final int offset, final int count) {
Jedis j = getShard(key);
return j.zrangeByScore(key, min, max, offset, count);
}
@Override
public Set<String> zrevrangeByScore(final String key, final double max, final double min, final int offset, final int count) {
Jedis j = getShard(key);
return j.zrevrangeByScore(key, max, min, offset, count);
}
@Override
public Set<Tuple> zrangeByScoreWithScores(final String key, final double min, final double max) {
Jedis j = getShard(key);
return j.zrangeByScoreWithScores(key, min, max);
}
@Override
public Set<Tuple> zrevrangeByScoreWithScores(final String key, final double max, final double min) {
Jedis j = getShard(key);
return j.zrevrangeByScoreWithScores(key, max, min);
}
@Override
public Set<Tuple> zrangeByScoreWithScores(final String key, final double min, final double max, final int offset,
final int count) {
Jedis j = getShard(key);
return j.zrangeByScoreWithScores(key, min, max, offset, count);
}
@Override
public Set<Tuple> zrevrangeByScoreWithScores(final String key, final double max, final double min, final int offset,
final int count) {
Jedis j = getShard(key);
return j.zrevrangeByScoreWithScores(key, max, min, offset, count);
}
@Override
public Set<String> zrangeByScore(final String key, final String min, final String max) {
Jedis j = getShard(key);
return j.zrangeByScore(key, min, max);
}
@Override
public Set<String> zrevrangeByScore(final String key, final String max, final String min) {
Jedis j = getShard(key);
return j.zrevrangeByScore(key, max, min);
}
@Override
public Set<String> zrangeByScore(final String key, final String min, final String max, final int offset, final int count) {
Jedis j = getShard(key);
return j.zrangeByScore(key, min, max, offset, count);
}
@Override
public Set<String> zrevrangeByScore(final String key, final String max, final String min, final int offset, final int count) {
Jedis j = getShard(key);
return j.zrevrangeByScore(key, max, min, offset, count);
}
@Override
public Set<Tuple> zrangeByScoreWithScores(final String key, final String min, final String max) {
Jedis j = getShard(key);
return j.zrangeByScoreWithScores(key, min, max);
}
@Override
public Set<Tuple> zrevrangeByScoreWithScores(final String key, final String max, final String min) {
Jedis j = getShard(key);
return j.zrevrangeByScoreWithScores(key, max, min);
}
@Override
public Set<Tuple> zrangeByScoreWithScores(final String key, final String min, final String max, final int offset,
final int count) {
Jedis j = getShard(key);
return j.zrangeByScoreWithScores(key, min, max, offset, count);
}
@Override
public Set<Tuple> zrevrangeByScoreWithScores(final String key, final String max, final String min, final int offset,
final int count) {
Jedis j = getShard(key);
return j.zrevrangeByScoreWithScores(key, max, min, offset, count);
}
@Override
public Long zremrangeByRank(final String key, final long start, final long stop) {
Jedis j = getShard(key);
return j.zremrangeByRank(key, start, stop);
}
@Override
public Long zremrangeByScore(final String key, final double min, final double max) {
Jedis j = getShard(key);
return j.zremrangeByScore(key, min, max);
}
@Override
public Long zremrangeByScore(final String key, final String min, final String max) {
Jedis j = getShard(key);
return j.zremrangeByScore(key, min, max);
}
@Override
public Long zlexcount(final String key, final String min, final String max) {
return getShard(key).zlexcount(key, min, max);
}
@Override
public Set<String> zrangeByLex(final String key, final String min, final String max) {
return getShard(key).zrangeByLex(key, min, max);
}
@Override
public Set<String> zrangeByLex(final String key, final String min, final String max,
final int offset, final int count) {
return getShard(key).zrangeByLex(key, min, max, offset, count);
}
@Override
public Set<String> zrevrangeByLex(final String key, final String max, final String min) {
return getShard(key).zrevrangeByLex(key, max, min);
}
@Override
public Set<String> zrevrangeByLex(final String key, final String max, final String min, final int offset, final int count) {
return getShard(key).zrevrangeByLex(key, max, min, offset, count);
}
@Override
public Long zremrangeByLex(final String key, final String min, final String max) {
return getShard(key).zremrangeByLex(key, min, max);
}
@Override
public Long linsert(final String key, final ListPosition where, final String pivot, final String value) {
Jedis j = getShard(key);
return j.linsert(key, where, pivot, value);
}
@Override
public Long bitcount(final String key) {
Jedis j = getShard(key);
return j.bitcount(key);
}
@Override
public Long bitcount(final String key, final long start, final long end) {
Jedis j = getShard(key);
return j.bitcount(key, start, end);
}
@Override
public Long bitpos(final String key, final boolean value) {
Jedis j = getShard(key);
return j.bitpos(key, value);
}
@Override
public Long bitpos(final String key, boolean value, final BitPosParams params) {
Jedis j = getShard(key);
return j.bitpos(key, value, params);
}
@Override
public ScanResult<Entry<String, String>> hscan(final String key, final String cursor) {
Jedis j = getShard(key);
return j.hscan(key, cursor);
}
@Override
public ScanResult<Entry<String, String>> hscan(final String key, final String cursor, final ScanParams params) {
Jedis j = getShard(key);
return j.hscan(key, cursor, params);
}
@Override
public ScanResult<String> sscan(final String key, final String cursor) {
Jedis j = getShard(key);
return j.sscan(key, cursor);
}
@Override
public ScanResult<Tuple> zscan(final String key, final String cursor) {
Jedis j = getShard(key);
return j.zscan(key, cursor);
}
@Override
public ScanResult<Tuple> zscan(final String key, final String cursor, final ScanParams params) {
Jedis j = getShard(key);
return j.zscan(key, cursor, params);
}
@Override
public ScanResult<String> sscan(final String key, final String cursor, final ScanParams params) {
Jedis j = getShard(key);
return j.sscan(key, cursor, params);
}
@Override
public void close() {
if (dataSource != null) {
boolean broken = false;
for (Jedis jedis : getAllShards()) {
if (jedis.getClient().isBroken()) {
broken = true;
break;
}
}
if (broken) {
dataSource.returnBrokenResource(this);
} else {
dataSource.returnResource(this);
}
} else {
disconnect();
}
}
public void setDataSource(ShardedJedisPool shardedJedisPool) {
this.dataSource = shardedJedisPool;
}
public void resetState() {
for (Jedis jedis : getAllShards()) {
jedis.resetState();
}
}
@Override
public Long pfadd(final String key, final String... elements) {
Jedis j = getShard(key);
return j.pfadd(key, elements);
}
@Override
public long pfcount(final String key) {
Jedis j = getShard(key);
return j.pfcount(key);
}
@Override
public Long touch(final String key) {
Jedis j = getShard(key);
return j.touch(key);
}
@Override
public Long geoadd(final String key, final double longitude, final double latitude, final String member) {
Jedis j = getShard(key);
return j.geoadd(key, longitude, latitude, member);
}
@Override
public Long geoadd(final String key, final Map<String, GeoCoordinate> memberCoordinateMap) {
Jedis j = getShard(key);
return j.geoadd(key, memberCoordinateMap);
}
@Override
public Double geodist(final String key, final String member1, final String member2) {
Jedis j = getShard(key);
return j.geodist(key, member1, member2);
}
@Override
public Double geodist(final String key, final String member1, final String member2, final GeoUnit unit) {
Jedis j = getShard(key);
return j.geodist(key, member1, member2, unit);
}
@Override
public List<String> geohash(final String key, final String... members) {
Jedis j = getShard(key);
return j.geohash(key, members);
}
@Override
public List<GeoCoordinate> geopos(final String key, final String... members) {
Jedis j = getShard(key);
return j.geopos(key, members);
}
@Override
public List<GeoRadiusResponse> georadius(final String key, final double longitude, final double latitude,
final double radius, final GeoUnit unit) {
Jedis j = getShard(key);
return j.georadius(key, longitude, latitude, radius, unit);
}
@Override
public List<GeoRadiusResponse> georadius(final String key, final double longitude, final double latitude,
final double radius, final GeoUnit unit, final GeoRadiusParam param) {
Jedis j = getShard(key);
return j.georadius(key, longitude, latitude, radius, unit, param);
}
@Override
public List<GeoRadiusResponse> georadiusByMember(final String key, final String member, final double radius,
final GeoUnit unit) {
Jedis j = getShard(key);
return j.georadiusByMember(key, member, radius, unit);
}
@Override
public List<GeoRadiusResponse> georadiusByMember(final String key, final String member, final double radius,
final GeoUnit unit, final GeoRadiusParam param) {
Jedis j = getShard(key);
return j.georadiusByMember(key, member, radius, unit, param);
}
@Override
public List<Long> bitfield(final String key, final String... arguments) {
Jedis j = getShard(key);
return j.bitfield(key, arguments);
}
@Override
public Long hstrlen(final String key, final String field) {
Jedis j = getShard(key);
return j.hstrlen(key, field);
}
}

77
fine-jedis/src/com/fr/third/redis/clients/jedis/ShardedJedisPipeline.java

@ -0,0 +1,77 @@
package com.fr.third.redis.clients.jedis;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
public class ShardedJedisPipeline extends PipelineBase {
private BinaryShardedJedis jedis;
private List<FutureResult> results = new ArrayList<FutureResult>();
private Queue<Client> clients = new LinkedList<Client>();
private static class FutureResult {
private Client client;
public FutureResult(Client client) {
this.client = client;
}
public Object get() {
return client.getOne();
}
}
public void setShardedJedis(BinaryShardedJedis jedis) {
this.jedis = jedis;
}
public List<Object> getResults() {
List<Object> r = new ArrayList<Object>();
for (FutureResult fr : results) {
r.add(fr.get());
}
return r;
}
/**
* Syncronize pipeline by reading all responses. This operation closes the pipeline. In order to
* get return values from pipelined commands, capture the different Response&lt;?&gt; of the
* commands you execute.
*/
public void sync() {
for (Client client : clients) {
generateResponse(client.getOne());
}
}
/**
* Syncronize pipeline by reading all responses. This operation closes the pipeline. Whenever
* possible try to avoid using this version and use ShardedJedisPipeline.sync() as it won't go
* through all the responses and generate the right response type (usually it is a waste of time).
* @return A list of all the responses in the order you executed them.
*/
public List<Object> syncAndReturnAll() {
List<Object> formatted = new ArrayList<Object>();
for (Client client : clients) {
formatted.add(generateResponse(client.getOne()).get());
}
return formatted;
}
@Override
protected Client getClient(String key) {
Client client = jedis.getShard(key).getClient();
clients.add(client);
results.add(new FutureResult(client));
return client;
}
@Override
protected Client getClient(byte[] key) {
Client client = jedis.getShard(key).getClient();
clients.add(client);
results.add(new FutureResult(client));
return client;
}
}

120
fine-jedis/src/com/fr/third/redis/clients/jedis/ShardedJedisPool.java

@ -0,0 +1,120 @@
package com.fr.third.redis.clients.jedis;
import java.util.List;
import java.util.regex.Pattern;
import com.fr.third.org.apache.commons.pool2.PooledObject;
import com.fr.third.org.apache.commons.pool2.PooledObjectFactory;
import com.fr.third.org.apache.commons.pool2.impl.DefaultPooledObject;
import com.fr.third.org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import com.fr.third.redis.clients.jedis.util.Hashing;
import com.fr.third.redis.clients.jedis.util.Pool;
public class ShardedJedisPool extends Pool<ShardedJedis> {
public ShardedJedisPool(final GenericObjectPoolConfig poolConfig, List<JedisShardInfo> shards) {
this(poolConfig, shards, Hashing.MURMUR_HASH);
}
public ShardedJedisPool(final GenericObjectPoolConfig poolConfig, List<JedisShardInfo> shards,
Hashing algo) {
this(poolConfig, shards, algo, null);
}
public ShardedJedisPool(final GenericObjectPoolConfig poolConfig, List<JedisShardInfo> shards,
Pattern keyTagPattern) {
this(poolConfig, shards, Hashing.MURMUR_HASH, keyTagPattern);
}
public ShardedJedisPool(final GenericObjectPoolConfig poolConfig, List<JedisShardInfo> shards,
Hashing algo, Pattern keyTagPattern) {
super(poolConfig, new ShardedJedisFactory(shards, algo, keyTagPattern));
}
@Override
public ShardedJedis getResource() {
ShardedJedis jedis = super.getResource();
jedis.setDataSource(this);
return jedis;
}
@Override
protected void returnBrokenResource(final ShardedJedis resource) {
if (resource != null) {
returnBrokenResourceObject(resource);
}
}
@Override
protected void returnResource(final ShardedJedis resource) {
if (resource != null) {
resource.resetState();
returnResourceObject(resource);
}
}
/**
* PoolableObjectFactory custom impl.
*/
private static class ShardedJedisFactory implements PooledObjectFactory<ShardedJedis> {
private List<JedisShardInfo> shards;
private Hashing algo;
private Pattern keyTagPattern;
public ShardedJedisFactory(List<JedisShardInfo> shards, Hashing algo, Pattern keyTagPattern) {
this.shards = shards;
this.algo = algo;
this.keyTagPattern = keyTagPattern;
}
@Override
public PooledObject<ShardedJedis> makeObject() throws Exception {
ShardedJedis jedis = new ShardedJedis(shards, algo, keyTagPattern);
return new DefaultPooledObject<ShardedJedis>(jedis);
}
@Override
public void destroyObject(PooledObject<ShardedJedis> pooledShardedJedis) throws Exception {
final ShardedJedis shardedJedis = pooledShardedJedis.getObject();
for (Jedis jedis : shardedJedis.getAllShards()) {
if (jedis.isConnected()) {
try {
try {
jedis.quit();
} catch (Exception e) {
}
jedis.disconnect();
} catch (Exception e) {
}
}
}
}
@Override
public boolean validateObject(PooledObject<ShardedJedis> pooledShardedJedis) {
try {
ShardedJedis jedis = pooledShardedJedis.getObject();
for (Jedis shard : jedis.getAllShards()) {
if (!shard.ping().equals("PONG")) {
return false;
}
}
return true;
} catch (Exception ex) {
return false;
}
}
@Override
public void activateObject(PooledObject<ShardedJedis> p) throws Exception {
}
@Override
public void passivateObject(PooledObject<ShardedJedis> p) throws Exception {
}
}
}

159
fine-jedis/src/com/fr/third/redis/clients/jedis/SortingParams.java

@ -0,0 +1,159 @@
package com.fr.third.redis.clients.jedis;
import static com.fr.third.redis.clients.jedis.Protocol.Keyword.ALPHA;
import static com.fr.third.redis.clients.jedis.Protocol.Keyword.ASC;
import static com.fr.third.redis.clients.jedis.Protocol.Keyword.BY;
import static com.fr.third.redis.clients.jedis.Protocol.Keyword.DESC;
import static com.fr.third.redis.clients.jedis.Protocol.Keyword.GET;
import static com.fr.third.redis.clients.jedis.Protocol.Keyword.LIMIT;
import static com.fr.third.redis.clients.jedis.Protocol.Keyword.NOSORT;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import com.fr.third.redis.clients.jedis.util.SafeEncoder;
/**
* Builder Class for {@link Jedis#sort(String, SortingParams) SORT} Parameters.
*/
public class SortingParams {
private List<byte[]> params = new ArrayList<byte[]>();
/**
* Sort by weight in keys.
* <p>
* Takes a pattern that is used in order to generate the key names of the weights used for
* sorting. Weight key names are obtained substituting the first occurrence of * with the actual
* value of the elements on the list.
* <p>
* The pattern for a normal key/value pair is "field*" and for a value in a hash
* "field*-&gt;fieldname".
* @param pattern
* @return the SortingParams Object
*/
public SortingParams by(final String pattern) {
return by(SafeEncoder.encode(pattern));
}
/**
* Sort by weight in keys.
* <p>
* Takes a pattern that is used in order to generate the key names of the weights used for
* sorting. Weight key names are obtained substituting the first occurrence of * with the actual
* value of the elements on the list.
* <p>
* The pattern for a normal key/value pair is "field*" and for a value in a hash
* "field*-&gt;fieldname".
* @param pattern
* @return the SortingParams Object
*/
public SortingParams by(final byte[] pattern) {
params.add(BY.raw);
params.add(pattern);
return this;
}
/**
* No sorting.
* <p>
* This is useful if you want to retrieve a external key (using {@link #get(String...) GET}) but
* you don't want the sorting overhead.
* @return the SortingParams Object
*/
public SortingParams nosort() {
params.add(BY.raw);
params.add(NOSORT.raw);
return this;
}
public Collection<byte[]> getParams() {
return Collections.unmodifiableCollection(params);
}
/**
* Get the Sorting in Descending Order.
* @return the sortingParams Object
*/
public SortingParams desc() {
params.add(DESC.raw);
return this;
}
/**
* Get the Sorting in Ascending Order. This is the default order.
* @return the SortingParams Object
*/
public SortingParams asc() {
params.add(ASC.raw);
return this;
}
/**
* Limit the Numbers of returned Elements.
* @param start is zero based
* @param count
* @return the SortingParams Object
*/
public SortingParams limit(final int start, final int count) {
params.add(LIMIT.raw);
params.add(Protocol.toByteArray(start));
params.add(Protocol.toByteArray(count));
return this;
}
/**
* Sort lexicographicaly. Note that Redis is utf-8 aware assuming you set the right value for the
* LC_COLLATE environment variable.
* @return the SortingParams Object
*/
public SortingParams alpha() {
params.add(ALPHA.raw);
return this;
}
/**
* Retrieving external keys from the result of the search.
* <p>
* Takes a pattern that is used in order to generate the key names of the result of sorting. The
* key names are obtained substituting the first occurrence of * with the actual value of the
* elements on the list.
* <p>
* The pattern for a normal key/value pair is "field*" and for a value in a hash
* "field*-&gt;fieldname".
* <p>
* To get the list itself use the char # as pattern.
* @param patterns
* @return the SortingParams Object
*/
public SortingParams get(String... patterns) {
for (final String pattern : patterns) {
params.add(GET.raw);
params.add(SafeEncoder.encode(pattern));
}
return this;
}
/**
* Retrieving external keys from the result of the search.
* <p>
* Takes a pattern that is used in order to generate the key names of the result of sorting. The
* key names are obtained substituting the first occurrence of * with the actual value of the
* elements on the list.
* <p>
* The pattern for a normal key/value pair is "field*" and for a value in a hash
* "field*-&gt;fieldname".
* <p>
* To get the list itself use the char # as pattern.
* @param patterns
* @return the SortingParams Object
*/
public SortingParams get(byte[]... patterns) {
for (final byte[] pattern : patterns) {
params.add(GET.raw);
params.add(pattern);
}
return this;
}
}

94
fine-jedis/src/com/fr/third/redis/clients/jedis/Transaction.java

@ -0,0 +1,94 @@
package com.fr.third.redis.clients.jedis;
import java.io.Closeable;
import java.util.ArrayList;
import java.util.List;
import com.fr.third.redis.clients.jedis.exceptions.JedisDataException;
/**
* Transaction is nearly identical to Pipeline, only differences are the multi/discard behaviors
*/
public class Transaction extends MultiKeyPipelineBase implements Closeable {
protected boolean inTransaction = true;
protected Transaction() {
// client will be set later in transaction block
}
public Transaction(final Client client) {
this.client = client;
}
@Override
protected Client getClient(String key) {
return client;
}
@Override
protected Client getClient(byte[] key) {
return client;
}
public void clear() {
if (inTransaction) {
discard();
}
}
public List<Object> exec() {
// Discard QUEUED or ERROR
client.getMany(getPipelinedResponseLength());
client.exec();
inTransaction = false;
List<Object> unformatted = client.getObjectMultiBulkReply();
if (unformatted == null) {
return null;
}
List<Object> formatted = new ArrayList<Object>();
for (Object o : unformatted) {
try {
formatted.add(generateResponse(o).get());
} catch (JedisDataException e) {
formatted.add(e);
}
}
return formatted;
}
public List<Response<?>> execGetResponse() {
// Discard QUEUED or ERROR
client.getMany(getPipelinedResponseLength());
client.exec();
inTransaction = false;
List<Object> unformatted = client.getObjectMultiBulkReply();
if (unformatted == null) {
return null;
}
List<Response<?>> response = new ArrayList<Response<?>>();
for (Object o : unformatted) {
response.add(generateResponse(o));
}
return response;
}
public String discard() {
client.getMany(getPipelinedResponseLength());
client.discard();
inTransaction = false;
clean();
return client.getStatusCodeReply();
}
public void setClient(Client client) {
this.client = client;
}
@Override
public void close() {
clear();
}
}

80
fine-jedis/src/com/fr/third/redis/clients/jedis/Tuple.java

@ -0,0 +1,80 @@
package com.fr.third.redis.clients.jedis;
import java.util.Arrays;
import java.util.Objects;
import com.fr.third.redis.clients.jedis.util.ByteArrayComparator;
import com.fr.third.redis.clients.jedis.util.SafeEncoder;
public class Tuple implements Comparable<Tuple> {
private byte[] element;
private Double score;
public Tuple(String element, Double score) {
this(SafeEncoder.encode(element), score);
}
public Tuple(byte[] element, Double score) {
super();
this.element = element;
this.score = score;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result;
if (null != element) {
for (final byte b : element) {
result = prime * result + b;
}
}
long temp = Double.doubleToLongBits(score);
result = prime * result + (int) (temp ^ (temp >>> 32));
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null) return false;
if (getClass() != obj.getClass()) return false;
Tuple other = (Tuple) obj;
if (!Arrays.equals(element, other.element)) return false;
return Objects.equals(score, other.score);
}
@Override
public int compareTo(Tuple other) {
return compare(this, other);
}
public static int compare(Tuple t1, Tuple t2) {
int compScore = Double.compare(t1.score, t2.score);
if(compScore != 0) return compScore;
return ByteArrayComparator.compare(t1.element, t2.element);
}
public String getElement() {
if (null != element) {
return SafeEncoder.encode(element);
} else {
return null;
}
}
public byte[] getBinaryElement() {
return element;
}
public double getScore() {
return score;
}
@Override
public String toString() {
return '[' + SafeEncoder.encode(element) + ',' + score + ']';
}
}

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save