org.infinispan.functional.MetaParam Maven / Gradle / Ivy
package org.infinispan.functional;
import java.util.Optional;
import org.infinispan.commons.util.Experimental;
import org.infinispan.container.versioning.EntryVersion;
/**
* An easily extensible metadata parameter that's stored along with the value
* in the the functional map.
*
* Some metadata parameters can be provided by the user in which case they
* need to implement {@link MetaParam.Writable}. Examples of writable metadata
* parameters are version information, lifespan of the cached value...etc.
*
*
Those metadata parameters not extending {@link MetaParam.Writable} are
* created by internal logic and hence can only be queried, for example:
* time when value was added into the functional map, or last time value
* was accessed or modified.
*
*
What makes {@link MetaParam} different from {@link Param} is that {@link MetaParam}
* values are designed to be stored along with key/value pairs in the functional map,
* to provide extra information. On the other hand, {@link Param} instances
* merely act as ways to tweak how operations are executed, and their contents
* are never stored permanently.
*
*
This interface replaces Infinispan's Metadata interface providing
* a more flexible way to add new metadata parameters to be stored with
* the cached entries.
*
*
{@link MetaParam} design has been geared towards making a clear
* separation between the metadata that can be provided by the user on
* per-entry basis, e.g. lifespan, maxIdle, version...etc, as opposed to
* metadata that's produced by the internal logic that cannot be modified
* directly by the user, e.g. cache entry created time, last time cache entry
* was modified or accessed ...etc.
*
* @param type of MetaParam instance, implementations should assign it to
* the implementation's type.
* @since 8.0
*/
@Experimental
public interface MetaParam {
/**
* Returns the value of the meta parameter.
*/
T get();
/**
* Provides metadata parameter lookup capabilities using {@link Class} as
* lookup key.
*
* When the {@link MetaParam} type is generic, e.g. {@link MetaEntryVersion},
* passing the correct {@link Class} information so that the return of
* {@link #findMetaParam} is of the expected type can be a bit tricky.
* {@link MetaEntryVersion#type()} offers an easy way to retrieve the
* expected {@link MetaParam} type from {@link #findMetaParam} at the
* expense of some type safety:
*
*
{@code
* Class> type = MetaEntryVersion.type();
* Optional> metaVersion =
* metaParamLookup.findMetaParam(type);
* }
*
* In the future, the API might be adjusted to provide additional lookup
* methods where this situation is improved. Also, if the {@link MetaParam}
* type is not generic, e.g. {@link MetaLifespan}, the problem is avoided
* altogether:
*
* {@code
* Optional> metaLifespan =
* metaParamLookup.findMetaParam(MetaLifespan.class);
* }
*
* A user that queries meta parameters can never assume that the
* meta parameter will always exist because some of them depends on the
* cache usage.
*
* @since 8.0
*/
@Experimental
interface Lookup {
/**
* Returns a non-empty {@link Optional} instance containing a metadata
* parameter instance that can be assigned to the type {@link Class}
* passed in, or an empty {@link Optional} if no metadata can be assigned
* to that type.
*
* @param metadata parameter type
*/
Optional findMetaParam(Class type);
}
/**
* Writable {@link MetaParam} instances are those that the user can provide
* to be stored as part of the cache entry. RESTful HTTTP MIME metadata, version
* information or lifespan are examples.
*
* @param type of MetaParam instance, implementations should assign it to
* the implementation's type.
* @since 8.0
*/
@Experimental
interface Writable extends MetaParam {}
/**
* Writable metadata parameter representing a cached entry's millisecond lifespan.
*
* @since 8.0
*/
@Experimental
final class MetaLifespan extends MetaLong implements Writable {
private static final MetaLifespan DEFAULT = new MetaLifespan(-1);
public MetaLifespan(long lifespan) {
super(lifespan);
}
@Override
public String toString() {
return "MetaLifespan=" + value;
}
public static MetaLifespan defaultValue() {
return DEFAULT;
}
}
/**
* Read only metadata parameter representing a cached entry's created time
* in milliseconds.
*
* @since 8.0
*/
@Experimental
final class MetaCreated extends MetaLong {
public MetaCreated(long created) {
super(created);
}
@Override
public String toString() {
return "MetaCreated=" + value;
}
}
/**
* Writable metadata parameter representing a cached entry's millisecond
* max idle time.
*
* @since 8.0
*/
@Experimental
final class MetaMaxIdle extends MetaLong implements Writable {
private static final MetaMaxIdle DEFAULT = new MetaMaxIdle(-1);
public MetaMaxIdle(long maxIdle) {
super(maxIdle);
}
@Override
public String toString() {
return "MetaMaxIdle=" + value;
}
public static MetaMaxIdle defaultValue() {
return DEFAULT;
}
}
/**
* Read only metadata parameter representing a cached entry's last used time
* in milliseconds.
*
* @since 8.0
*/
@Experimental
final class MetaLastUsed extends MetaLong {
public MetaLastUsed(long lastUsed) {
super(lastUsed);
}
@Override
public String toString() {
return "MetaLastUsed=" + value;
}
}
/**
* Writable metadata parameter representing a cached entry's generic version.
*
* @since 8.0
*/
@Experimental
class MetaEntryVersion implements Writable {
private final EntryVersion entryVersion;
public MetaEntryVersion(EntryVersion entryVersion) {
this.entryVersion = entryVersion;
}
@Override
public EntryVersion get() {
return entryVersion;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
MetaEntryVersion that = (MetaEntryVersion) o;
return entryVersion.equals(that.entryVersion);
}
@Override
public int hashCode() {
return entryVersion.hashCode();
}
@Override
public String toString() {
return "MetaEntryVersion=" + entryVersion;
}
}
/**
* Abstract class for numeric long-based metadata parameter instances.
*
* @since 8.0
*/
@Experimental
abstract class MetaLong implements MetaParam {
protected final long value;
public MetaLong(long value) {
this.value = value;
}
public Long get() {
return value;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
MetaLong longMeta = (MetaLong) o;
return value == longMeta.value;
}
@Override
public int hashCode() {
return (int) (value ^ (value >>> 32));
}
}
@Experimental
abstract class MetaBoolean implements MetaParam {
protected final boolean value;
public MetaBoolean(boolean value) {
this.value = value;
}
public Boolean get() {
return value;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
MetaBoolean metaBoolean = (MetaBoolean) o;
return value == metaBoolean.value;
}
@Override
public int hashCode() {
return value ? 1 : 0;
}
}
/**
* Non-writable parameter telling if the entry was loaded from a persistence tier
* ({@link org.infinispan.persistence.spi.CacheLoader}) or not.
* This information may be available only to write commands due to implementation reasons.
*/
@Experimental
final class MetaLoadedFromPersistence extends MetaBoolean {
public static final MetaLoadedFromPersistence LOADED = new MetaLoadedFromPersistence(true);
public static final MetaLoadedFromPersistence NOT_LOADED = new MetaLoadedFromPersistence(false);
private MetaLoadedFromPersistence(boolean loaded) {
super(loaded);
}
public static MetaLoadedFromPersistence of(boolean loaded) {
return loaded ? LOADED : NOT_LOADED;
}
}
/**
* A parameter to tell if the creation timestamp should be updated for modified entries.
*
* Created entries will always update its creation timestamp.
*/
@Experimental
final class MetaUpdateCreationTime extends MetaBoolean implements Writable {
private static final MetaUpdateCreationTime UPDATE = new MetaUpdateCreationTime(true);
private static final MetaUpdateCreationTime NOT_UPDATE = new MetaUpdateCreationTime(false);
public MetaUpdateCreationTime(boolean value) {
super(value);
}
public static MetaUpdateCreationTime of(boolean update) {
return update ? UPDATE : NOT_UPDATE;
}
}
}