Merge remote-tracking branch 'origin/develop' into feature/GEODE-77

Project: http://git-wip-us.apache.org/repos/asf/incubator-geode/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-geode/commit/e0d1c4f9
Tree: http://git-wip-us.apache.org/repos/asf/incubator-geode/tree/e0d1c4f9
Diff: http://git-wip-us.apache.org/repos/asf/incubator-geode/diff/e0d1c4f9

Branch: refs/heads/feature/GEODE-77
Commit: e0d1c4f908b30bdf239041403bf9c6369f2be22b
Parents: ab68f4e eb7e7b7
Author: Bruce Schuchardt <bschucha...@pivotal.io>
Authored: Fri Aug 14 13:39:20 2015 -0700
Committer: Bruce Schuchardt <bschucha...@pivotal.io>
Committed: Fri Aug 14 13:39:20 2015 -0700

----------------------------------------------------------------------
 build.gradle                                    |   1 +
 docker/Dockerfile                               |  56 ++
 docker/README.md                                |  67 ++
 gemfire-assembly/build.gradle                   |   1 +
 gemfire-core/build.gradle                       |  30 +-
 .../cache/operations/GetOperationContext.java   |   7 +-
 .../operations/KeyValueOperationContext.java    |  70 +-
 .../internal/GetOperationContextImpl.java       |  16 +-
 .../cache/query/internal/RuntimeIterator.java   |   3 -
 .../query/internal/index/AbstractMapIndex.java  |   6 +-
 .../internal/index/CompactMapRangeIndex.java    |   7 +-
 .../internal/DistributionConfigImpl.java        |   1 -
 .../gemfire/internal/SharedLibrary.java         |  20 +-
 .../gemfire/internal/cache/CacheConfig.java     |   4 +-
 .../DistTXStateProxyImplOnCoordinator.java      |   2 +
 .../gemfire/internal/cache/ExpiryTask.java      |   2 +-
 .../internal/cache/GemFireCacheImpl.java        |   3 +-
 .../gemfire/internal/cache/LocalRegion.java     |   9 +-
 .../cache/MinimumSystemRequirements.java        |   4 +-
 .../internal/cache/RegionIdleExpiryTask.java    |   3 +-
 .../gemfire/internal/cache/TXManagerImpl.java   |  11 +-
 .../cache/control/HeapMemoryMonitor.java        |  14 +-
 .../internal/cache/control/MemoryEvent.java     |   9 +-
 .../cache/control/OffHeapMemoryMonitor.java     |  88 +-
 .../cache/control/ResourceManagerStats.java     |  13 +
 .../internal/cache/partitioned/GetMessage.java  |   6 +
 .../AbstractGatewaySenderEventProcessor.java    |   1 +
 .../parallel/ParallelGatewaySenderQueue.java    |  41 +-
 .../internal/cache/xmlcache/CacheXmlParser.java |  26 +-
 .../gemfire/internal/lang/SystemUtils.java      |  35 +-
 .../gemfire/internal/logging/LogService.java    |  58 +-
 .../internal/logging/log4j/Configurator.java    |  65 +-
 .../internal/logging/log4j/FastLogger.java      |  50 +-
 .../offheap/SimpleMemoryAllocatorImpl.java      |   2 +-
 .../internal/redis/ByteArrayWrapper.java        |  11 +-
 .../internal/redis/ByteToCommandDecoder.java    |  57 +-
 .../gemstone/gemfire/internal/redis/Coder.java  |  24 +-
 .../gemfire/internal/redis/Command.java         |  25 +-
 .../gemfire/internal/redis/DoubleWrapper.java   |  14 +-
 .../internal/redis/ExecutionHandlerContext.java | 139 +++-
 .../gemfire/internal/redis/Executor.java        |   2 +-
 .../gemfire/internal/redis/Extendable.java      |   6 +-
 .../gemfire/internal/redis/RedisConstants.java  |   2 +-
 .../gemfire/internal/redis/RedisDataType.java   |   9 -
 .../gemfire/internal/redis/RegionCache.java     | 410 ----------
 .../internal/redis/RegionCreationException.java |   9 +-
 .../gemfire/internal/redis/RegionProvider.java  | 531 ++++++++++++
 .../redis/executor/AbstractExecutor.java        |  12 +-
 .../redis/executor/AbstractScanExecutor.java    |   2 +-
 .../internal/redis/executor/DBSizeExecutor.java |   2 +-
 .../internal/redis/executor/DelExecutor.java    |   2 +-
 .../internal/redis/executor/EchoExecutor.java   |   2 +-
 .../internal/redis/executor/ExistsExecutor.java |   2 +-
 .../redis/executor/ExpirationExecutor.java      |   6 +-
 .../redis/executor/ExpireAtExecutor.java        |   4 +-
 .../internal/redis/executor/ExpireExecutor.java |   4 +-
 .../redis/executor/FlushAllExecutor.java        |  15 +-
 .../internal/redis/executor/KeysExecutor.java   |   7 +-
 .../internal/redis/executor/ListQuery.java      |  12 +-
 .../redis/executor/PersistExecutor.java         |   2 +-
 .../internal/redis/executor/PingExecutor.java   |   2 +-
 .../internal/redis/executor/QuitExecutor.java   |   2 +-
 .../internal/redis/executor/ScanExecutor.java   |   4 +-
 .../internal/redis/executor/SortedSetQuery.java |  36 +-
 .../internal/redis/executor/TTLExecutor.java    |   4 +-
 .../internal/redis/executor/TypeExecutor.java   |   2 +-
 .../internal/redis/executor/UnkownExecutor.java |   2 +-
 .../redis/executor/hash/HDelExecutor.java       |   2 +-
 .../redis/executor/hash/HGetAllExecutor.java    |   7 +-
 .../redis/executor/hash/HKeysExecutor.java      |   7 +-
 .../redis/executor/hash/HScanExecutor.java      |   5 +-
 .../redis/executor/hash/HValsExecutor.java      |   9 +-
 .../redis/executor/hash/HashExecutor.java       |   4 +-
 .../redis/executor/hll/HllExecutor.java         |   2 +-
 .../redis/executor/hll/PFAddExecutor.java       |   2 +-
 .../redis/executor/hll/PFCountExecutor.java     |   2 +-
 .../redis/executor/hll/PFMergeExecutor.java     |   4 +-
 .../redis/executor/list/LIndexExecutor.java     |   4 +-
 .../redis/executor/list/LLenExecutor.java       |   2 +-
 .../redis/executor/list/LRangeExecutor.java     |  10 +-
 .../redis/executor/list/LRemExecutor.java       |   4 +-
 .../redis/executor/list/LSetExecutor.java       |   4 +-
 .../redis/executor/list/LTrimExecutor.java      |  26 +-
 .../redis/executor/list/ListExecutor.java       |  26 +-
 .../redis/executor/list/PopExecutor.java        |  23 +-
 .../redis/executor/list/PushExecutor.java       |   2 +-
 .../redis/executor/list/PushXExecutor.java      |   2 +-
 .../org/apache/hadoop/fs/GlobPattern.java       | 164 ----
 .../redis/executor/set/SAddExecutor.java        |   2 +-
 .../redis/executor/set/SCardExecutor.java       |   2 +-
 .../redis/executor/set/SIsMemberExecutor.java   |   2 +-
 .../redis/executor/set/SMembersExecutor.java    |   7 +-
 .../redis/executor/set/SMoveExecutor.java       |   2 +-
 .../redis/executor/set/SPopExecutor.java        |   4 +-
 .../redis/executor/set/SRandMemberExecutor.java |   4 +-
 .../redis/executor/set/SRemExecutor.java        |   2 +-
 .../redis/executor/set/SScanExecutor.java       |   4 +-
 .../redis/executor/set/SetOpExecutor.java       |   9 +-
 .../executor/sortedset/SortedSetExecutor.java   |   4 +-
 .../executor/sortedset/ZRangeByLexExecutor.java |   2 -
 .../sortedset/ZRangeByScoreExecutor.java        |   3 +-
 .../redis/executor/sortedset/ZRemExecutor.java  |   2 +-
 .../sortedset/ZRemRangeByLexExecutor.java       |   3 +-
 .../sortedset/ZRemRangeByRankExecutor.java      |   4 +-
 .../sortedset/ZRemRangeByScoreExecutor.java     |   4 +-
 .../redis/executor/sortedset/ZScanExecutor.java |   5 +-
 .../redis/executor/string/AppendExecutor.java   |   2 +-
 .../redis/executor/string/BitCountExecutor.java |   2 +-
 .../redis/executor/string/BitOpExecutor.java    |   2 +-
 .../redis/executor/string/BitPosExecutor.java   |   2 +-
 .../redis/executor/string/DecrByExecutor.java   |   2 +-
 .../redis/executor/string/DecrExecutor.java     |   4 +-
 .../redis/executor/string/GetBitExecutor.java   |   2 +-
 .../redis/executor/string/GetExecutor.java      |   2 +-
 .../redis/executor/string/GetRangeExecutor.java |   2 +-
 .../redis/executor/string/GetSetExecutor.java   |   2 +-
 .../redis/executor/string/IncrByExecutor.java   |   2 +-
 .../executor/string/IncrByFloatExecutor.java    |   2 +-
 .../redis/executor/string/IncrExecutor.java     |   2 +-
 .../redis/executor/string/MGetExecutor.java     |   2 +-
 .../redis/executor/string/MSetExecutor.java     |   2 +-
 .../redis/executor/string/MSetNXExecutor.java   |   2 +-
 .../redis/executor/string/SetBitExecutor.java   |   2 +-
 .../redis/executor/string/SetEXExecutor.java    |   4 +-
 .../redis/executor/string/SetExecutor.java      |   4 +-
 .../redis/executor/string/SetNXExecutor.java    |   2 +-
 .../redis/executor/string/SetRangeExecutor.java |   4 +-
 .../redis/executor/string/StringExecutor.java   |   4 +-
 .../redis/executor/string/StrlenExecutor.java   |   2 +-
 .../redis/org/apache/hadoop/fs/GlobPattern.java | 164 ++++
 .../size/ReflectionSingleObjectSizer.java       |   4 +-
 .../internal/cli/commands/QueueCommands.java    |   4 +-
 .../CreateAsyncEventQueueFunction.java          |   8 +-
 .../internal/cli/i18n/CliStrings.java           |   4 +-
 .../controllers/QueueCommandsController.java    |   6 +-
 .../pdx/ReflectionBasedAutoSerializer.java      |   9 +
 .../pdx/internal/AutoSerializableManager.java   |   8 -
 .../gemfire/pdx/internal/TypeRegistry.java      |   4 +-
 .../gemfire/redis/GemFireRedisServer.java       | 130 +--
 .../internal/RegionWithHDFSBasicDUnitTest.java  |  22 +-
 .../RegionWithHDFSOffHeapBasicDUnitTest.java    |  10 +-
 .../hdfs/internal/RegionWithHDFSTestBase.java   |   6 +-
 .../MemoryThresholdsOffHeapDUnitTest.java       |  42 +-
 .../PutOperationContextJUnitTest.java           | 248 ++++++
 .../GetOperationContextImplJUnitTest.java       | 275 +++++++
 .../query/dunit/CloseCacheAuthorization.java    |   2 -
 .../index/CopyOnReadIndexDUnitTest.java         |  68 +-
 .../index/CopyOnReadIndexJUnitTest.java         |   5 +-
 .../MapRangeIndexMaintenanceJUnitTest.java      |  50 ++
 .../gemfire/cache30/MultiVMRegionTestCase.java  |  94 ++-
 .../gemfire/cache30/RegionTestCase.java         | 137 ++--
 .../LocatorLauncherRemoteFileJUnitTest.java     |   8 +-
 .../LocatorLauncherRemoteJUnitTest.java         |  57 +-
 .../ServerLauncherLocalJUnitTest.java           |  47 +-
 .../ServerLauncherRemoteFileJUnitTest.java      |   2 -
 .../ServerLauncherRemoteJUnitTest.java          |   2 +-
 .../ServerLauncherWithSpringJUnitTest.java      |   2 +
 .../gemfire/disttx/DistTXDebugDUnitTest.java    |   3 +
 .../disttx/DistributedTransactionDUnitTest.java |  19 +-
 .../internal/cache/Bug34011JUnitTest.java       | 199 -----
 .../cache/ClientServerTransactionDUnitTest.java |  38 +-
 .../ConcurrentRegionOperationsJUnitTest.java    |   7 +-
 .../PartitionedRegionSingleHopDUnitTest.java    |   4 -
 .../cache/RemoteTransactionDUnitTest.java       | 113 ++-
 .../control/RebalanceOperationDUnitTest.java    |   2 +
 .../cache/ha/Bug36853EventsExpiryDUnitTest.java |   1 +
 .../DistributedSystemLogFileJUnitTest.java      |  20 +-
 .../logging/LoggingIntegrationTestSuite.java    |  14 +
 .../internal/logging/LoggingUnitTestSuite.java  |  12 +
 .../log4j/FastLoggerIntegrationJUnitTest.java   | 557 +++++++++++++
 .../logging/log4j/FastLoggerJUnitTest.java      | 274 +++----
 .../FastLoggerWithDefaultConfigJUnitTest.java   |  74 ++
 .../log4j/Log4jIntegrationTestSuite.java        |  12 +
 .../logging/log4j/Log4jUnitTestSuite.java       |  16 +
 .../internal/size/ObjectSizerJUnitTest.java     |  14 +-
 .../gemfire/pdx/AutoSerializableJUnitTest.java  |   2 +-
 .../gemfire/redis/ConcurrentStartTest.java      |  58 ++
 .../gemstone/gemfire/redis/HashesJUnitTest.java | 175 ++++
 .../gemstone/gemfire/redis/ListsJUnitTest.java  | 238 ++++++
 .../gemfire/redis/RedisDistDUnitTest.java       | 231 ++++++
 .../gemstone/gemfire/redis/SetsJUnitTest.java   | 242 ++++++
 .../gemfire/redis/SortedSetsJUnitTest.java      | 414 ++++++++++
 .../gemfire/redis/StringsJunitTest.java         | 296 +++++++
 .../gemfire/test/golden/ExecutableProcess.java  |   8 +
 .../gemfire/test/golden/FailOutputTestCase.java |  22 +-
 .../golden/FailWithErrorInOutputJUnitTest.java  |  18 +-
 .../FailWithExtraLineInOutputJUnitTest.java     |  41 +-
 ...WithLineMissingFromEndOfOutputJUnitTest.java |  39 +-
 ...hLineMissingFromMiddleOfOutputJUnitTest.java |  39 +-
 .../FailWithLoggerErrorInOutputJUnitTest.java   |  18 +-
 .../FailWithLoggerFatalInOutputJUnitTest.java   |  18 +-
 .../FailWithLoggerWarnInOutputJUnitTest.java    |  18 +-
 .../golden/FailWithProblemInOutputTestCase.java |  30 +-
 .../golden/FailWithSevereInOutputJUnitTest.java |  18 +-
 ...hTimeoutOfWaitForOutputToMatchJUnitTest.java |  42 +-
 .../FailWithWarningInOutputJUnitTest.java       |  18 +-
 .../gemfire/test/golden/GoldenComparator.java   |  64 +-
 .../test/golden/GoldenStringComparator.java     |   5 +-
 .../gemfire/test/golden/GoldenTestCase.java     | 108 +--
 .../golden/GoldenTestFrameworkTestSuite.java    |  27 +
 .../gemfire/test/golden/PassJUnitTest.java      |  50 +-
 .../golden/PassWithExpectedErrorJUnitTest.java  |  18 +-
 .../golden/PassWithExpectedProblemTestCase.java |  58 +-
 .../golden/PassWithExpectedSevereJUnitTest.java |  18 +-
 .../PassWithExpectedWarningJUnitTest.java       |  18 +-
 .../test/golden/RegexGoldenComparator.java      |  10 +-
 .../test/golden/StringGoldenComparator.java     |   4 +-
 .../process/ProcessTestFrameworkTestSuite.java  |  12 +
 .../gemfire/test/process/ProcessWrapper.java    | 251 +++---
 .../test/process/ProcessWrapperJUnitTest.java   |  19 +-
 .../test/java/dunit/DistributedTestCase.java    |  19 +-
 .../gemfire/test/golden/log4j2-test.xml         |  18 +
 gemfire-rebalancer/build.gradle                 |  12 +
 .../gemfire/cache/util/AutoBalancer.java        | 512 ++++++++++++
 .../cache/util/AutoBalancerJUnitTest.java       | 803 +++++++++++++++++++
 .../connector/GemFirePairRDDFunctions.scala     |   5 +-
 .../spark/connector/GemFireRDDFunctions.scala   |   5 +-
 .../internal/DefaultGemFireConnection.scala     |  30 +-
 .../connector/internal/LocatorHelper.scala      |  91 ++-
 .../internal/rdd/GemFireRegionRDD.scala         |   2 +-
 .../gemfire/spark/connector/package.scala       |   7 +
 .../spark/connector/LocatorHelperTest.scala     |  77 ++
 settings.gradle                                 |   1 +
 223 files changed, 7167 insertions(+), 2385 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/e0d1c4f9/gemfire-assembly/build.gradle
