All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.bagri.server.hazelcast.impl.ModelManagementImpl Maven / Gradle / Ivy

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