public void publishWanReplicationRemove(String mapName, Data key, long removeTime) { MapContainer mapContainer = getMapContainer(mapName); MapReplicationRemove replicationEvent = new MapReplicationRemove(mapName, key, removeTime); mapContainer .getWanReplicationPublisher() .publishReplicationEvent(SERVICE_NAME, replicationEvent); }
@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(); } }
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); }
public void publishWanReplicationUpdate(String mapName, EntryView entryView) { MapContainer mapContainer = getMapContainer(mapName); MapReplicationUpdate replicationEvent = new MapReplicationUpdate(mapName, mapContainer.getWanMergePolicy(), entryView); mapContainer .getWanReplicationPublisher() .publishReplicationEvent(SERVICE_NAME, replicationEvent); }
private void destroyMapStores() { for (MapContainer mapContainer : mapContainers.values()) { MapStoreWrapper store = mapContainer.getStore(); if (store != null) { store.destroy(); } } }
public boolean compare(String mapName, Object value1, Object value2) { if (value1 == null && value2 == null) { return true; } if (value1 == null) { return false; } if (value2 == null) { return false; } MapContainer mapContainer = getMapContainer(mapName); return mapContainer.getRecordFactory().isEquals(value1, value2); }
public void destroyDistributedObject(String name) { MapContainer mapContainer = mapContainers.remove(name); if (mapContainer != null) { if (mapContainer.isNearCacheEnabled()) { NearCache nearCache = nearCacheMap.remove(name); if (nearCache != null) { nearCache.clear(); } } mapContainer.shutDownMapStoreScheduledExecutor(); } final PartitionContainer[] containers = partitionContainers; for (PartitionContainer container : containers) { if (container != null) { container.destroyMap(name); } } nodeEngine.getEventService().deregisterAllListeners(SERVICE_NAME, name); }
public void run() { for (final MapContainer mapContainer : recordMap.keySet()) { Collection<Record> recordList = recordMap.get(mapContainer); String mergePolicyName = mapContainer.getMapConfig().getMergePolicy(); MapMergePolicy mergePolicy = getMergePolicy(mergePolicyName); // todo number of records may be high. below can be optimized a many records can be send in // single invocation final MapMergePolicy finalMergePolicy = mergePolicy; for (final Record record : recordList) { // todo too many submission. should submit them in subgroups nodeEngine .getExecutionService() .submit( "hz:map-merge", new Runnable() { public void run() { SimpleEntryView entryView = new SimpleEntryView( record.getKey(), toData(record.getValue()), record.getStatistics(), record.getCost(), record.getVersion()); MergeOperation operation = new MergeOperation( mapContainer.getName(), record.getKey(), entryView, finalMergePolicy); try { int partitionId = nodeEngine.getPartitionService().getPartitionId(record.getKey()); Future f = nodeEngine .getOperationService() .invokeOnPartition(SERVICE_NAME, operation, partitionId); f.get(); } catch (Throwable t) { throw ExceptionUtil.rethrow(t); } } }); } } }
@Override public void onReplicationEvent(WanReplicationEvent replicationEvent) { Object eventObject = replicationEvent.getEventObject(); if (eventObject instanceof MapReplicationUpdate) { MapReplicationUpdate replicationUpdate = (MapReplicationUpdate) eventObject; EntryView entryView = replicationUpdate.getEntryView(); MapMergePolicy mergePolicy = replicationUpdate.getMergePolicy(); String mapName = replicationUpdate.getMapName(); MapContainer mapContainer = getMapContainer(mapName); MergeOperation operation = new MergeOperation( mapName, toData(entryView.getKey(), mapContainer.getPartitioningStrategy()), entryView, mergePolicy); try { int partitionId = nodeEngine.getPartitionService().getPartitionId(entryView.getKey()); Future f = nodeEngine .getOperationService() .invokeOnPartition(SERVICE_NAME, operation, partitionId); f.get(); } catch (Throwable t) { throw ExceptionUtil.rethrow(t); } } else if (eventObject instanceof MapReplicationRemove) { MapReplicationRemove replicationRemove = (MapReplicationRemove) eventObject; WanOriginatedDeleteOperation operation = new WanOriginatedDeleteOperation( replicationRemove.getMapName(), replicationRemove.getKey()); try { int partitionId = nodeEngine.getPartitionService().getPartitionId(replicationRemove.getKey()); Future f = nodeEngine .getOperationService() .invokeOnPartition(SERVICE_NAME, operation, partitionId); f.get(); } catch (Throwable t) { throw ExceptionUtil.rethrow(t); } } }
private void migrateIndex(PartitionMigrationEvent event) { final PartitionContainer container = partitionContainers[event.getPartitionId()]; for (RecordStore recordStore : container.getMaps().values()) { final MapContainer mapContainer = getMapContainer(recordStore.getName()); final IndexService indexService = mapContainer.getIndexService(); if (indexService.hasIndex()) { for (Record record : recordStore.getReadonlyRecordMap().values()) { if (event.getMigrationEndpoint() == MigrationEndpoint.SOURCE) { indexService.removeEntryIndex(record.getKey()); } else { Object value = record.getValue(); if (value != null) { indexService.saveEntryIndex( new QueryEntry( getSerializationService(), record.getKey(), record.getKey(), value)); } } } } } }
private void setDelays(MapContainer mapContainer, RecordInfo info, Data key, int extraDelay) { long deleteDelay = -1; long writeDelay = -1; long idleDelay; long ttlDelay; if (mapContainer.getMapStoreScheduler() != null) { final ScheduledEntry scheduledEntry = mapContainer.getMapStoreScheduler().get(key); if (scheduledEntry != null) { if (scheduledEntry.getValue() == null) { deleteDelay = extraDelay + findDelayMillis(scheduledEntry); } else { writeDelay = extraDelay + findDelayMillis(scheduledEntry); } } } idleDelay = getDelay(mapContainer.getIdleEvictionScheduler(), key, extraDelay); ttlDelay = getDelay(mapContainer.getTtlEvictionScheduler(), key, extraDelay); // set delays. info.setMapStoreDeleteDelayMillis(deleteDelay); info.setMapStoreWriteDelayMillis(writeDelay); info.setIdleDelayMillis(idleDelay); info.setTtlDelayMillis(ttlDelay); }
public Record createRecord( String name, Data dataKey, Object value, long ttl, boolean shouldSchedule) { MapContainer mapContainer = getMapContainer(name); Record record = mapContainer.getRecordFactory().newRecord(dataKey, value); if (shouldSchedule) { // if ttl is 0 then no eviction. if ttl is -1 then default configured eviction is applied if (ttl < 0 && mapContainer.getMapConfig().getTimeToLiveSeconds() > 0) { scheduleTtlEviction( name, record, mapContainer.getMapConfig().getTimeToLiveSeconds() * 1000); } else if (ttl > 0) { scheduleTtlEviction(name, record, ttl); } if (mapContainer.getMapConfig().getMaxIdleSeconds() > 0) { scheduleIdleEviction(name, dataKey, mapContainer.getMapConfig().getMaxIdleSeconds() * 1000); } } return record; }
public boolean isNearCacheEnabled(String mapName) { final MapContainer mapContainer = getMapContainer(mapName); return mapContainer.isNearCacheEnabled(); }
public boolean isNearCacheAndInvalidationEnabled(String mapName) { final MapContainer mapContainer = getMapContainer(mapName); return mapContainer.isNearCacheEnabled() && mapContainer.getMapConfig().getNearCacheConfig().isInvalidateOnChange(); }
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; }