Java tutorial
/******************************************************************************* * Copyright (c) 2014 EURA NOVA. * All rights reserved. This program and the accompanying materials * are made available under the terms of the GNU Public License v2.0 * which accompanies this distribution, and is available at * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html * * Contributors: * Aldemar Reynaga - initial API and implementation * Salim Jouili - initial API and implementation ******************************************************************************/ package com.steffi.index; import java.util.concurrent.ConcurrentHashMap; import org.apache.commons.collections.IteratorUtils; import org.infinispan.Cache; import org.infinispan.lifecycle.ComponentStatus; import com.steffi.model.Cell; import com.steffi.model.SteffiEdge; import com.steffi.model.SteffiVertex; import com.steffi.storage.CacheContainer; import com.steffi.storage.CellTransactionThread; import com.steffi.storage.IndexOperation; import com.steffi.storage.IndexOperation.IndexOperationItem; /** * @author Aldemar Reynaga * Implementation of the ImgIndex using an Infinispan Cache as a storage, the entries of the index are * stored as key/values where the key is an IndexKeyValue instance and the value is a set of Cell ids * or EdgeIndexEntry instances * @param <T> The class of the Imgraph cells to be indexed */ public class ImgMapIndex<T extends Cell> implements ImgIndex<T> { /** * */ //private static final long serialVersionUID = -7157672464559662812L; private final String name; private final Class<T> indexClass; private Cache<IndexKeyValue, ConcurrentHashMap<Object, Boolean>> map; public ImgMapIndex(String name, Class<T> indexClass, boolean createCache) { this.name = name; this.indexClass = indexClass; if (createCache) this.map = CacheContainer.createIndexCache(name, indexClass); } private Cache<IndexKeyValue, ConcurrentHashMap<Object, Boolean>> getMap() { if (map == null) { map = CacheContainer.getCache(name); if (!map.getStatus().equals(ComponentStatus.RUNNING)) map.start(); } return map; } @Override public String getName() { return name; } @Override public Class<T> getEntityType() { return indexClass; } @Override public ImgIndexHits<T> get(String key, Object value) { IndexKeyValue indexKeyValue = new IndexKeyValue(key, value); ConcurrentHashMap<Object, Boolean> idElements = getMap().get(indexKeyValue); if (idElements == null || idElements.isEmpty()) return new ImgMapIndexHits<T>(IteratorUtils.emptyIterator(), 0, indexClass); else return new ImgMapIndexHits<T>(idElements.keySet().iterator(), idElements.size(), indexClass); } public void commitChanges(IndexOperation<T> operations) { if (operations.getNewKeyValues() != null) { for (IndexOperationItem opItem : operations.getNewKeyValues()) { IndexKeyValue indexKeyValue = new IndexKeyValue(opItem.getKey(), opItem.getValue()); ConcurrentHashMap<Object, Boolean> curElements = getMap().get(indexKeyValue); if (curElements == null) curElements = new ConcurrentHashMap<Object, Boolean>(); if (!opItem.getObject().getClass().equals(this.indexClass) && !opItem.getObject().getClass().getSuperclass().equals(this.indexClass)) throw new RuntimeException("Index was created for " + indexClass.getSimpleName()); Cell cellElement = indexClass.cast(opItem.getObject()); if (cellElement instanceof SteffiEdge) { SteffiEdge edge = (SteffiEdge) cellElement; curElements.put(new EdgeIndexEntry(edge.getSourceCellId(), edge.getId()), true); } else { curElements.put(cellElement.getId(), true); } getMap().put(indexKeyValue, curElements); } } if (operations.getRemovedKeyValues() != null) { for (IndexOperationItem opItem : operations.getRemovedKeyValues()) { ConcurrentHashMap<Object, Boolean> curValues = getMap() .get(new IndexKeyValue(opItem.getKey(), opItem.getValue())); if (curValues != null) { Cell cellElement = indexClass.cast(opItem.getObject()); if (cellElement instanceof SteffiVertex) { curValues.remove(cellElement.getId()); } else { SteffiEdge edge = (SteffiEdge) cellElement; curValues.remove(new EdgeIndexEntry(edge.getSourceCellId(), edge.getId())); } } } } } @Override public void put(String key, Object value, T element) { CellTransactionThread.get().putKeyValueIndex(name, key, value, element); } @Override public void remove(T element, String key, Object value) { CellTransactionThread.get().removeKeyValueIndex(name, key, value, element); } @Override public long count(String key, Object value) { ConcurrentHashMap<Object, Boolean> curValues = getMap().get(new IndexKeyValue(key, value)); if (curValues != null) return curValues.size(); return 0; } @Override public boolean hasElementForKeyValue(T element, String key, Object value) { ConcurrentHashMap<Object, Boolean> curValues = getMap().get(new IndexKeyValue(key, value)); if (curValues != null) { Cell cellElement = indexClass.cast(element); if (cellElement instanceof SteffiVertex) { return curValues.contains(cellElement.getId()); } else { SteffiEdge edge = (SteffiEdge) cellElement; return curValues.contains(new EdgeIndexEntry(edge.getSourceCellId(), edge.getId())); } } return false; } }