----------------------------------------------------------------------
diff --cc gemfire-assembly/build.gradle
index a50d3ff,f65930d..7e7dcb3
--- a/gemfire-assembly/build.gradle
+++ b/gemfire-assembly/build.gradle
@@@ -112,7 -113,7 +112,8 @@@ def cp = 
        it.contains('spring-shell') ||
        it.contains('snappy-java') ||
        it.contains('hbase') ||
 +      it.contains('jgroups')
+       it.contains('netty')
      }.join(' ') 
  }
  

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/e0d1c4f9/gemfire-core/build.gradle
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/e0d1c4f9/gemfire-core/src/main/java/com/gemstone/gemfire/distributed/internal/DistributionConfigImpl.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/e0d1c4f9/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/LocalRegion.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/e0d1c4f9/gemfire-core/src/main/java/com/gemstone/gemfire/internal/logging/LogService.java
----------------------------------------------------------------------
diff --cc 
gemfire-core/src/main/java/com/gemstone/gemfire/internal/logging/LogService.java
index e12f83f,a4a399d..877fdb1
--- 
a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/logging/LogService.java
+++ 
b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/logging/LogService.java
@@@ -117,12 -119,13 +119,13 @@@ public class LogService extends LogMana
    /**
     * Check to see if the user has specified a Log4j configuration file.  If 
not, attempt
     * to find a GemFire Log4j configuration file in various locations.
+    * 
+    * @return true if log4j.configurationFile property was set; false if it 
was unchanged
     */
