
com.tangosol.util.ForwardOnlyMapIndex Maven / Gradle / Ivy
/*
* Copyright (c) 2000, 2020, Oracle and/or its affiliates.
*
* Licensed under the Universal Permissive License v 1.0 as shown at
* http://oss.oracle.com/licenses/upl.
*/
package com.tangosol.util;
import com.tangosol.net.BackingMapContext;
import com.tangosol.net.CacheFactory;
import com.tangosol.util.filter.IndexAwareFilter;
import java.util.Comparator;
import java.util.Map;
/**
* ForwardOnlyMapIndex is a {@link MapIndex} implementation that unlike the
* {@link SimpleMapIndex} maintains only a forward index and not the inverse index.
* As a result, the content of {@link #getIndexContents()} is always empty, so this
* index cannot be used for querying by {@link IndexAwareFilter#applyIndex
* IndexAwareFilter}, with its primary use as a deserialization optimization.
*
* @author gg/hr/jh 2014.03.07
* @since Coherence 12.1.3
*/
public class ForwardOnlyMapIndex
implements MapIndex
{
// ----- constructors ---------------------------------------------------
/**
* Construct an index for the given map.
*
* @param extractor the ValueExtractor that is used to extract an indexed
* value from a resource map entry
* @param ctx the {@link BackingMapContext context} associated with
* the indexed cache
* @param fOnDemand if true, the forward index will be created "on-demand"
* as the values are attempted to be accessed; otherwise
* the forward index is populated proactively
*/
public ForwardOnlyMapIndex(ValueExtractor extractor, BackingMapContext ctx, boolean fOnDemand)
{
Base.azzert(extractor != null);
f_extractor = extractor;
f_ctx = ctx;
f_fLazy = fOnDemand;
f_mapForward = instantiateForwardIndex();
}
// ----- MapIndex interface ---------------------------------------------
/**
* {@inheritDoc}
*/
public ValueExtractor getValueExtractor()
{
return f_extractor;
}
/**
* {@inheritDoc}
*/
public boolean isOrdered()
{
// this question makes no sense for this index
return false;
}
/**
* {@inheritDoc}
*/
public boolean isPartial()
{
return false;
}
/**
* {@inheritDoc}
*/
public Comparator getComparator()
{
return null;
}
/**
* {@inheritDoc}
*/
public Map getIndexContents()
{
return NullImplementation.getMap();
}
/**
* {@inheritDoc}
*/
public Object get(Object oKey)
{
Object oValue = f_mapForward.get(oKey);
if (oValue == null && !f_mapForward.containsKey(oKey))
{
if (f_fLazy)
{
Map mapBacking = f_ctx.getBackingMap();
if (mapBacking.containsKey(oKey))
{
oValue = mapBacking.get(oKey);
}
if (oValue != null)
{
oValue = f_ctx.getManagerContext().
getValueFromInternalConverter().convert(oValue);
f_mapForward.put(oKey, oValue);
return oValue;
}
}
return NO_VALUE;
}
else
{
return oValue;
}
}
/**
* {@inheritDoc}
*/
public void insert(Map.Entry entry)
{
updateInternal(entry);
}
/**
* {@inheritDoc}
*/
public void update(Map.Entry entry)
{
updateInternal(entry);
}
/**
* {@inheritDoc}
*/
public void delete(Map.Entry entry)
{
deleteInternal(entry);
}
// ----- helpers --------------------------------------------------------
/**
* Instantiate the forward index.
*
* @return the forward index
*/
protected Map instantiateForwardIndex()
{
return new SegmentedHashMap();
}
/**
* Update this index in response to an update operation on a cache.
*
* @param entry the entry representing the object being updated
*/
protected void updateInternal(Map.Entry entry)
{
Object oKey = entry instanceof BinaryEntry ?
((BinaryEntry) entry).getBinaryKey() : entry.getKey();
if (!f_fLazy || f_mapForward.containsKey(oKey))
{
try
{
f_mapForward.put(oKey, InvocableMapHelper.extractFromEntry(f_extractor, entry));
}
catch (RuntimeException e)
{
CacheFactory.log("An Exception occurred during index update for key " + entry.getKey()
+ ". The entry will be excluded from the index"
+ (f_ctx == null ? "" : " for cache " + f_ctx.getCacheName()) + ".\n",
CacheFactory.LOG_WARN);
CacheFactory.log(e + ":\n" + Base.getStackTrace(e), CacheFactory.LOG_WARN);
f_mapForward.remove(oKey);
}
}
}
/**
* Update this index in response to a remove operation on a cache.
*
* @param entry the entry representing the object being removed
*/
protected void deleteInternal(Map.Entry entry)
{
Object oKey = entry instanceof BinaryEntry ?
((BinaryEntry) entry).getBinaryKey() : entry.getKey();
f_mapForward.remove(oKey);
}
// ----- Object interface -----------------------------------------------
/**
* Returns a string representation of this SimpleMapIndex.
*
* @return a String representation of this SimpleMapIndex
*/
public String toString()
{
return ClassHelper.getSimpleName(getClass())
+ ": Extractor=" + getValueExtractor();
}
/**
* Compares the specified object with this index for equality. Returns
* true if the given object is also a SimpleMapIndex and the two
* represent the same index.
*
* @param o object to be compared for equality with this MapIndex
*
* @return true if the specified object is equal to this index
*/
public boolean equals(Object o)
{
if (this == o)
{
return true;
}
if (o == null || o.getClass() != this.getClass())
{
return false;
}
ForwardOnlyMapIndex that = (ForwardOnlyMapIndex) o;
return Base.equals(this.getValueExtractor(), that.getValueExtractor());
}
/**
* Returns the hash code value for this MapIndex.
*
* @return the hash code value for this MapIndex
*/
public int hashCode()
{
return f_extractor.hashCode();
}
// ----- data members ---------------------------------------------------
/**
* ValueExtractor object that this MapIndex uses to extract an indexable
* property value from a [converted] value stored in the resource map.
*/
protected final ValueExtractor f_extractor;
/**
* Map that contains the index values (forward index). The keys of the Map
* are the keys to the map being indexed and the values are the extracted
* values. This map is used by the IndexAwareComparators to avoid a
* conversion and value extraction steps.
*/
protected final Map f_mapForward;
/**
* The {@link BackingMapContext context} associated with this index.
*/
protected final BackingMapContext f_ctx;
/**
* The "lazy" flag.
*/
protected boolean f_fLazy;
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy