com.bagri.server.hazelcast.impl.ModelManagementImpl Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of bagri-server-hazelcast Show documentation
Show all versions of bagri-server-hazelcast Show documentation
Bagri DB Cache: Hazelcast implementation
The newest version!
package com.bagri.server.hazelcast.impl;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import com.bagri.client.hazelcast.impl.IdGeneratorImpl;
import com.bagri.core.model.Path;
import com.bagri.core.server.api.ModelManagement;
import com.bagri.core.server.api.impl.ModelManagementBase;
import com.bagri.support.idgen.IdGenerator;
import com.hazelcast.core.EntryEvent;
import com.hazelcast.core.IAtomicLong;
import com.hazelcast.core.IMap;
import com.hazelcast.core.MapEvent;
import com.hazelcast.map.listener.EntryAddedListener;
import com.hazelcast.map.listener.EntryRemovedListener;
import com.hazelcast.map.listener.EntryUpdatedListener;
import com.hazelcast.map.listener.MapClearedListener;
import com.hazelcast.map.listener.MapEvictedListener;
import com.hazelcast.query.Predicate;
import com.hazelcast.query.Predicates;
import com.hazelcast.query.impl.predicates.RegexPredicate;
public class ModelManagementImpl extends ModelManagementBase implements ModelManagement {
protected IMap pathCache;
private IdGenerator pathGen;
private ConcurrentMap cachePath = new ConcurrentHashMap<>();
private ConcurrentMap> cacheType = new ConcurrentHashMap<>();
public ModelManagementImpl() {
super();
}
protected Map getPathCache() {
return pathCache;
}
protected IdGenerator getPathGen() {
return pathGen;
}
public void setPathCache(IMap pathCache) {
this.pathCache = pathCache;
this.pathCache.addEntryListener(new PathCacheListener(), true);
}
public void setPathGen(IAtomicLong pathGen) {
this.pathGen = new IdGeneratorImpl(pathGen);
}
private Path getPathInternal(int pathId) {
Predicate f = Predicates.equal("pathId", pathId);
Collection entries = pathCache.values(f);
if (entries.isEmpty()) {
return null;
}
// check size > 1 ??
return entries.iterator().next();
}
@Override
public Path getPath(int pathId) {
Path result = cachePath.get(pathId);
if (result == null) {
result = getPathInternal(pathId);
if (result != null) {
cachePath.putIfAbsent(pathId, result);
}
}
return result;
}
private Set getTypePathsInternal(String root) {
Predicate f = Predicates.equal("root", root);
Collection entries = pathCache.values(f);
if (entries.isEmpty()) {
return Collections.emptySet();
}
// check size > 1 ??
Set result = new HashSet<>(entries);
//Collections.sort(result);
//if (logger.isTraceEnabled()) {
// logger.trace("getTypePath; returning {} for type {}", result, typeId);
//}
return result;
}
@Override
public Collection getTypePaths(String root) {
Collection result = cacheType.get(root);
if (result == null) {
result = getTypePathsInternal(root);
cacheType.putIfAbsent(root, (Set) result);
}
// to prevent concurrent access to results..
return new ArrayList<>(result);
}
@Override
protected Set> getTypedPathEntries(String root) {
Predicate f = Predicates.equal("root", root);
Set> entries = pathCache.entrySet(f);
return entries;
}
@Override
protected Set> getTypedPathWithRegex(String regex, String root) {
regex = regex.replaceAll("\\{", Matcher.quoteReplacement("\\{"));
regex = regex.replaceAll("\\}", Matcher.quoteReplacement("\\}"));
Predicate filter = new RegexPredicate("path", regex);
if (root != null) {
filter = Predicates.and(filter, Predicates.equal("root", root));
}
Set> entries = pathCache.entrySet(filter);
return entries;
}
//@Override
@SuppressWarnings({ "unchecked", "rawtypes" })
protected boolean lock(Map cache, K key) {
try {
return ((IMap) cache).tryLock(key, timeout, TimeUnit.MILLISECONDS);
} catch (InterruptedException ex) {
logger.error("Interrupted on lock", ex);
return false;
}
}
//@Override
@SuppressWarnings({ "unchecked", "rawtypes" })
protected void unlock(Map cache, K key) {
((IMap) cache).unlock(key);
}
@Override
protected V putIfAbsent(Map map, K key, V value) {
IMap cache = (IMap) map;
V val2 = cache.putIfAbsent(key, value);
//V val2 = cache.put(key, value);
if (val2 == null) {
return value;
}
logger.debug("putIfAbsent; got collision on cache: {}, key: {}; returning: {}", cache.getName(), key, val2);
return val2;
}
@Override
public void updatePath(Path path) {
String pathKey = getPathKey(path.getRoot(), path.getPath());
((IMap) getPathCache()).set(pathKey, path);
}
private class PathCacheListener implements MapClearedListener, MapEvictedListener,
EntryAddedListener, EntryRemovedListener, EntryUpdatedListener {
@Override
public void mapEvicted(MapEvent event) {
// don't think we have to clear everything in this case
}
@Override
public void mapCleared(MapEvent event) {
cachePath.clear();
cacheType.clear();
}
@Override
public void entryUpdated(EntryEvent event) {
Path path = event.getValue();
cachePath.put(path.getPathId(), path);
Set paths = cacheType.get(path.getRoot());
if (paths == null) {
paths = new HashSet<>();
Set paths2 = cacheType.putIfAbsent(path.getRoot(), paths);
if (paths2 != null) {
paths = paths2;
}
}
paths.add(path);
}
@Override
public void entryRemoved(EntryEvent event) {
Path path = event.getValue();
cachePath.remove(path.getPathId());
Set paths = cacheType.get(path.getRoot());
if (paths != null) {
paths.remove(path);
}
}
@Override
public void entryAdded(EntryEvent event) {
Path path = event.getValue();
cachePath.putIfAbsent(path.getPathId(), path);
Set paths = cacheType.get(path.getRoot());
if (paths == null) {
paths = new HashSet<>();
Set paths2 = cacheType.putIfAbsent(path.getRoot(), paths);
if (paths2 != null) {
paths = paths2;
}
}
paths.add(path);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy