/* * Copyright (c) 2008-2012, Hazel Bilisim Ltd. All Rights Reserved. * * Licensed 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 com.hazelcast.config; import com.hazelcast.core.Prefix; import com.hazelcast.merge.AddNewEntryMergePolicy; import com.hazelcast.nio.DataSerializable; import com.hazelcast.util.ByteUtil; import java.io.DataInput; import java.io.DataOutput; import java.io.IOException; import java.util.ArrayList; import java.util.List; public class MapConfig implements DataSerializable { public final static int MIN_BACKUP_COUNT = 0; public final static int DEFAULT_BACKUP_COUNT = 1; public final static int MIN_EVICTION_PERCENTAGE = 0; public final static int DEFAULT_EVICTION_PERCENTAGE = 25; public final static int MAX_EVICTION_PERCENTAGE = 100; public final static int DEFAULT_EVICTION_DELAY_SECONDS = 3; public final static int DEFAULT_TTL_SECONDS = 0; public final static int DEFAULT_MAX_IDLE_SECONDS = 0; public final static int DEFAULT_MAX_SIZE = Integer.MAX_VALUE; public final static String ATOMIC_LONG_MAP_NAME = Prefix.MAP_HAZELCAST + "AtomicLongMap"; public final static String COUNT_DOWN_LATCH_MAP_NAME = Prefix.MAP_HAZELCAST + "CountDownLatcheMap"; public final static String SEMAPHORE_MAP_NAME = Prefix.MAP_HAZELCAST + "SemaphoreMap"; public final static String DEFAULT_EVICTION_POLICY = "NONE"; public final static String DEFAULT_MERGE_POLICY = AddNewEntryMergePolicy.NAME; public final static boolean DEFAULT_CACHE_VALUE = true; private String name = null; private int backupCount = DEFAULT_BACKUP_COUNT; private int evictionPercentage = DEFAULT_EVICTION_PERCENTAGE; private int timeToLiveSeconds = DEFAULT_TTL_SECONDS; private int maxIdleSeconds = DEFAULT_TTL_SECONDS; private int evictionDelaySeconds = DEFAULT_EVICTION_DELAY_SECONDS; private MaxSizeConfig maxSizeConfig = new MaxSizeConfig(); private String evictionPolicy = DEFAULT_EVICTION_POLICY; private boolean valueIndexed = false; private MapStoreConfig mapStoreConfig = null; private NearCacheConfig nearCacheConfig = null; private boolean readBackupData = false; private boolean cacheValue = DEFAULT_CACHE_VALUE; private String mergePolicy = DEFAULT_MERGE_POLICY; private WanReplicationRef wanReplicationRef; private List<EntryListenerConfig> listenerConfigs; private List<MapIndexConfig> mapIndexConfigs; private StorageType storageType = null; public enum StorageType { HEAP, OFFHEAP } public MapConfig(String name) { this.name = name; } public MapConfig() { } public MapConfig(MapConfig config) { this.name = config.name; this.backupCount = config.backupCount; this.evictionPercentage = config.evictionPercentage; this.timeToLiveSeconds = config.timeToLiveSeconds; this.maxIdleSeconds = config.maxIdleSeconds; this.evictionDelaySeconds = config.evictionDelaySeconds; this.maxSizeConfig = config.maxSizeConfig; this.evictionPolicy = config.evictionPolicy; this.valueIndexed = config.valueIndexed; this.mapStoreConfig = config.mapStoreConfig; this.nearCacheConfig = config.nearCacheConfig; this.readBackupData = config.readBackupData; this.cacheValue = config.cacheValue; this.mergePolicy = config.mergePolicy; } /** * @return the name */ public String getName() { return name; } /** * @param name the name to set */ public MapConfig setName(String name) { this.name = name; return this; } /** * Returns if the value of the mapEntry should be indexed for * faster containsValue(obj) operations. * <p/> * Default is false. * * @return true if value is indexed, false otherwise */ public boolean isValueIndexed() { return valueIndexed; } /** * Sets if the value of the map entries should be indexed for * faster containsValue(obj) operations. * <p/> * Default is false. * * @param valueIndexed */ public void setValueIndexed(boolean valueIndexed) { this.valueIndexed = valueIndexed; } /** * Returns if the entry values are cached * * @return true if cached, false otherwise */ public boolean isCacheValue() { return cacheValue; } /** * Sets if entry values should be cached * * @param cacheValue * @return this MapConfig */ public MapConfig setCacheValue(boolean cacheValue) { this.cacheValue = cacheValue; return this; } /** * @return the backupCount */ public int getBackupCount() { return backupCount; } /** * Number of backups. If 1 is set as the backup-count for example, * then all entries of the map will be copied to another JVM for * fail-safety. 0 means no backup. * * @param backupCount the backupCount to set */ public MapConfig setBackupCount(final int backupCount) { if (backupCount < MIN_BACKUP_COUNT) { throw new IllegalArgumentException("map backup count must be equal to or bigger than " + MIN_BACKUP_COUNT); } this.backupCount = backupCount; return this; } /** * @return the evictionPercentage */ public int getEvictionPercentage() { return evictionPercentage; } /** * When max. size is reached, specified percentage of the map will be evicted. * Any integer between 0 and 100 is allowed. * If 25 is set for example, 25% of the entries will get evicted. * * @param evictionPercentage the evictionPercentage to set * @throws IllegalArgumentException if evictionPercentage is not in the 0-100 range. */ public MapConfig setEvictionPercentage(final int evictionPercentage) { if (evictionPercentage < MIN_EVICTION_PERCENTAGE) { throw new IllegalArgumentException("eviction percentage must be greater or equal than 0"); } if (evictionPercentage > MAX_EVICTION_PERCENTAGE) { throw new IllegalArgumentException("eviction percentage must be smaller or equal than 100"); } this.evictionPercentage = evictionPercentage; return this; } /** * @return the evictionDelaySeconds * @deprecated */ public int getEvictionDelaySeconds() { return evictionDelaySeconds; } /** * @param evictionDelaySeconds the evictionPercentage to set * @deprecated */ public MapConfig setEvictionDelaySeconds(int evictionDelaySeconds) { this.evictionDelaySeconds = evictionDelaySeconds; return this; } /** * @return the timeToLiveSeconds */ public int getTimeToLiveSeconds() { return timeToLiveSeconds; } /** * Maximum number of seconds for each entry to stay in the map. Entries that are * older than timeToLiveSeconds will get automatically evicted from the map. * Updates on the entry don't change the eviction time. * Any integer between 0 and Integer.MAX_VALUE. * 0 means infinite. Default is 0. * * @param timeToLiveSeconds the timeToLiveSeconds to set */ public MapConfig setTimeToLiveSeconds(int timeToLiveSeconds) { this.timeToLiveSeconds = timeToLiveSeconds; return this; } /** * @return the maxIdleSeconds */ public int getMaxIdleSeconds() { return maxIdleSeconds; } /** * Maximum number of seconds for each entry to stay idle in the map. Entries that are * idle(not touched) for more than maxIdleSeconds will get * automatically evicted from the map. Entry is touched if get, put or * containsKey is called. * Any integer between 0 and Integer.MAX_VALUE. * 0 means infinite. Default is 0. * * @param maxIdleSeconds the maxIdleSeconds to set */ public MapConfig setMaxIdleSeconds(int maxIdleSeconds) { this.maxIdleSeconds = maxIdleSeconds; return this; } /** * @return the maxSize * @deprecated use MaxSizeConfig.getSize */ public int getMaxSize() { return maxSizeConfig.getSize(); } /** * @param maxSize the maxSize to set * @deprecated use MaxSizeConfig.setSize */ public MapConfig setMaxSize(final int maxSize) { if (maxSize < 0) { throw new IllegalArgumentException("map max size must be greater than 0"); } this.maxSizeConfig.setSize(maxSize); return this; } public MaxSizeConfig getMaxSizeConfig() { return maxSizeConfig; } public void setMaxSizeConfig(MaxSizeConfig maxSizeConfig) { this.maxSizeConfig = maxSizeConfig; } /** * @return the evictionPolicy */ public String getEvictionPolicy() { return evictionPolicy; } /** * @param evictionPolicy the evictionPolicy to set */ public MapConfig setEvictionPolicy(String evictionPolicy) { this.evictionPolicy = evictionPolicy; return this; } /** * Returns the map store configuration * * @return the mapStoreConfig */ public MapStoreConfig getMapStoreConfig() { return mapStoreConfig; } /** * Sets the mapStore configuration * * @param mapStoreConfig the mapStoreConfig to set */ public MapConfig setMapStoreConfig(MapStoreConfig mapStoreConfig) { this.mapStoreConfig = mapStoreConfig; return this; } public NearCacheConfig getNearCacheConfig() { return nearCacheConfig; } public MapConfig setNearCacheConfig(NearCacheConfig nearCacheConfig) { this.nearCacheConfig = nearCacheConfig; return this; } public String getMergePolicy() { return mergePolicy; } public MapConfig setMergePolicy(String mergePolicyName) { this.mergePolicy = mergePolicyName; return this; } public boolean isReadBackupData() { return readBackupData; } public MapConfig setReadBackupData(boolean readBackupData) { this.readBackupData = readBackupData; return this; } public WanReplicationRef getWanReplicationRef() { return wanReplicationRef; } public MapConfig setWanReplicationRef(WanReplicationRef wanReplicationRef) { this.wanReplicationRef = wanReplicationRef; return this; } public StorageType getStorageType() { return storageType; } public MapConfig setStorageType(StorageType storageType) { this.storageType = storageType; return this; } public MapConfig addEntryListenerConfig(EntryListenerConfig listenerConfig) { getEntryListenerConfigs().add(listenerConfig); return this; } public List<EntryListenerConfig> getEntryListenerConfigs() { if (listenerConfigs == null) { listenerConfigs = new ArrayList<EntryListenerConfig>(); } return listenerConfigs; } public void setEntryListenerConfigs(List<EntryListenerConfig> listenerConfigs) { this.listenerConfigs = listenerConfigs; } public MapConfig addMapIndexConfig(MapIndexConfig mapIndexConfig) { getMapIndexConfigs().add(mapIndexConfig); return this; } public List<MapIndexConfig> getMapIndexConfigs() { if (mapIndexConfigs == null) { mapIndexConfigs = new ArrayList<MapIndexConfig>(); } return mapIndexConfigs; } public void setMapIndexConfigs(List<MapIndexConfig> mapIndexConfigs) { this.mapIndexConfigs = mapIndexConfigs; } public boolean isCompatible(MapConfig other) { if (this == other) return true; return other != null && (this.name != null ? this.name.equals(other.name) : other.name == null) && this.backupCount == other.backupCount && this.evictionDelaySeconds == other.evictionDelaySeconds && this.evictionPercentage == other.evictionPercentage && this.maxIdleSeconds == other.maxIdleSeconds && (this.maxSizeConfig.getSize() == other.maxSizeConfig.getSize() || (Math.min(maxSizeConfig.getSize(), other.maxSizeConfig.getSize()) == 0 && Math.max(maxSizeConfig.getSize(), other.maxSizeConfig.getSize()) == Integer.MAX_VALUE)) && this.timeToLiveSeconds == other.timeToLiveSeconds && this.readBackupData == other.readBackupData && this.valueIndexed == other.valueIndexed; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + this.backupCount; result = prime * result + this.evictionDelaySeconds; result = prime * result + this.evictionPercentage; result = prime * result + ((this.evictionPolicy == null) ? 0 : this.evictionPolicy .hashCode()); result = prime * result + ((this.mapStoreConfig == null) ? 0 : this.mapStoreConfig .hashCode()); result = prime * result + this.maxIdleSeconds; result = prime * result + this.maxSizeConfig.getSize(); result = prime * result + ((this.mergePolicy == null) ? 0 : this.mergePolicy.hashCode()); result = prime * result + ((this.name == null) ? 0 : this.name.hashCode()); result = prime * result + ((this.nearCacheConfig == null) ? 0 : this.nearCacheConfig .hashCode()); result = prime * result + this.timeToLiveSeconds; result = prime * result + (this.readBackupData ? 1231 : 1237); result = prime * result + (this.valueIndexed ? 1231 : 1237); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (!(obj instanceof MapConfig)) return false; MapConfig other = (MapConfig) obj; return (this.name != null ? this.name.equals(other.name) : other.name == null) && this.backupCount == other.backupCount && this.evictionDelaySeconds == other.evictionDelaySeconds && this.evictionPercentage == other.evictionPercentage && this.maxIdleSeconds == other.maxIdleSeconds && this.maxSizeConfig.getSize() == other.maxSizeConfig.getSize() && this.timeToLiveSeconds == other.timeToLiveSeconds && this.readBackupData == other.readBackupData && this.valueIndexed == other.valueIndexed && (this.mergePolicy != null ? this.mergePolicy.equals(other.mergePolicy) : other.mergePolicy == null) && (this.evictionPolicy != null ? this.evictionPolicy.equals(other.evictionPolicy) : other.evictionPolicy == null) && (this.mapStoreConfig != null ? this.mapStoreConfig.equals(other.mapStoreConfig) : other.mapStoreConfig == null) && (this.nearCacheConfig != null ? this.nearCacheConfig.equals(other.nearCacheConfig) : other.nearCacheConfig == null); } @Override public String toString() { return "MapConfig{" + "name='" + name + '\'' + ", backupCount=" + backupCount + ", mergePolicy=" + mergePolicy + ", evictionPercentage=" + evictionPercentage + ", timeToLiveSeconds=" + timeToLiveSeconds + ", maxIdleSeconds=" + maxIdleSeconds + ", evictionDelaySeconds=" + evictionDelaySeconds + ", maxSizeConfig=" + maxSizeConfig + ", evictionPolicy='" + evictionPolicy + '\'' + ", mapStoreConfig=" + mapStoreConfig + ", nearCacheConfig=" + nearCacheConfig + ", readBackupData=" + readBackupData + ", wanReplicationRef=" + wanReplicationRef + '}'; } public void readData(DataInput in) throws IOException { name = in.readUTF(); backupCount = in.readInt(); evictionPercentage = in.readInt(); timeToLiveSeconds = in.readInt(); maxIdleSeconds = in.readInt(); evictionDelaySeconds = in.readInt(); maxSizeConfig.readData(in); boolean[] b = ByteUtil.fromByte(in.readByte()); valueIndexed = b[0]; readBackupData = b[1]; cacheValue = b[2]; evictionPolicy = in.readUTF(); mergePolicy = in.readUTF(); // TODO: MapStoreConfig mapStoreConfig // TODO: NearCacheConfig nearCacheConfig } public void writeData(DataOutput out) throws IOException { out.writeUTF(name); out.writeInt(backupCount); out.writeInt(evictionPercentage); out.writeInt(timeToLiveSeconds); out.writeInt(maxIdleSeconds); out.writeInt(evictionDelaySeconds); maxSizeConfig.writeData(out); out.writeByte(ByteUtil.toByte(valueIndexed, readBackupData, cacheValue)); out.writeUTF(evictionPolicy); out.writeUTF(mergePolicy); // TODO: MapStoreConfig mapStoreConfig // TODO: NearCacheConfig nearCacheConfig } }