Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.hazelcast.internal.nearcache.impl.DefaultNearCache Maven / Gradle / Ivy
/*
* Copyright (c) 2008-2020, Hazelcast, Inc. 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.internal.nearcache.impl;
import com.hazelcast.config.InMemoryFormat;
import com.hazelcast.config.NearCacheConfig;
import com.hazelcast.internal.adapter.DataStructureAdapter;
import com.hazelcast.internal.nearcache.NearCache;
import com.hazelcast.internal.nearcache.NearCacheRecordStore;
import com.hazelcast.internal.nearcache.impl.store.NearCacheDataRecordStore;
import com.hazelcast.internal.nearcache.impl.store.NearCacheObjectRecordStore;
import com.hazelcast.internal.serialization.Data;
import com.hazelcast.internal.serialization.SerializationService;
import com.hazelcast.nearcache.NearCacheStats;
import com.hazelcast.spi.impl.executionservice.TaskScheduler;
import com.hazelcast.spi.properties.HazelcastProperties;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import static com.hazelcast.config.NearCacheConfig.DEFAULT_MEMORY_FORMAT;
import static com.hazelcast.internal.util.Preconditions.checkInstanceOf;
import static com.hazelcast.internal.util.Preconditions.checkNotInstanceOf;
public class DefaultNearCache implements NearCache {
protected final String name;
protected final TaskScheduler scheduler;
protected final ClassLoader classLoader;
protected final NearCacheConfig nearCacheConfig;
protected final SerializationService serializationService;
protected ScheduledFuture expirationTaskFuture;
protected NearCacheRecordStore nearCacheRecordStore;
private final boolean serializeKeys;
private final HazelcastProperties properties;
private volatile boolean preloadDone;
public DefaultNearCache(String name, NearCacheConfig nearCacheConfig,
SerializationService serializationService, TaskScheduler scheduler,
ClassLoader classLoader, HazelcastProperties properties) {
this(name, nearCacheConfig, null,
serializationService, scheduler, classLoader, properties);
}
public DefaultNearCache(String name, NearCacheConfig nearCacheConfig,
NearCacheRecordStore nearCacheRecordStore,
SerializationService serializationService, TaskScheduler scheduler,
ClassLoader classLoader, HazelcastProperties properties) {
this.name = name;
this.nearCacheConfig = nearCacheConfig;
this.serializationService = serializationService;
this.classLoader = classLoader;
this.scheduler = scheduler;
this.nearCacheRecordStore = nearCacheRecordStore;
this.serializeKeys = nearCacheConfig.isSerializeKeys();
this.properties = properties;
}
@Override
public void initialize() {
if (nearCacheRecordStore == null) {
nearCacheRecordStore = createNearCacheRecordStore(name, nearCacheConfig);
}
nearCacheRecordStore.initialize();
expirationTaskFuture = createAndScheduleExpirationTask();
}
protected NearCacheRecordStore createNearCacheRecordStore(String name, NearCacheConfig nearCacheConfig) {
InMemoryFormat inMemoryFormat = nearCacheConfig.getInMemoryFormat();
if (inMemoryFormat == null) {
inMemoryFormat = DEFAULT_MEMORY_FORMAT;
}
switch (inMemoryFormat) {
case BINARY:
return new NearCacheDataRecordStore(name, nearCacheConfig, serializationService, classLoader);
case OBJECT:
return new NearCacheObjectRecordStore(name, nearCacheConfig, serializationService, classLoader);
default:
throw new IllegalArgumentException("Invalid in memory format: " + inMemoryFormat);
}
}
private ScheduledFuture createAndScheduleExpirationTask() {
if (nearCacheConfig.getMaxIdleSeconds() > 0L
|| nearCacheConfig.getTimeToLiveSeconds() > 0L) {
return new ExpirationTask().schedule(scheduler);
}
return null;
}
@Override
public String getName() {
return name;
}
@Override
public NearCacheConfig getNearCacheConfig() {
return nearCacheConfig;
}
@Override
public V get(K key) {
checkKeyFormat(key);
return nearCacheRecordStore.get(key);
}
// only implemented for testing purposes
@Override
public void put(K key, Data keyData, V value, Data valueData) {
checkKeyFormat(key);
nearCacheRecordStore.doEviction(false);
nearCacheRecordStore.put(key, keyData, value, valueData);
}
@Override
public void invalidate(K key) {
checkKeyFormat(key);
nearCacheRecordStore.invalidate(key);
}
@Override
public void clear() {
nearCacheRecordStore.clear();
}
@Override
public void destroy() {
if (expirationTaskFuture != null) {
expirationTaskFuture.cancel(true);
}
nearCacheRecordStore.destroy();
}
@Override
public NearCacheStats getNearCacheStats() {
return nearCacheRecordStore.getNearCacheStats();
}
@Override
public boolean isSerializeKeys() {
return serializeKeys;
}
@Override
public int size() {
return nearCacheRecordStore.size();
}
@Override
public void preload(DataStructureAdapter adapter) {
nearCacheRecordStore.loadKeys(adapter);
preloadDone = true;
}
@Override
public void storeKeys() {
// we don't store new keys, until the pre-loader is done
if (preloadDone) {
nearCacheRecordStore.storeKeys();
}
}
@Override
public boolean isPreloadDone() {
return preloadDone;
}
@Override
public T unwrap(Class clazz) {
if (clazz.isAssignableFrom(getClass())) {
return clazz.cast(this);
}
throw new IllegalArgumentException("Unwrapping to " + clazz + " is not supported by this implementation");
}
@Override
public long tryReserveForUpdate(K key, Data keyData, UpdateSemantic updateSemantic) {
nearCacheRecordStore.doEviction(false);
return nearCacheRecordStore.tryReserveForUpdate(key, keyData, updateSemantic);
}
@Override
public V tryPublishReserved(K key, V value, long reservationId, boolean deserialize) {
return nearCacheRecordStore.tryPublishReserved(key, value, reservationId, deserialize);
}
public NearCacheRecordStore getNearCacheRecordStore() {
return nearCacheRecordStore;
}
private void checkKeyFormat(K key) {
if (serializeKeys) {
checkInstanceOf(Data.class, key, "key must be of type Data!");
} else {
checkNotInstanceOf(Data.class, key, "key cannot be of type Data!");
}
}
private class ExpirationTask implements Runnable {
private final AtomicBoolean expirationInProgress = new AtomicBoolean(false);
@Override
public void run() {
if (expirationInProgress.compareAndSet(false, true)) {
try {
nearCacheRecordStore.doExpiration();
} finally {
expirationInProgress.set(false);
}
}
}
private ScheduledFuture schedule(TaskScheduler scheduler) {
return scheduler.scheduleWithRepetition(this,
properties.getInteger(TASK_INITIAL_DELAY_SECONDS),
properties.getInteger(TASK_PERIOD_SECONDS),
TimeUnit.SECONDS);
}
}
@Override
public String toString() {
return "DefaultNearCache{"
+ "name='" + name + '\''
+ ", nearCacheConfig=" + nearCacheConfig
+ ", preloadDone=" + preloadDone
+ '}';
}
}