Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions re-cache/src/main/java/com/g2forge/reassert/cache/ICache.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,20 @@

import com.g2forge.alexandria.java.function.IFunction1;

/**
* An on disk cache, capable of creating multiple cache areas. Each cache area can have it's own key and value types.
*/
public interface ICache {
/**
* Create a cache area from it's descriptor.
*
* @param <K>
* The type of keys for this cache area.
* @param <V>
* The type of values for this cache area.
* @param areaDescriptor
* The cache area descriptor.
* @return A cache area. A function from keys to values.
*/
public <K, V> IFunction1<? super K, ? extends V> createArea(ICacheAreaDescriptor<K, V> areaDescriptor);
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,88 @@

import java.nio.file.Path;

import com.g2forge.alexandria.java.adt.name.INamed;
import com.g2forge.alexandria.java.function.IFunction1;
import com.g2forge.alexandria.java.function.IFunction2;
import com.g2forge.reassert.cache.store.ICacheStore;

public interface ICacheAreaDescriptor<K, V> {
/**
* A descriptor for a cache area. The methods on this interface allow the cache to learn how to compute values, load &amp; store keys, exceptions, and values,
* and where to create cache entries within this area. Caches should cache exceptions when possible, and should verify that the key for any cache entry matches
* to expected key in case of collisions in {@link #getHashFunction()}.
*
* @param <K>
* The type of keys for this cache area.
* @param <V>
* The type of values for this cache area.
*/
public interface ICacheAreaDescriptor<K, V> extends INamed<Path> {
/**
* Storage abstraction for exceptions from {@link #getFunction()}. Exceptions are cached in order to improve performance. See
* {@link com.g2forge.reassert.cache.store.ObjectSerializationCacheStore} which is strongly recommended as being one of the few ways to serialize and
* deserialize exceptions in Java.
*
* @return Storage abstraction for the cache function exceptions.
*/
public ICacheStore<Exception> getExceptionConverter();

/**
* Get the name of the on-disk exception within the cache entry.
*
* @return The name of the on-disk exception within the cache entry.
*/
public String getExceptionName();

/**
* The function to cache. Accepts the key, and the on-disk path where the value should be cached. The path should only be used if this function is
* downloading something, or otherwise making a copy of a large file structure. The path will not exist when this function is called, but it can be created
* by this function. If <code>path</code> is <code>null</code> then the function should download any files to a temp directory instead. Returns the actual
* value.
*
* @return The function whose results we are caching. A function from key and local path to actual value.
*/
public IFunction2<? super K, ? super Path, ? extends V> getFunction();

/**
* Key hash function used to determine the on-disk location of the cache entry within the cache area. This function should return a (hopefully, but not
* necessarily always) unique path for each key, which is valid on this operating system. <code>key -> Paths.get(key.toString())</code>, or something
* equally simple, is acceptable if there are never OS-disallowed characters in that string.
*
* @return The key hash function.
*/
public IFunction1<? super K, ? extends Path> getHashFunction();

/**
* Storage abstraction for the cache keys. See implementations of {@link ICacheStore}.
*
* @return Storage abstraction for the cache keys
*/
public ICacheStore<K> getKeyConverter();

/**
* Get the name of the on-disk key within the cache entry.
*
* @return The name of the on-disk key within the cache entry.
*/
public String getKeyName();

/**
* A name for this cache area. Should be unique to whatever is being cached and stable over time. <code>Paths.get(getClass().getSimpleName())</code> is
* often a reasonable value.
*/
public Path getName();

/**
* Storage abstraction for the cache values. See implementations of {@link ICacheStore}.
*
* @return Storage abstraction for the cache values.
*/
public ICacheStore<V> getValueConverter();

public ICacheStore<Exception> getExceptionConverter();

/**
* Get the name of the on-disk value within the cache entry.
*
* @return The name of the on-disk value within the cache entry.
*/
public String getValueName();

public String getExceptionName();
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@
import com.g2forge.alexandria.java.io.RuntimeIOException;
import com.g2forge.alexandria.java.io.file.HFile;

/**
* A cache store for directories abstracted as java paths. They are moved into the cache when stored, or copied in if the move fails.
*/
public class DirectoryCacheStore implements ICacheStore<Path> {
@Override
public Path load(Path path) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@

import com.g2forge.alexandria.java.io.RuntimeIOException;

/**
* A cache store for files abstracted as java paths. They are moved into the cache when stored.
*/
public class FileCacheStore implements ICacheStore<Path> {
@Override
public Path load(Path path) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,30 @@

import java.nio.file.Path;

/**
* A type-specific storage abstraction for cached keys and values.
*
* @param <T>
* The type being stored.
*/
public interface ICacheStore<T> {
/**
* Load a value from the specified path.
*
* @param path
* The file or directory to load.
* @return The loaded value.
*/
public T load(Path path);

/**
* Store a value to the specified path.
*
* @param path
* The file or directory to store a value to. This may or may not exist.
* @param value
* The value to store.
* @return The value that was stored.
*/
public T store(Path path, T value);
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,19 @@
import lombok.Getter;
import lombok.RequiredArgsConstructor;

/**
* A cache store for objects, which uses a jackson object mapper to serialize and deserialize them.
*
* @param <T>
* The type of the values being stored.
*/
@Getter
@RequiredArgsConstructor
public class JacksonCacheStore<T> implements ICacheStore<T> {
/** The jackson mapper to use during serdes. */
protected final ObjectMapper mapper;

/** The type of the values being stored. */
protected final ITypeRef<T> type;

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,17 @@
import lombok.Getter;
import lombok.RequiredArgsConstructor;

/**
* A cache store for objects, which uses java object serialization. This is particularly suited to storing exceptions on disk, and is often used for
* {@link com.g2forge.reassert.cache.ICacheAreaDescriptor#getExceptionConverter()}.
*
* @param <T>
* The type of the values being stored.
*/
@Getter
@RequiredArgsConstructor
public class ObjectSerializationCacheStore<T> implements ICacheStore<T> {
/** The type of the values being stored. */
protected final ITypeRef<T> type;

@Override
Expand Down