blob: 5574100c8de2c9f0f468d7a675c4ba619a211fb8 [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.eviction;
import org.apache.geode.cache.EvictionAction;
import org.apache.geode.cache.EvictionAlgorithm;
import org.apache.geode.cache.util.ObjectSizer;
import org.apache.geode.internal.cache.InternalRegion;
import org.apache.geode.internal.cache.Token;
import org.apache.geode.internal.cache.persistence.DiskRegionView;
/**
* An {@code EvictionController} that will evict one more entries from a region once the region
* reaches a certain byte {@linkplain #setMaximumMegabytes capacity}. Capacity is determined by
* monitoring the size of entries. Capacity is specified in terms of megabytes. GemFire uses an
* efficient algorithm to determine the amount of space a region entry occupies in the JVM. However,
* this algorithm may not yield optimal results for all kinds of data. The user may provide their
* own algorithm for determining the size of objects by implementing an {@link ObjectSizer}.
*
* @since GemFire 2.0.2
*/
public class MemoryLRUController extends SizeLRUController {
private long limit;
private final boolean isOffHeap;
private static final long ONE_MEG = 1024L * 1024L;
/**
* Create an instance of the capacity controller the given settings.
*
*
* @param megabytes the amount of memory allowed in this region specified in megabytes.<br>
* <p>
* For a region with {@link org.apache.geode.cache.DataPolicy#PARTITION}, it is overridden
* by {@link org.apache.geode.cache.PartitionAttributesFactory#setLocalMaxMemory(int) "
* local max memory "} specified for the
* {@link org.apache.geode.cache.PartitionAttributes}. It signifies the amount of memory
* allowed in the region, collectively for its primary buckets and redundant copies for
* this VM. It can be different for the same region in different VMs.
* @param sizer classname of a class that implements ObjectSizer, used to compute object sizes for
* MemLRU
* @param isOffHeap true if the region that owns this cc is stored off heap
*/
public MemoryLRUController(EvictionCounters evictionCounters, int megabytes, ObjectSizer sizer,
EvictionAction evictionAction, boolean isOffHeap, EvictionAlgorithm algorithm) {
super(evictionCounters, evictionAction, sizer, algorithm);
this.isOffHeap = isOffHeap;
setMaximumMegabytes(megabytes);
}
/**
* Reset the maximum allowed limit on memory to use for this region. This change takes effect on
* next region operation that could increase the region's byte size. If the region is shared, this
* change is seen by all members in the cluster.
*/
private void setMaximumMegabytes(int megabytes) {
if (megabytes <= 0) {
throw new IllegalArgumentException(
String.format("MemLRUController limit must be postive: %s",
megabytes));
}
this.limit = megabytes * ONE_MEG;
getCounters().setLimit(this.limit);
}
@Override
public void setLimit(int maximum) {
setMaximumMegabytes(maximum);
}
@Override
public long getLimit() {
return this.limit;
}
/**
* compute the size of storing a key/value pair in the cache..
*/
@Override
public int entrySize(Object key, Object value) {
if (value == Token.TOMBSTONE) {
return 0;
}
int size = 0;
int keySize = 0;
if (!this.isOffHeap) {
size += getPerEntryOverhead();
keySize = sizeof(key);
}
int valueSize = sizeof(value);
size += keySize;
size += valueSize;
return size;
}
@Override
public boolean mustEvict(EvictionCounters counters, InternalRegion region, int delta) {
return counters.getCounter() + delta > counters.getLimit();
}
@Override
public boolean lruLimitExceeded(EvictionCounters counters, DiskRegionView diskRegionView) {
return counters.getCounter() > counters.getLimit();
}
/**
* Returns a brief description of this capacity controller.
*
* @since GemFire 4.0
*/
@Override
public String toString() {
return "MemLRUCapacityController with a capacity of " + this.getLimit()
+ " megabytes and and eviction action " + this.getEvictionAction();
}
}