Exemple #1
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);
  }
 private List<Object>[] buildMapping(InternalPartitionService partitionService) {
   List<Object>[] mapping = new List[partitionService.getPartitionCount()];
   for (Object key : keys) {
     int pid = partitionService.getPartitionId(key);
     List<Object> list = mapping[pid];
     if (list == null) {
       list = new ArrayList<Object>();
       mapping[pid] = list;
     }
     list.add(key);
   }
   return mapping;
 }
 @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;
   }
 }
  @Override
  public Collection<Integer> getPartitions() {
    InternalPartitionService partitionService = getClientEngine().getPartitionService();
    int partitions = partitionService.getPartitionCount();
    int capacity = Math.min(partitions, keys.size()); // todo: is there better way to estimate size?
    Set<Integer> partitionIds = new HashSet<Integer>(capacity);

    Iterator<Data> iterator = keys.iterator();
    while (iterator.hasNext() && partitionIds.size() < partitions) {
      Data key = iterator.next();
      partitionIds.add(partitionService.getPartitionId(key));
    }
    return partitionIds;
  }
  public LocalMapStatsImpl createLocalMapStats(String mapName) {
    MapContainer mapContainer = mapServiceContext.getMapContainer(mapName);
    LocalMapStatsImpl stats = getLocalMapStatsImpl(mapName);
    if (!mapContainer.getMapConfig().isStatisticsEnabled()) {
      return stats;
    }
    int backupCount = mapContainer.getTotalBackupCount();
    Address thisAddress = clusterService.getThisAddress();

    LocalMapOnDemandCalculatedStats onDemandStats = new LocalMapOnDemandCalculatedStats();
    onDemandStats.setBackupCount(backupCount);

    addNearCacheStats(stats, onDemandStats, mapContainer);

    for (int partitionId = 0; partitionId < partitionService.getPartitionCount(); partitionId++) {
      InternalPartition partition = partitionService.getPartition(partitionId);
      Address owner = partition.getOwnerOrNull();
      if (owner == null) {
        // no-op because no owner is set yet. Therefore we don't know anything about the map
        continue;
      }

      if (owner.equals(thisAddress)) {
        addOwnerPartitionStats(stats, onDemandStats, mapName, partitionId);
      } else {
        addReplicaPartitionStats(
            onDemandStats,
            mapName,
            partitionId,
            partition,
            partitionService,
            backupCount,
            thisAddress);
      }
    }

    onDemandStats.copyValuesTo(stats);

    return stats;
  }
Exemple #6
0
 private static boolean isEvictablePerPartition(final MapContainer mapContainer) {
   final MapService mapService = mapContainer.getMapService();
   final MaxSizeConfig maxSizeConfig = mapContainer.getMapConfig().getMaxSizeConfig();
   final int maxSize = getApproximateMaxSize(maxSizeConfig.getSize());
   final String mapName = mapContainer.getName();
   final NodeEngine nodeEngine = mapService.getNodeEngine();
   final InternalPartitionService partitionService = nodeEngine.getPartitionService();
   for (int i = 0; i < partitionService.getPartitionCount(); i++) {
     final Address owner = partitionService.getPartitionOwner(i);
     if (nodeEngine.getThisAddress().equals(owner)) {
       final PartitionContainer container = mapService.getPartitionContainer(i);
       if (container == null) {
         return false;
       }
       final int size = container.getRecordStore(mapName).size();
       if (size >= maxSize) {
         return true;
       }
     }
   }
   return false;
 }
Exemple #7
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;
  }