-   private static final void setLog4jConfigFileProperty() {
+   private static final boolean setLog4jConfigFileProperty() {
      // fix bug #52175
      final URL configInClasspath = ConfigLocator.findConfigInClasspath();
 -    if (configInClasspath != null ) {
 +    if (configInClasspath != null) {
- //      System.out.println("log config is " + configInClasspath);
        // Log4J 2 will find the configuration file in classpath so do nothing
        configFileInformation = "Using log4j configuration found in classpath: 
'" + configInClasspath.toString() + "'";
        StatusLogger.getLogger().info(configFileInformation);

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/e0d1c4f9/gemfire-core/src/main/java/com/gemstone/gemfire/internal/redis/RegionProvider.java
----------------------------------------------------------------------
diff --cc 
gemfire-core/src/main/java/com/gemstone/gemfire/internal/redis/RegionProvider.java
index 0000000,a95f853..18971eb
mode 000000,100644..100644
--- 
a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/redis/RegionProvider.java
+++ 
b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/redis/RegionProvider.java
@@@ -1,0 -1,531 +1,531 @@@
+ package com.gemstone.gemfire.internal.redis;
+ 
+ import java.io.Closeable;
+ import java.util.HashMap;
+ import java.util.Map;
+ import java.util.Map.Entry;
+ import java.util.Set;
+ import java.util.concurrent.ConcurrentHashMap;
+ import java.util.concurrent.ConcurrentMap;
+ import java.util.concurrent.ScheduledExecutorService;
+ import java.util.concurrent.ScheduledFuture;
+ import java.util.concurrent.TimeUnit;
+ import java.util.concurrent.locks.Lock;
+ import java.util.concurrent.locks.ReentrantLock;
+ 
+ import com.gemstone.gemfire.LogWriter;
+ import com.gemstone.gemfire.cache.Cache;
+ import com.gemstone.gemfire.cache.CacheTransactionManager;
+ import com.gemstone.gemfire.cache.Region;
+ import com.gemstone.gemfire.cache.RegionShortcut;
+ import com.gemstone.gemfire.cache.TransactionId;
+ import com.gemstone.gemfire.cache.query.IndexNameConflictException;
+ import com.gemstone.gemfire.cache.query.Query;
+ import com.gemstone.gemfire.cache.query.QueryInvalidException;
+ import com.gemstone.gemfire.cache.query.QueryService;
+ import com.gemstone.gemfire.cache.query.RegionNotFoundException;
+ import com.gemstone.gemfire.internal.cache.GemFireCacheImpl;
+ import com.gemstone.gemfire.internal.redis.executor.ExpirationExecutor;
+ import com.gemstone.gemfire.internal.redis.executor.ListQuery;
+ import com.gemstone.gemfire.internal.redis.executor.SortedSetQuery;
+ import com.gemstone.gemfire.internal.redis.executor.hll.HyperLogLogPlus;
+ import com.gemstone.gemfire.management.cli.Result;
+ import com.gemstone.gemfire.management.cli.Result.Status;
+ import 
com.gemstone.gemfire.management.internal.cli.commands.CreateAlterDestroyRegionCommands;
+ import com.gemstone.gemfire.redis.GemFireRedisServer;
+ 
+ /**
+  * This class stands between {@link Executor} and {@link 
Cache#getRegion(String)}.
+  * This is needed because some keys for Redis represented as a {@link Region} 
in
+  * {@link GemFireRedisServer} come with additional state. Therefore getting, 
creating,
+  * or destroying a {@link Region} needs to be synchronized, which is done 
away with
+  * and abstracted by this class.
+  * 
+  * @author Vitaly Gavrilov
+  *
+  */
+ public class RegionProvider implements Closeable {
+ 
+   private final ConcurrentHashMap<ByteArrayWrapper, Region<?, ?>> regions;
+ 
+   /**
+    * This is the Redis meta data {@link Region} that holds the {@link 
RedisDataType}
+    * information for all Regions created. The mapping is a {@link String} key 
which is the name
+    * of the {@link Region} created to hold the data to the RedisDataType it 
contains.
+    */
+   private final Region<String, RedisDataType> redisMetaRegion;
+ 
+   /**
+    * This is the {@link RedisDataType#REDIS_STRING} {@link Region}. This is 
the Region
+    * that stores all string contents
+    */
+   private final Region<ByteArrayWrapper, ByteArrayWrapper> stringsRegion;
+ 
+   /**
+    * This is the {@link RedisDataType#REDIS_HLL} {@link Region}. This is the 
Region
+    * that stores all HyperLogLog contents
+    */
+   private final Region<ByteArrayWrapper, HyperLogLogPlus> hLLRegion;
+ 
+   private final Cache cache;
+   private final QueryService queryService;
+   private final ConcurrentMap<ByteArrayWrapper, Map<Enum<?>, Query>> 
preparedQueries = new ConcurrentHashMap<ByteArrayWrapper, Map<Enum<?>, 
Query>>();
+   private final ConcurrentMap<ByteArrayWrapper, ScheduledFuture<?>> 
expirationsMap;
+   private final ScheduledExecutorService expirationExecutor;
+   private final RegionShortcut defaultRegionType;
+   private static final CreateAlterDestroyRegionCommands cliCmds = new 
CreateAlterDestroyRegionCommands();
+   private final ConcurrentHashMap<String, Lock> locks;
+   private final LogWriter logger;
+ 
+   public RegionProvider(Region<ByteArrayWrapper, ByteArrayWrapper> 
stringsRegion, Region<ByteArrayWrapper, HyperLogLogPlus> hLLRegion, 
Region<String, RedisDataType> redisMetaRegion, ConcurrentMap<ByteArrayWrapper, 
ScheduledFuture<?>> expirationsMap, ScheduledExecutorService 
expirationExecutor, RegionShortcut defaultShortcut) {
+     if (stringsRegion == null || hLLRegion == null || redisMetaRegion == null)
+       throw new NullPointerException();
+     this.regions = new ConcurrentHashMap<ByteArrayWrapper, Region<?, ?>>();
+     this.stringsRegion = stringsRegion;
+     this.hLLRegion = hLLRegion;
+     this.redisMetaRegion = redisMetaRegion;
+     this.cache = GemFireCacheImpl.getInstance();
+     this.queryService = cache.getQueryService();
+     this.expirationsMap = expirationsMap;
+     this.expirationExecutor = expirationExecutor;
+     this.defaultRegionType = defaultShortcut;
+     this.locks = new ConcurrentHashMap<String, Lock>();
+     this.logger = this.cache.getLogger();
+   }
+ 
+   public boolean existsKey(ByteArrayWrapper key) {
+     return this.redisMetaRegion.containsKey(key.toString());
+   }
+ 
+   public Set<String> metaKeySet() {
+     return this.redisMetaRegion.keySet();
+   }
+ 
+   public Set<Map.Entry<String, RedisDataType>> metaEntrySet() {
+     return this.redisMetaRegion.entrySet();
+   }
+ 
+   public int getMetaSize() {
+     return this.redisMetaRegion.size() - RedisConstants.NUM_DEFAULT_KEYS;
+   }
+ 
+   private boolean metaRemoveEntry(ByteArrayWrapper key) {
+     return this.redisMetaRegion.remove(key.toString()) != null;
+   }
+ 
+   public RedisDataType metaPutIfAbsent(ByteArrayWrapper key, RedisDataType 
value) {
+     return this.redisMetaRegion.putIfAbsent(key.toString(), value);
+   }
+ 
+   public RedisDataType metaPut(ByteArrayWrapper key, RedisDataType value) {
+     return this.redisMetaRegion.put(key.toString(), value);
+   }
+ 
+   public RedisDataType metaGet(ByteArrayWrapper key) {
+     return this.redisMetaRegion.get(key.toString());
+   }
+ 
+   public Region<?, ?> getRegion(ByteArrayWrapper key) {
+     return this.regions.get(key);
+   }
+ 
+   public void removeRegionReferenceLocally(ByteArrayWrapper key, 
RedisDataType type) {
+     Lock lock = this.locks.get(key.toString());
+     boolean locked = false;
+     try {
+       locked = lock.tryLock();
+       // If we cannot get the lock we ignore this remote event, this key has 
local event
+       // that started independently, ignore this event to prevent deadlock
+       if (locked) {
+         cancelKeyExpiration(key);
+         removeRegionState(key, type);
+       }
+     } finally {
+       if (locked) {
+         lock.unlock();
+       }
+     }
+   }
+ 
+   public boolean removeKey(ByteArrayWrapper key) {
+     RedisDataType type = getRedisDataType(key);
+     return removeKey(key, type);
+   }
+ 
+   public boolean removeKey(ByteArrayWrapper key, RedisDataType type) {
+     return removeKey(key, type, true);
+   }
+ 
+   public boolean removeKey(ByteArrayWrapper key, RedisDataType type, boolean 
cancelExpiration) {
+     if (type == null || type == RedisDataType.REDIS_PROTECTED)
+       return false;
+     Lock lock = this.locks.get(key.toString());
+     try {
+       if (lock != null)  {// Strings/hlls will not have locks
+         lock.lock();
+       }
+       metaRemoveEntry(key);
+       try {
+         if (type == RedisDataType.REDIS_STRING) {
+           return this.stringsRegion.remove(key) != null;
+         } else if (type == RedisDataType.REDIS_HLL) {
+           return this.hLLRegion.remove(key) != null;
+         } else {
+           return destroyRegion(key, type);
+         }
+       } catch (Exception exc) {
+         return false;
+       } finally {
+         if (cancelExpiration)
+           cancelKeyExpiration(key);
+         else
+           removeKeyExpiration(key);
+         if (lock != null)
+           this.locks.remove(key.toString());
+       }
+     } finally {
+       if (lock != null) {
+         lock.unlock();
+       }
+     }
+   }
+ 
+   public Region<?, ?> getOrCreateRegion(ByteArrayWrapper key, RedisDataType 
type, ExecutionHandlerContext context) {
+     return getOrCreateRegion0(key, type, context, true);
+   }
+ 
+   public void createRemoteRegionLocally(ByteArrayWrapper key, RedisDataType 
type) {
+     if (type == null || type == RedisDataType.REDIS_STRING || type == 
RedisDataType.REDIS_HLL)
+       return;
+     Region<?, ?> r = this.regions.get(key);
+     if (r != null)
+       return;
+     if (!this.regions.contains(key)) {
+       String stringKey = key.toString();
+       Lock lock = this.locks.get(stringKey);
+       if (lock == null) {
+         this.locks.putIfAbsent(stringKey, new ReentrantLock());
+         lock = this.locks.get(stringKey);
+       }
+       boolean locked = false;
+       try {
+         locked = lock.tryLock();
+         // If we cannot get the lock then this remote even may have been 
initialized
+         // independently on this machine, so if we wait on the lock it is 
more than
+         // likely we will deadlock just to do the same task, this even can be 
ignored
+         if (locked) {
+           r = cache.getRegion(key.toString());
+           if (type == RedisDataType.REDIS_LIST)
+             doInitializeList(key, r);
+           else if (type == RedisDataType.REDIS_SORTEDSET)
+             doInitializeSortedSet(key, r);
+           this.regions.put(key, r);
+         }
+       } finally {
+         if (locked) {
+           lock.unlock();
+         }
+       }
+     }
+   }
+ 
+   private Region<?, ?> getOrCreateRegion0(ByteArrayWrapper key, RedisDataType 
type, ExecutionHandlerContext context, boolean addToMeta) {
+     checkDataType(key, type);
+     Region<?, ?> r = this.regions.get(key);
+     if (r != null && r.isDestroyed()) {
+       removeKey(key, type);
+       r = null;
+     }
+     if (r == null) {
+       String stringKey = key.toString();
+       Lock lock = this.locks.get(stringKey);
+       if (lock == null) {
+         this.locks.putIfAbsent(stringKey, new ReentrantLock());
+         lock = this.locks.get(stringKey);
+       }
+ 
+       try {
+         lock.lock();
+         r = regions.get(key);
+         if (r == null) {
+           boolean hasTransaction = context != null && 
context.hasTransaction(); // Can create without context
+           CacheTransactionManager txm = null;
+           TransactionId transactionId = null;
+           try {
+             if (hasTransaction) {
+               txm = cache.getCacheTransactionManager();
+               transactionId = txm.suspend();
+             }
+             Exception concurrentCreateDestroyException = null;
+             do {
+               concurrentCreateDestroyException = null;
+               r = createRegionGlobally(stringKey);
+               try {
+                 if (type == RedisDataType.REDIS_LIST)
+                   doInitializeList(key, r);
+                 else if (type == RedisDataType.REDIS_SORTEDSET)
+                   doInitializeSortedSet(key, r);
+               } catch (QueryInvalidException e) {
+                 if (e.getCause() instanceof RegionNotFoundException) {
+                   concurrentCreateDestroyException = e;
+                 }
+               }
+             } while(concurrentCreateDestroyException != null);
+             this.regions.put(key, r);            
+             if (addToMeta) {
+               RedisDataType existingType = metaPutIfAbsent(key, type);
+               if (existingType != null && existingType != type)
+                 throw new RedisDataTypeMismatchException("The key name \"" + 
key + "\" is already used by a " + existingType.toString());
+             }
+           } finally {
+             if (hasTransaction)
+               txm.resume(transactionId);
+           }
+         }
+       } finally {
+         lock.unlock();
+       }
+     }
+     return r;
+   }
+ 
+   /**
+    * SYNCHRONIZE EXTERNALLY OF this.locks.get(key.toString())!!!!!
+    * 
+    * @param key Key of region to destroy
+    * @param type Type of region to destroyu
+    * @return Flag if destroyed
+    */
+   private boolean destroyRegion(ByteArrayWrapper key, RedisDataType type) {
+     Region<?, ?> r = this.regions.get(key);
+     if (r != null) {
+       try {
+         r.destroyRegion();
+       } catch (Exception e) {
+         return false;
+       } finally {
+         removeRegionState(key, type);
+       }
+     }
+     return true;
+   }
+ 
+   /**
+    * Do not call this method if you are not synchronized on the lock 
associated with this key
+    * 
+    * @param key Key of region to remove
+    * @param type Type of key to remove all state
+    */
+   private void removeRegionState(ByteArrayWrapper key, RedisDataType type) {
+     this.preparedQueries.remove(key);
+     this.regions.remove(key);
+   }
+ 
+   private void doInitializeSortedSet(ByteArrayWrapper key, Region<?, ?> r) {
+     String fullpath = r.getFullPath();
+     try {
+       queryService.createIndex("scoreIndex", "entry.value.score", 
r.getFullPath() + ".entrySet entry");
+       queryService.createIndex("scoreIndex2", "value.score", r.getFullPath() 
+ ".values value");
+     } catch (Exception e) {
+       if (!(e instanceof IndexNameConflictException)) {
+         if (logger.errorEnabled()) {
+           logger.error(e);
+         }
+       }
+     }
+     HashMap<Enum<?>, Query> queryList = new HashMap<Enum<?>, Query>();
+     for (SortedSetQuery lq: SortedSetQuery.values()) {
+       String queryString = lq.getQueryString(fullpath);
+       Query query = this.queryService.newQuery(queryString);
+       queryList.put(lq, query);
+     }
+     this.preparedQueries.put(key, queryList);
+   }
+ 
+   private void doInitializeList(ByteArrayWrapper key, Region r) {
+     r.put("head", Integer.valueOf(0));
+     r.put("tail", Integer.valueOf(0));
+     String fullpath = r.getFullPath();
+     HashMap<Enum<?>, Query> queryList = new HashMap<Enum<?>, Query>();
+     for (ListQuery lq: ListQuery.values()) {
+       String queryString = lq.getQueryString(fullpath);
+       Query query = this.queryService.newQuery(queryString);
+       queryList.put(lq, query);
+     }
+     this.preparedQueries.put(key, queryList);
+   }
+ 
+   /**
+    * This method creates a Region globally with the given name. If
+    * there is an error in the creation, a runtime exception will
+    * be thrown.
+    * 
+    * @param key Name of Region to create
+    * @return Region Region created globally
+    */
+   private Region<?, ?> createRegionGlobally(String key) {
+     Region<?, ?> r = null;
+     r = cache.getRegion(key);
+     if (r != null) return r;
+     do {
 -      Result result = cliCmds.createRegion(key, defaultRegionType, null, 
null, true, null, null, null, null, null, null, null, null, null, null, null, 
null, null, null, null, null, null, null, null, null, null, null, null, null, 
null, null, null, null, null, null, null, null, null, null);
++      Result result = cliCmds.createRegion(key, defaultRegionType, null, 
null, true, null, null, null, null, null, null, null, null, null, null, null, 
null, null, null, null, null, null, null, null, null, null, null, null, null, 
null, null, null, null, null, null, null, null, null, null, null);
+       r = cache.getRegion(key);
+       if (result.getStatus() == Status.ERROR && r == null) {
+         String err = "";
+         while(result.hasNextLine())
+           err += result.nextLine();
+         if (this.logger.errorEnabled()) {
+           this.logger.error("Region creation failure- "+ err);
+         }
+         throw new RegionCreationException(err);
+       }
+     } while(r == null); // The region can be null in the case that it is 
concurrently destroyed by
+     // a remote even triggered internally by Geode
+     return r;
+   }
+ 
+   public Query getQuery(ByteArrayWrapper key, Enum<?> query) {
+     return this.preparedQueries.get(key).get(query);
+     /*
+     if (query instanceof ListQuery) {
+       return 
this.queryService.newQuery(((ListQuery)query).getQueryString(this.regions.get(key).getFullPath()));
+     } else {
+       return 
this.queryService.newQuery(((SortedSetQuery)query).getQueryString(this.regions.get(key).getFullPath()));
+     }
+     */
+   }
+ 
+   /**
+    * Checks if the given key is associated with the passed data type.
+    * If there is a mismatch, a {@link RuntimeException} is thrown
+    * 
+    * @param key Key to check
+    * @param type Type to check to
+    */
+   protected void checkDataType(ByteArrayWrapper key, RedisDataType type) {
+     RedisDataType currentType = redisMetaRegion.get(key.toString());
+     if (currentType == null)
+       return;
+     if (currentType == RedisDataType.REDIS_PROTECTED)
+       throw new RedisDataTypeMismatchException("The key name \"" + key + "\" 
is protected");
+     if (currentType != type)
+       throw new RedisDataTypeMismatchException("The key name \"" + key + "\" 
is already used by a " + currentType.toString());
+   }
+ 
+   public boolean regionExists(ByteArrayWrapper key) {
+     return this.regions.containsKey(key);
+   }
+ 
+   public Region<ByteArrayWrapper, ByteArrayWrapper> getStringsRegion() {
+     return this.stringsRegion;
+   }
+ 
+   public Region<ByteArrayWrapper, HyperLogLogPlus> gethLLRegion() {
+     return this.hLLRegion;
+   }
+ 
+   private RedisDataType getRedisDataType(String key) {
+     return this.redisMetaRegion.get(key);
+   }
+ 
+   public RedisDataType getRedisDataType(ByteArrayWrapper key) {
+     return getRedisDataType(key.toString());
+   }
+ 
+   /**
+    * Sets the expiration for a key. The setting and modifying of a key 
expiration can only be set by a delay,
+    * which means that both expiring after a time and at a time can be done but
+    * the delay to expire at a time must be calculated before these calls. It 
is
+    * also important to note that the delay is always handled in milliseconds
+    * 
+    * @param key The key to set the expiration for
+    * @param delay The delay in milliseconds of the expiration
+    * @return True is expiration set, false otherwise
+    */
+   public final boolean setExpiration(ByteArrayWrapper key, long delay) {
+     RedisDataType type = getRedisDataType(key);
+     if (type == null)
+       return false;
+     ScheduledFuture<?> future = this.expirationExecutor.schedule(new 
ExpirationExecutor(key, type, this), delay, TimeUnit.MILLISECONDS);
+     this.expirationsMap.put(key, future);
+     return true;
+   }
+ 
+   /**
+    * Modifies an expiration on a key
+    * 
+    * @param key String key to modify expiration on
+    * @param delay Delay in milliseconds to reset the expiration to
+    * @return True if reset, false if not
+    */
+   public final boolean modifyExpiration(ByteArrayWrapper key, long delay) {
+     /*
+      * Attempt to cancel future task
+      */
+     boolean canceled = cancelKeyExpiration(key);
+ 
+     if (!canceled)
+       return false;
+ 
+     RedisDataType type = getRedisDataType(key);
+     if (type == null)
+       return false;
+ 
+     ScheduledFuture<?> future = this.expirationExecutor.schedule(new 
ExpirationExecutor(key, type, this), delay, TimeUnit.MILLISECONDS);
+     this.expirationsMap.put(key, future);
+     return true;
+   }
+ 
+   /**
+    * Removes an expiration from a key
+    * 
+    * @param key Key
+    * @param context Context
+    * @return True is expiration cancelled on the key, false otherwise
+    */
+   public final boolean cancelKeyExpiration(ByteArrayWrapper key) {
+     ScheduledFuture<?> future = expirationsMap.remove(key);
+     if (future == null)
+       return false;
+     return future.cancel(false);
+   }
+ 
+   private boolean removeKeyExpiration(ByteArrayWrapper key) {
+     return expirationsMap.remove(key) != null;
+   }
+ 
+   /**
+    * Check method if key has expiration
+    * 
+    * @param key Key
+    * @return True if key has expiration, false otherwise
+    */
+   public boolean hasExpiration(ByteArrayWrapper key) {
+     return this.expirationsMap.containsKey(key);
+   }
+ 
+   /**
+    * Get remaining expiration time
+    * 
+    * @param key Key
+    * @return Remaining time in milliseconds or 0 if no delay or key doesn't 
exist
+    */
+   public final long getExpirationDelayMillis(ByteArrayWrapper key) {
+     ScheduledFuture<?> future = this.expirationsMap.get(key);
+     return future != null ? future.getDelay(TimeUnit.MILLISECONDS) : 0L;
+   }
+ 
+   @Override
+   public void close() {
+     this.preparedQueries.clear();
+   }
+ 
+   public String dumpRegionsCache() {
+     StringBuilder builder = new StringBuilder();
+     for (Entry<ByteArrayWrapper, Region<?, ?>> e : this.regions.entrySet()) {
+       builder.append(e.getKey() + " --> {" + e.getValue() + "}\n");
+     }
+     return builder.toString();
+   }
+ 
+ }

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/e0d1c4f9/gemfire-core/src/main/java/com/gemstone/gemfire/management/internal/cli/i18n/CliStrings.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/e0d1c4f9/gemfire-core/src/test/java/com/gemstone/gemfire/cache/management/MemoryThresholdsOffHeapDUnitTest.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/e0d1c4f9/gemfire-core/src/test/java/com/gemstone/gemfire/cache/query/internal/index/CopyOnReadIndexDUnitTest.java
----------------------------------------------------------------------
diff --cc 
gemfire-core/src/test/java/com/gemstone/gemfire/cache/query/internal/index/CopyOnReadIndexDUnitTest.java
index e66c047,61bb55d..5ad8537
--- 
a/gemfire-core/src/test/java/com/gemstone/gemfire/cache/query/internal/index/CopyOnReadIndexDUnitTest.java
+++ 
b/gemfire-core/src/test/java/com/gemstone/gemfire/cache/query/internal/index/CopyOnReadIndexDUnitTest.java
@@@ -598,12 -601,25 +600,24 @@@ public class CopyOnReadIndexDUnitTest e
      return p;
    }
  
 -  protected Properties getServerProperties(int mcastPort) {
 +  protected Properties getServerProperties() {
      Properties p = new Properties();
 -    p.setProperty(DistributionConfig.MCAST_PORT_NAME, mcastPort+"");
 -    p.setProperty(DistributionConfig.LOCATORS_NAME, "");
 +    p.setProperty(DistributionConfig.LOCATORS_NAME, 
"localhost["+getDUnitLocatorPort()+"]");
      return p;
    }
-   
+ 
+   private WaitCriterion verifyPortfolioCount(final int expected) {
+     return new WaitCriterion() {
+       private int expectedCount = expected;
+       public boolean done() {
+         return expectedCount == Portfolio.instanceCount.get();
+       }
+       
+       public String description() {
+         return "verifying number of object instances created";
+       }
+     };
+   }
    
  
  }

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/e0d1c4f9/gemfire-core/src/test/java/com/gemstone/gemfire/internal/cache/ClientServerTransactionDUnitTest.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/e0d1c4f9/gemfire-core/src/test/java/dunit/DistributedTestCase.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/e0d1c4f9/settings.gradle
----------------------------------------------------------------------


Reply via email to