public LocalMapStats createStats(String name) {
    LocalMultiMapStatsImpl stats = getLocalMultiMapStatsImpl(name);
    long ownedEntryCount = 0;
    long backupEntryCount = 0;
    long hits = 0;
    long lockedEntryCount = 0;
    ClusterServiceImpl clusterService = (ClusterServiceImpl) nodeEngine.getClusterService();

    Address thisAddress = clusterService.getThisAddress();
    for (int i = 0; i < nodeEngine.getPartitionService().getPartitionCount(); i++) {
      InternalPartition partition = nodeEngine.getPartitionService().getPartition(i);
      MultiMapPartitionContainer partitionContainer = getPartitionContainer(i);
      MultiMapContainer multiMapContainer = partitionContainer.getCollectionContainer(name);
      if (multiMapContainer == null) {
        continue;
      }
      Address owner = partition.getOwnerOrNull();
      if (owner != null) {
        if (owner.equals(thisAddress)) {
          lockedEntryCount += multiMapContainer.getLockedCount();
          for (MultiMapWrapper wrapper : multiMapContainer.multiMapWrappers.values()) {
            hits += wrapper.getHits();
            ownedEntryCount += wrapper.getCollection(false).size();
          }
        } else {
          int backupCount = multiMapContainer.config.getTotalBackupCount();
          for (int j = 1; j <= backupCount; j++) {
            Address replicaAddress = partition.getReplicaAddress(j);
            int memberSize = nodeEngine.getClusterService().getMembers().size();

            int tryCount = REPLICA_ADDRESS_TRY_COUNT;
            // wait if the partition table is not updated yet
            while (memberSize > backupCount && replicaAddress == null && tryCount-- > 0) {
              try {
                Thread.sleep(REPLICA_ADDRESS_SLEEP_WAIT_MILLIS);
              } catch (InterruptedException e) {
                throw ExceptionUtil.rethrow(e);
              }
              replicaAddress = partition.getReplicaAddress(j);
            }

            if (replicaAddress != null && replicaAddress.equals(thisAddress)) {
              for (MultiMapWrapper wrapper : multiMapContainer.multiMapWrappers.values()) {
                backupEntryCount += wrapper.getCollection(false).size();
              }
            }
          }
        }
      }
    }
    stats.setOwnedEntryCount(ownedEntryCount);
    stats.setBackupEntryCount(backupEntryCount);
    stats.setHits(hits);
    stats.setLockedEntryCount(lockedEntryCount);
    return stats;
  }
Exemple #2
0
  public Runnable prepareMergeRunnable() {
    Map<MapContainer, Collection<Record>> recordMap =
        new HashMap<MapContainer, Collection<Record>>(mapContainers.size());
    InternalPartitionService partitionService = nodeEngine.getPartitionService();
    int partitionCount = partitionService.getPartitionCount();
    Address thisAddress = nodeEngine.getClusterService().getThisAddress();

    for (MapContainer mapContainer : mapContainers.values()) {
      for (int i = 0; i < partitionCount; i++) {
        RecordStore recordStore = getPartitionContainer(i).getRecordStore(mapContainer.getName());
        // add your owned entries to the map so they will be merged
        if (thisAddress.equals(partitionService.getPartitionOwner(i))) {
          Collection<Record> records = recordMap.get(mapContainer);
          if (records == null) {
            records = new ArrayList<Record>();
            recordMap.put(mapContainer, records);
          }
          records.addAll(recordStore.getReadonlyRecordMap().values());
        }
        // clear all records either owned or backup
        recordStore.reset();
      }
    }
    return new Merger(recordMap);
  }
Exemple #3
0
 @SuppressWarnings("unchecked")
 public void dispatchEvent(EventData eventData, EntryListener listener) {
   Member member = nodeEngine.getClusterService().getMember(eventData.getCaller());
   EntryEvent event =
       new DataAwareEntryEvent(
           member,
           eventData.getEventType(),
           eventData.getMapName(),
           eventData.getDataKey(),
           eventData.getDataNewValue(),
           eventData.getDataOldValue(),
           getSerializationService());
   switch (event.getEventType()) {
     case ADDED:
       listener.entryAdded(event);
       break;
     case EVICTED:
       listener.entryEvicted(event);
       break;
     case UPDATED:
       listener.entryUpdated(event);
       break;
     case REMOVED:
       listener.entryRemoved(event);
       break;
     default:
       throw new IllegalArgumentException("Invalid event type: " + event.getEventType());
   }
   MapContainer mapContainer = getMapContainer(eventData.getMapName());
   if (mapContainer.getMapConfig().isStatisticsEnabled()) {
     getLocalMapStatsImpl(eventData.getMapName()).incrementReceivedEvents();
   }
 }
 @Override
 public Xid[] recover(int flag) throws XAException {
   NodeEngine nodeEngine = getNodeEngine();
   XAService xaService = getService();
   OperationService operationService = nodeEngine.getOperationService();
   ClusterService clusterService = nodeEngine.getClusterService();
   Collection<Member> memberList = clusterService.getMembers();
   List<InternalCompletableFuture<SerializableList>> futureList =
       new ArrayList<InternalCompletableFuture<SerializableList>>();
   for (Member member : memberList) {
     if (member.localMember()) {
       continue;
     }
     CollectRemoteTransactionsOperation op = new CollectRemoteTransactionsOperation();
     Address address = member.getAddress();
     InternalCompletableFuture<SerializableList> future =
         operationService.invokeOnTarget(SERVICE_NAME, op, address);
     futureList.add(future);
   }
   HashSet<SerializableXID> xids = new HashSet<SerializableXID>();
   xids.addAll(xaService.getPreparedXids());
   for (InternalCompletableFuture<SerializableList> future : futureList) {
     SerializableList xidSet = future.getSafely();
     for (Data xidData : xidSet) {
       SerializableXID xid = nodeEngine.toObject(xidData);
       xids.add(xid);
     }
   }
   return xids.toArray(new SerializableXID[xids.size()]);
 }
Exemple #5
0
 public void invalidateAllNearCaches(String mapName, Set<Data> keys) {
   if (!isNearCacheEnabled(mapName)) {
     return;
   }
   if (keys == null || keys.isEmpty()) {
     return;
   }
   // send operation.
   Operation operation =
       new NearCacheKeySetInvalidationOperation(mapName, keys).setServiceName(SERVICE_NAME);
   Collection<MemberImpl> members = nodeEngine.getClusterService().getMemberList();
   for (MemberImpl member : members) {
     try {
       if (member.localMember()) continue;
       nodeEngine.getOperationService().send(operation, member.getAddress());
     } catch (Throwable throwable) {
       logger.warning(throwable);
     }
   }
   // below local invalidation is for the case the data is cached before partition is
   // owned/migrated
   for (final Data key : keys) {
     invalidateNearCache(mapName, key);
   }
 }
 private void rollbackTxBackup() {
   final OperationService operationService = nodeEngine.getOperationService();
   final List<Future> futures = new ArrayList<Future>(txLogs.size());
   // rollback tx backup
   if (durability > 0 && transactionType.equals(TransactionType.TWO_PHASE)) {
     for (Address backupAddress : backupAddresses) {
       if (nodeEngine.getClusterService().getMember(backupAddress) != null) {
         final Future f =
             operationService.invokeOnTarget(
                 TransactionManagerServiceImpl.SERVICE_NAME,
                 new RollbackTxBackupOperation(txnId),
                 backupAddress);
         futures.add(f);
       }
     }
     for (Future future : futures) {
       try {
         future.get(timeoutMillis, TimeUnit.MILLISECONDS);
       } catch (Throwable e) {
         nodeEngine.getLogger(getClass()).warning("Error during tx rollback backup!", e);
       }
     }
     futures.clear();
   }
 }
Exemple #7
0
  public void connectionRemoved(Connection connection) {
    if (connection.isClient() && connection instanceof TcpIpConnection && nodeEngine.isActive()) {
      final ClientEndpoint endpoint = endpoints.get(connection);
      if (endpoint != null
          && node.getLocalMember().getUuid().equals(endpoint.getPrincipal().getOwnerUuid())) {
        removeEndpoint(connection, true);
        if (!endpoint.isFirstConnection()) {
          return;
        }
        NodeEngine nodeEngine = node.nodeEngine;
        final Collection<MemberImpl> memberList = nodeEngine.getClusterService().getMemberList();
        for (MemberImpl member : memberList) {
          final ClientDisconnectionOperation op =
              new ClientDisconnectionOperation(endpoint.getUuid());
          op.setNodeEngine(nodeEngine)
              .setServiceName(SERVICE_NAME)
              .setService(this)
              .setResponseHandler(ResponseHandlerFactory.createEmptyResponseHandler());

          if (member.localMember()) {
            nodeEngine.getOperationService().runOperation(op);
          } else {
            nodeEngine.getOperationService().send(op, member.getAddress());
          }
        }
      }
    }
  }
  protected MapProxySupport(
      String name, MapService service, NodeEngine nodeEngine, MapConfig mapConfig) {
    super(nodeEngine, service);
    this.name = name;

    HazelcastProperties properties = nodeEngine.getProperties();

    this.mapServiceContext = service.getMapServiceContext();
    this.mapConfig = mapConfig;
    this.partitionStrategy =
        PartitioningStrategyFactory.getPartitioningStrategy(
            nodeEngine, mapConfig.getName(), mapConfig.getPartitioningStrategyConfig());
    this.localMapStats = mapServiceContext.getLocalMapStatsProvider().getLocalMapStatsImpl(name);
    this.partitionService = getNodeEngine().getPartitionService();
    this.lockSupport =
        new LockProxySupport(
            new DefaultObjectNamespace(SERVICE_NAME, name),
            LockServiceImpl.getMaxLeaseTimeInMillis(properties));
    this.operationProvider = mapServiceContext.getMapOperationProvider(name);
    this.operationService = nodeEngine.getOperationService();
    this.serializationService = nodeEngine.getSerializationService();
    this.thisAddress = nodeEngine.getClusterService().getThisAddress();
    this.statisticsEnabled = mapConfig.isStatisticsEnabled();

    this.putAllBatchSize = properties.getInteger(MAP_PUT_ALL_BATCH_SIZE);
    this.putAllInitialSizeFactor = properties.getFloat(MAP_PUT_ALL_INITIAL_SIZE_FACTOR);
  }
 public MultiMapService(NodeEngine nodeEngine) {
   this.nodeEngine = nodeEngine;
   int partitionCount = nodeEngine.getPartitionService().getPartitionCount();
   partitionContainers = new MultiMapPartitionContainer[partitionCount];
   this.logger = nodeEngine.getLogger(MultiMapService.class);
   dispatcher = new MultiMapEventsDispatcher(this, nodeEngine.getClusterService());
   publisher = new MultiMapEventsPublisher(nodeEngine);
 }
 public LocalMapStatsProvider(MapServiceContext mapServiceContext) {
   this.mapServiceContext = mapServiceContext;
   NodeEngine nodeEngine = mapServiceContext.getNodeEngine();
   this.logger = nodeEngine.getLogger(getClass());
   this.nearCacheProvider = mapServiceContext.getNearCacheProvider();
   this.clusterService = nodeEngine.getClusterService();
   this.partitionService = nodeEngine.getPartitionService();
 }
 protected void destroyCacheOnAllMembers(String name, String callerUuid) {
   final OperationService operationService = nodeEngine.getOperationService();
   final Collection<Member> members = nodeEngine.getClusterService().getMembers();
   for (Member member : members) {
     if (!member.localMember() && !member.getUuid().equals(callerUuid)) {
       final CacheDestroyOperation op = new CacheDestroyOperation(name, true);
       operationService.invokeOnTarget(AbstractCacheService.SERVICE_NAME, op, member.getAddress());
     }
   }
 }
 @Override
 public void run() {
   final long now = Clock.currentTimeMillis();
   final String mapName = this.mapName;
   final MapServiceContext mapServiceContext = this.mapServiceContext;
   final NodeEngine nodeEngine = mapServiceContext.getNodeEngine();
   final ClusterService clusterService = nodeEngine.getClusterService();
   final InternalPartitionService partitionService = nodeEngine.getPartitionService();
   final Address thisAddress = clusterService.getThisAddress();
   final int partitionCount = partitionService.getPartitionCount();
   Map<Integer, Integer> partitionToEntryCountHolder = Collections.emptyMap();
   List<DelayedEntry> entries = Collections.emptyList();
   boolean createLazy = true;
   for (int partitionId = 0; partitionId < partitionCount; partitionId++) {
     final InternalPartition partition = partitionService.getPartition(partitionId, false);
     final Address owner = partition.getOwnerOrNull();
     final RecordStore recordStore = getRecordStoreOrNull(mapName, partitionId);
     if (owner == null || recordStore == null) {
       // no-op because no owner is set yet.
       // Therefore we don't know anything about the map
       continue;
     }
     final WriteBehindQueue<DelayedEntry> queue = getWriteBehindQueue(recordStore);
     final List<DelayedEntry> delayedEntries = filterItemsLessThanOrEqualToTime(queue, now);
     if (delayedEntries.isEmpty()) {
       continue;
     }
     if (!owner.equals(thisAddress)) {
       if (now > lastRunTime + backupRunIntervalTime) {
         doInBackup(queue, delayedEntries, partitionId);
       }
       continue;
     }
     // initialize when needed, we do not want
     // to create these on backups for every second.
     if (createLazy) {
       partitionToEntryCountHolder = new HashMap<Integer, Integer>();
       entries = new ArrayList<DelayedEntry>();
       createLazy = false;
     }
     partitionToEntryCountHolder.put(partitionId, delayedEntries.size());
     entries.addAll(delayedEntries);
   }
   if (!entries.isEmpty()) {
     final Map<Integer, List<DelayedEntry>> failsPerPartition =
         writeBehindProcessor.process(entries);
     removeProcessed(mapName, getEntryPerPartitionMap(entries));
     addFailsToQueue(mapName, failsPerPartition);
     lastRunTime = now;
   }
 }
 private List<Future> startTxBackup() {
   final OperationService operationService = nodeEngine.getOperationService();
   List<Future> futures = new ArrayList<Future>(backupAddresses.length);
   for (Address backupAddress : backupAddresses) {
     if (nodeEngine.getClusterService().getMember(backupAddress) != null) {
       final Future f =
           operationService.invokeOnTarget(
               TransactionManagerServiceImpl.SERVICE_NAME,
               new BeginTxBackupOperation(txOwnerUuid, txnId, xid),
               backupAddress);
       futures.add(f);
     }
   }
   return futures;
 }
 /**
  * @param queue write behind queue.
  * @param delayedEntries entries to be processed.
  * @param partitionId corresponding partition id.
  */
 private void doInBackup(
     final WriteBehindQueue queue,
     final List<DelayedEntry> delayedEntries,
     final int partitionId) {
   final NodeEngine nodeEngine = mapServiceContext.getNodeEngine();
   final ClusterService clusterService = nodeEngine.getClusterService();
   final InternalPartitionService partitionService = nodeEngine.getPartitionService();
   final Address thisAddress = clusterService.getThisAddress();
   final InternalPartition partition = partitionService.getPartition(partitionId, false);
   final Address owner = partition.getOwnerOrNull();
   if (owner != null && !owner.equals(thisAddress)) {
     writeBehindProcessor.callBeforeStoreListeners(delayedEntries);
     removeProcessed(mapName, getEntryPerPartitionMap(delayedEntries));
     writeBehindProcessor.callAfterStoreListeners(delayedEntries);
   }
 }
 public void removeMapInterceptorInternal(String id) {
   NodeEngine nodeEngine = getNodeEngine();
   mapServiceContext.removeInterceptor(name, id);
   Collection<Member> members = nodeEngine.getClusterService().getMembers();
   for (Member member : members) {
     try {
       if (member.localMember()) {
         continue;
       }
       RemoveInterceptorOperation op = new RemoveInterceptorOperation(name, id);
       Future future = operationService.invokeOnTarget(SERVICE_NAME, op, member.getAddress());
       future.get();
     } catch (Throwable t) {
       throw rethrow(t);
     }
   }
 }
 private void purgeTxBackups() {
   if (durability > 0 && transactionType.equals(TransactionType.TWO_PHASE)) {
     final OperationService operationService = nodeEngine.getOperationService();
     for (Address backupAddress : backupAddresses) {
       if (nodeEngine.getClusterService().getMember(backupAddress) != null) {
         try {
           operationService.invokeOnTarget(
               TransactionManagerServiceImpl.SERVICE_NAME,
               new PurgeTxBackupOperation(txnId),
               backupAddress);
         } catch (Throwable e) {
           nodeEngine.getLogger(getClass()).warning("Error during purging backups!", e);
         }
       }
     }
   }
 }
 public Set<Data> localKeySet(String name) {
   Set<Data> keySet = new HashSet<Data>();
   ClusterServiceImpl clusterService = (ClusterServiceImpl) nodeEngine.getClusterService();
   Address thisAddress = clusterService.getThisAddress();
   for (int i = 0; i < nodeEngine.getPartitionService().getPartitionCount(); i++) {
     InternalPartition partition = nodeEngine.getPartitionService().getPartition(i);
     MultiMapPartitionContainer partitionContainer = getPartitionContainer(i);
     MultiMapContainer multiMapContainer = partitionContainer.getCollectionContainer(name);
     if (multiMapContainer == null) {
       continue;
     }
     if (thisAddress.equals(partition.getOwnerOrNull())) {
       keySet.addAll(multiMapContainer.keySet());
     }
   }
   getLocalMultiMapStatsImpl(name).incrementOtherOperations();
   return keySet;
 }
Exemple #18
0
 public void invalidateAllNearCaches(String mapName, Data key) {
   if (!isNearCacheEnabled(mapName)) {
     return;
   }
   Collection<MemberImpl> members = nodeEngine.getClusterService().getMemberList();
   for (MemberImpl member : members) {
     try {
       if (member.localMember()) continue;
       Operation operation =
           new InvalidateNearCacheOperation(mapName, key).setServiceName(SERVICE_NAME);
       nodeEngine.getOperationService().send(operation, member.getAddress());
     } catch (Throwable throwable) {
       throw new HazelcastException(throwable);
     }
   }
   // below local invalidation is for the case the data is cached before partition is
   // owned/migrated
   invalidateNearCache(mapName, key);
 }
 private void replicateTxnLog()
     throws InterruptedException, ExecutionException, java.util.concurrent.TimeoutException {
   final List<Future> futures = new ArrayList<Future>(txLogs.size());
   final OperationService operationService = nodeEngine.getOperationService();
   for (Address backupAddress : backupAddresses) {
     if (nodeEngine.getClusterService().getMember(backupAddress) != null) {
       final Future f =
           operationService.invokeOnTarget(
               TransactionManagerServiceImpl.SERVICE_NAME,
               new ReplicateTxOperation(txLogs, txOwnerUuid, txnId, timeoutMillis, startTime),
               backupAddress);
       futures.add(f);
     }
   }
   for (Future future : futures) {
     future.get(timeoutMillis, TimeUnit.MILLISECONDS);
   }
   futures.clear();
 }
 public String addMapInterceptorInternal(MapInterceptor interceptor) {
   NodeEngine nodeEngine = getNodeEngine();
   if (interceptor instanceof HazelcastInstanceAware) {
     ((HazelcastInstanceAware) interceptor)
         .setHazelcastInstance(nodeEngine.getHazelcastInstance());
   }
   String id = mapServiceContext.generateInterceptorId(name, interceptor);
   Collection<Member> members = nodeEngine.getClusterService().getMembers();
   for (Member member : members) {
     try {
       AddInterceptorOperation op = new AddInterceptorOperation(id, interceptor, name);
       Future future = operationService.invokeOnTarget(SERVICE_NAME, op, member.getAddress());
       future.get();
     } catch (Throwable t) {
       throw rethrow(t);
     }
   }
   return id;
 }
  public void dispatchEvent(MultiMapEvent event, EventListener listener) {
    EntryListener entryListener = (EntryListener) listener;
    final MemberImpl member = nodeEngine.getClusterService().getMember(event.getCaller());
    EntryEvent entryEvent =
        new EntryEvent(
            event.getName(),
            member,
            event.getEventType().getType(),
            nodeEngine.toObject(event.getKey()),
            nodeEngine.toObject(event.getValue()));
    if (member == null) {
      if (logger.isLoggable(Level.INFO)) {
        logger.info("Dropping event " + entryEvent + " from unknown address:" + event.getCaller());
      }
      return;
    }

    if (event.getEventType().equals(EntryEventType.ADDED)) {
      entryListener.entryAdded(entryEvent);
    } else if (event.getEventType().equals(EntryEventType.REMOVED)) {
      entryListener.entryRemoved(entryEvent);
    }
    getLocalMultiMapStatsImpl(event.getName()).incrementReceivedEvents();
  }
