blob: 96d871db06bd969efe0ce279a672b2fa9ae89f27 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more contributor license
* agreements. See the NOTICE file distributed with this work for additional information regarding
* copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License. You may obtain a
* copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package org.apache.geode.internal.cache;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.Callable;
import org.apache.logging.log4j.Logger;
import org.apache.geode.cache.RegionDestroyedException;
import org.apache.geode.distributed.internal.DistributionConfig;
import org.apache.geode.internal.cache.lru.HeapEvictor;
import org.apache.geode.internal.i18n.LocalizedStrings;
import org.apache.geode.internal.logging.LogService;
import org.apache.geode.internal.logging.log4j.LocalizedMessage;
/**
* Takes delta to be evicted and tries to evict the least no of LRU entry which would make
* evictedBytes more than or equal to the delta
*
* @since GemFire 6.0
*/
public class RegionEvictorTask implements Runnable {
private static final Logger logger = LogService.getLogger();
private static final int EVICTION_BURST_PAUSE_TIME_MILLIS;
public static int TEST_EVICTION_BURST_PAUSE_TIME_MILLIS = Integer.MAX_VALUE;
static {
EVICTION_BURST_PAUSE_TIME_MILLIS = Integer
.getInteger(DistributionConfig.GEMFIRE_PREFIX + "evictionBurstPauseTimeMillis", 1000);
}
private static volatile long lastTaskCompletionTime = 0;
public static void setLastTaskCompletionTime(long v) {
lastTaskCompletionTime = v;
}
public static long getLastTaskCompletionTime() {
return lastTaskCompletionTime;
}
private List<LocalRegion> regionSet;
private final HeapEvictor evictor;
private final long bytesToEvictPerTask;
public RegionEvictorTask(List<LocalRegion> regionSet, HeapEvictor evictor,
long bytesToEvictPerTask) {
this.evictor = evictor;
this.regionSet = regionSet;
this.bytesToEvictPerTask = bytesToEvictPerTask;
}
public List<LocalRegion> getRegionList() {
synchronized (this.regionSet) {
return this.regionSet;
}
}
private InternalCache getInternalCache() {
return getHeapEvictor().getGemFireCache();
}
private HeapEvictor getHeapEvictor() {
return this.evictor;
}
@Override
public void run() {
getInternalCache().getCachePerfStats().incEvictorJobsStarted();
long bytesEvicted = 0;
long totalBytesEvicted = 0;
try {
while (true) {
getInternalCache().getCachePerfStats();
final long start = CachePerfStats.getStatTime();
synchronized (this.regionSet) {
if (this.regionSet.isEmpty()) {
lastTaskCompletionTime = System.currentTimeMillis();
return;
}
// TODO: Yogesh : try Fisher-Yates shuffle algorithm
Iterator<LocalRegion> iter = regionSet.iterator();
while (iter.hasNext()) {
LocalRegion region = iter.next();
try {
bytesEvicted = ((AbstractLRURegionMap) region.entries).centralizedLruUpdateCallback();
if (bytesEvicted == 0) {
iter.remove();
}
totalBytesEvicted += bytesEvicted;
if (totalBytesEvicted >= bytesToEvictPerTask || !getHeapEvictor().mustEvict()
|| this.regionSet.size() == 0) {
lastTaskCompletionTime = System.currentTimeMillis();
return;
}
} catch (RegionDestroyedException rd) {
region.cache.getCancelCriterion().checkCancelInProgress(rd);
} catch (Exception e) {
region.cache.getCancelCriterion().checkCancelInProgress(e);
logger.warn(LocalizedMessage.create(LocalizedStrings.Eviction_EVICTOR_TASK_EXCEPTION,
new Object[] {e.getMessage()}), e);
} finally {
getInternalCache().getCachePerfStats();
long end = CachePerfStats.getStatTime();
getInternalCache().getCachePerfStats().incEvictWorkTime(end - start);
}
}
}
}
} finally {
getInternalCache().getCachePerfStats().incEvictorJobsCompleted();
}
}
public static int getEvictionBurstPauseTimeMillis() {
if (TEST_EVICTION_BURST_PAUSE_TIME_MILLIS != Integer.MAX_VALUE) {
return TEST_EVICTION_BURST_PAUSE_TIME_MILLIS;
}
return EVICTION_BURST_PAUSE_TIME_MILLIS;
}
}