Exemple #22
0
  public LocalMapStatsImpl createLocalMapStats(String mapName) {
    MapContainer mapContainer = getMapContainer(mapName);
    LocalMapStatsImpl localMapStats = getLocalMapStatsImpl(mapName);
    if (!mapContainer.getMapConfig().isStatisticsEnabled()) {
      return localMapStats;
    }

    long ownedEntryCount = 0;
    long backupEntryCount = 0;
    long dirtyCount = 0;
    long ownedEntryMemoryCost = 0;
    long backupEntryMemoryCost = 0;
    long hits = 0;
    long lockedEntryCount = 0;
    long heapCost = 0;

    int backupCount = mapContainer.getTotalBackupCount();
    ClusterService clusterService = nodeEngine.getClusterService();
    final InternalPartitionService partitionService = nodeEngine.getPartitionService();

    Address thisAddress = clusterService.getThisAddress();
    for (int partitionId = 0; partitionId < partitionService.getPartitionCount(); partitionId++) {
      InternalPartition partition = partitionService.getPartition(partitionId);
      Address owner = partition.getOwner();
      if (owner == null) {
        // no-op because no owner is set yet. Therefor we don't know anything about the map
        continue;
      }
      if (owner.equals(thisAddress)) {
        PartitionContainer partitionContainer = getPartitionContainer(partitionId);
        RecordStore recordStore = partitionContainer.getExistingRecordStore(mapName);

        // we don't want to force loading the record store because we are loading statistics. So
        // that is why
        // we ask for 'getExistingRecordStore' instead of 'getRecordStore' which does the load.
        if (recordStore != null) {
          heapCost += recordStore.getHeapCost();
          Map<Data, Record> records = recordStore.getReadonlyRecordMap();
          for (Record record : records.values()) {
            RecordStatistics stats = record.getStatistics();
            // there is map store and the record is dirty (waits to be stored)
            ownedEntryCount++;
            ownedEntryMemoryCost += record.getCost();
            localMapStats.setLastAccessTime(stats.getLastAccessTime());
            localMapStats.setLastUpdateTime(stats.getLastUpdateTime());
            hits += stats.getHits();
            if (recordStore.isLocked(record.getKey())) {
              lockedEntryCount++;
            }
          }
        }
      } else {
        for (int replica = 1; replica <= backupCount; replica++) {
          Address replicaAddress = partition.getReplicaAddress(replica);
          int tryCount = 30;
          // wait if the partition table is not updated yet
          while (replicaAddress == null
              && clusterService.getSize() > backupCount
              && tryCount-- > 0) {
            try {
              Thread.sleep(100);
            } catch (InterruptedException e) {
              throw ExceptionUtil.rethrow(e);
            }
            replicaAddress = partition.getReplicaAddress(replica);
          }

          if (replicaAddress != null && replicaAddress.equals(thisAddress)) {
            PartitionContainer partitionContainer = getPartitionContainer(partitionId);
            RecordStore recordStore = partitionContainer.getRecordStore(mapName);
            heapCost += recordStore.getHeapCost();

            Map<Data, Record> records = recordStore.getReadonlyRecordMap();
            for (Record record : records.values()) {
              backupEntryCount++;
              backupEntryMemoryCost += record.getCost();
            }
          } else if (replicaAddress == null && clusterService.getSize() > backupCount) {
            logger.warning("Partition: " + partition + ", replica: " + replica + " has no owner!");
          }
        }
      }
    }

    if (mapContainer.getMapStoreScheduler() != null) {
      dirtyCount = mapContainer.getMapStoreScheduler().size();
    }
    localMapStats.setBackupCount(backupCount);
    localMapStats.setDirtyEntryCount(zeroOrPositive(dirtyCount));
    localMapStats.setLockedEntryCount(zeroOrPositive(lockedEntryCount));
    localMapStats.setHits(zeroOrPositive(hits));
    localMapStats.setOwnedEntryCount(zeroOrPositive(ownedEntryCount));
    localMapStats.setBackupEntryCount(zeroOrPositive(backupEntryCount));
    localMapStats.setOwnedEntryMemoryCost(zeroOrPositive(ownedEntryMemoryCost));
    localMapStats.setBackupEntryMemoryCost(zeroOrPositive(backupEntryMemoryCost));
    // add near cache heap cost.
    heapCost += mapContainer.getNearCacheSizeEstimator().getSize();
    localMapStats.setHeapCost(heapCost);
    if (mapContainer.getMapConfig().isNearCacheEnabled()) {
      NearCacheStatsImpl nearCacheStats = getNearCache(mapName).getNearCacheStats();
      localMapStats.setNearCacheStats(nearCacheStats);
    }

    return localMapStats;
  }
  public void run() {
    final NodeEngine nodeEngine = getNodeEngine();
    final Address masterAddress = nodeEngine.getMasterAddress();
    if (!masterAddress.equals(migrationInfo.getMaster())) {
      throw new RetryableHazelcastException(
          "Migration initiator is not master node! => " + toString());
    }
    if (!masterAddress.equals(getCallerAddress())) {
      throw new RetryableHazelcastException("Caller is not master node! => " + toString());
    }

    final Address source = migrationInfo.getSource();
    final Address destination = migrationInfo.getDestination();
    final Member target = nodeEngine.getClusterService().getMember(destination);
    if (target == null) {
      throw new RetryableHazelcastException(
          "Destination of migration could not be found! => " + toString());
    }
    if (destination.equals(source)) {
      getLogger().warning("Source and destination addresses are the same! => " + toString());
      success = false;
      return;
    }

    if (source == null || !source.equals(nodeEngine.getThisAddress())) {
      throw new RetryableHazelcastException(
          "Source of migration is not this node! => " + toString());
    }
    if (migrationInfo.startProcessing()) {
      try {
        PartitionServiceImpl partitionService = getService();
        PartitionImpl partition = partitionService.getPartition(migrationInfo.getPartitionId());
        final Address owner = partition.getOwner();
        if (!source.equals(owner)) {
          throw new HazelcastException(
              "Cannot migrate! This node is not owner of the partition => "
                  + migrationInfo
                  + " -> "
                  + partition);
        }
        partitionService.addActiveMigration(migrationInfo);
        final long[] replicaVersions =
            partitionService.getPartitionReplicaVersions(migrationInfo.getPartitionId());
        final long timeout = nodeEngine.getGroupProperties().PARTITION_MIGRATION_TIMEOUT.getLong();
        final Collection<Operation> tasks = prepareMigrationTasks();
        if (tasks.size() > 0) {
          returnResponse = false;
          final ResponseHandler responseHandler = getResponseHandler();
          final SerializationService serializationService = nodeEngine.getSerializationService();

          nodeEngine
              .getExecutionService()
              .getExecutor(ExecutionService.ASYNC_EXECUTOR)
              .execute(
                  new Runnable() {
                    public void run() {
                      final BufferObjectDataOutput out =
                          serializationService.createObjectDataOutput(1024 * 32);
                      try {
                        out.writeInt(tasks.size());
                        for (Operation task : tasks) {
                          serializationService.writeObject(out, task);
                        }
                        final byte[] data;
                        boolean compress =
                            nodeEngine
                                .getGroupProperties()
                                .PARTITION_MIGRATION_ZIP_ENABLED
                                .getBoolean();
                        if (compress) {
                          data = IOUtil.compress(out.toByteArray());
                        } else {
                          data = out.toByteArray();
                        }
                        final MigrationOperation migrationOperation =
                            new MigrationOperation(
                                migrationInfo, replicaVersions, data, tasks.size(), compress);
                        Invocation inv =
                            nodeEngine
                                .getOperationService()
                                .createInvocationBuilder(
                                    PartitionServiceImpl.SERVICE_NAME,
                                    migrationOperation,
                                    destination)
                                .setTryPauseMillis(1000)
                                .setReplicaIndex(getReplicaIndex())
                                .build();
                        Future future = inv.invoke();
                        Boolean result =
                            (Boolean) nodeEngine.toObject(future.get(timeout, TimeUnit.SECONDS));
                        responseHandler.sendResponse(result);
                      } catch (Throwable e) {
                        responseHandler.sendResponse(Boolean.FALSE);
                        if (e instanceof ExecutionException) {
                          e = e.getCause() != null ? e.getCause() : e;
                        }
                        Level level =
                            (e instanceof MemberLeftException || e instanceof InterruptedException)
                                    || !getNodeEngine().isActive()
                                ? Level.INFO
                                : Level.WARNING;
                        getLogger().log(level, e.getMessage(), e);
                      } finally {
                        IOUtil.closeResource(out);
                      }
                    }
                  });
        } else {
          success = true;
        }
      } catch (Throwable e) {
        getLogger().warning(e);
        success = false;
      } finally {
        migrationInfo.doneProcessing();
      }
    } else {
      getLogger().warning("Migration is cancelled -> " + migrationInfo);
      success = false;
    }
  }