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

com.jparams.store.Store Maven / Gradle / Ivy

There is a newer version: 3.1.4
Show newest version
package com.jparams.store;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Optional;
import java.util.UUID;

import com.jparams.store.index.Index;
import com.jparams.store.index.IndexDefinition;
import com.jparams.store.index.IndexException;
import com.jparams.store.index.KeyMapper;
import com.jparams.store.query.Query;

/**
 * Store of data
 *
 * @param  value type
 */
public interface Store extends Collection
{
    /**
     * Create an index using the index build provided
     *
     * @param indexName       name of the index
     * @param indexDefinition build of the index
     * @param              indexed key type
     * @return index
     * @throws IndexException thrown if the creation of the new index fails with exceptions.
     */
     Index index(String indexName, IndexDefinition indexDefinition) throws IndexException;

    /**
     * Create an index using the index build provided
     *
     * @param indexDefinition build of the index
     * @param              indexed key type
     * @return index
     * @throws IndexException thrown if the creation of the new index fails with exceptions.
     */
    default  Index index(final IndexDefinition indexDefinition) throws IndexException
    {
        return index(UUID.randomUUID().toString(), indexDefinition);
    }

    /**
     * Register a new index with this store, mapping a single value to a collection of indexed keys.
     * This is a convenient of creating an index, for more options see {@link #index(IndexDefinition)}
     *
     * @param indexName name of the index
     * @param keyMapper function to provide a value to one or more keys
     * @param        key type
     * @return index
     * @throws IndexException thrown if the new index failed with exceptions.
     */
    default  Index index(final String indexName, final KeyMapper keyMapper) throws IndexException
    {
        return index(indexName, IndexDefinition.withKeyMapping(keyMapper));
    }

    /**
     * Register a new index with this store, mapping a single value to a collection of indexed keys.
     * This is a convenient of creating an index, for more options see {@link #index(IndexDefinition)}
     *
     * @param keyMapper function to provide a value to one or more keys
     * @param        key type
     * @return index
     * @throws IndexException thrown if the new index failed with exceptions.
     */
    default  Index index(final KeyMapper keyMapper) throws IndexException
    {
        return index(IndexDefinition.withKeyMapping(keyMapper));
    }

    /**
     * Query an index by name and lookup the given key. This method is the equivalent of calling {@link #getIndex(String)}
     * and then {@link Index#get(Object)}
     *
     * @param indexName name of the index to query
     * @param key       key to lookup
     * @param limit     limit results to the first x number of items
     * @return values associated with this key or an empty list
     */
    default List get(final String indexName, final Object key, final Integer limit)
    {
        return get(Query.where(indexName, key), limit);
    }

    /**
     * Query an index by name and lookup the given key. This method is the equivalent of calling {@link #getIndex(String)}
     * and then {@link Index#get(Object)}
     *
     * @param indexName name of the index to query
     * @param key       key to lookup
     * @return values associated with this key or an empty list
     */
    default List get(final String indexName, final Object key)
    {
        return get(Query.where(indexName, key), null);
    }

    /**
     * Query an index by name and lookup the given key. This method is the equivalent of calling {@link #getIndex(String)}
     * and then {@link Index#getFirst(Object)}
     *
     * @param indexName name of the index to query
     * @param key       key to lookup
     * @return first value associated with this key or null
     */
    default V getFirst(final String indexName, final Object key)
    {
        return getFirst(Query.where(indexName, key));
    }

    /**
     * Query an index by name and lookup the given key. This method is the equivalent of calling {@link #getIndex(String)}
     * and then {@link Index#findFirst(Object)}
     *
     * @param indexName name of the index to query
     * @param key       key to lookup
     * @return first value associated with this key or an empty optional
     */
    default Optional findFirst(final String indexName, final Object key)
    {
        return Optional.ofNullable(getFirst(indexName, key));
    }

    /**
     * Query indexes and look up all  matching value.
     *
     * @param query query to execute
     * @param limit limit results to the first x number of items
     * @return values associated with this key or an empty list
     */
    List get(final Query query, Integer limit);

    /**
     * Query indexes and look up all  matching value.
     *
     * @param query query to execute
     * @return values associated with this key or an empty list
     */
    default List get(final Query query)
    {
        return get(query, null);
    }

    /**
     * Query indexes and look up the first matching value.
     *
     * @param query query to execute
     * @return first value matching the query
     */
    default V getFirst(final Query query)
    {
        final List results = get(query, 1);
        return results.isEmpty() ? null : results.get(0);
    }

    /**
     * Query indexes and look up the first matching value.
     *
     * @param query query to execute
     * @return first value matching the query
     */
    default Optional findFirst(final Query query)
    {
        return Optional.ofNullable(getFirst(query));
    }

    /**
     * Find index with name. This is the same as {@link Store#findIndex(String)}, but returns a null instead of an optional if an index cannot be found.
     *
     * @param indexName name of index to lookup
     * @return index
     */
    Index getIndex(String indexName);

    /**
     * Get all indexes
     *
     * @return indexes
     */
    Collection> getIndexes();

    /**
     * Remove all indexes associated with this store
     */
    default void removeAllIndexes()
    {
        new ArrayList<>(getIndexes()).forEach(this::removeIndex);
    }

    /**
     * Find index with name. This is the same as {@link Store#getIndex(String)}, but returns an optional instead of a null if an index cannot be found.
     *
     * @param indexName name of index to lookup
     * @return index optional
     */
    default Optional> findIndex(final String indexName)
    {
        return Optional.ofNullable(getIndex(indexName));
    }

    /**
     * Remove an index from store
     *
     * @param indexName index to remove
     * @return true if removed successfully
     */
    boolean removeIndex(String indexName);

    /**
     * Remove an index from store
     *
     * @param index index to remove
     * @return true if removed successfully
     */
    boolean removeIndex(Index index);

    /**
     * Clear the existing indexes and reindex the entire store. This can be a slow operation
     * depending on the number of items in the store and total number of indexes.
     *
     * @throws IndexException thrown if one or more indexes failed with exceptions.
     */
    void reindex() throws IndexException;

    /**
     * Reindex a collection of items. This method will need to be called anytime a change
     * is made to items stored within the store that causes its indexes to become out
     * of date.
     *
     * @param items items to reindex
     * @throws IndexException thrown if one or more indexes failed with exceptions.
     */
    void reindex(Collection items) throws IndexException;

    /**
     * Reindex a particular item. This method will need to be called anytime a change
     * is made to an item stored within the store that causes its indexes to become out
     * of date.
     *
     * @param item item to reindex
     * @throws IndexException thrown if one or more indexes failed with exceptions.
     */
    void reindex(final V item) throws IndexException;

    /**
     * Adds an item to the store and indexes it. If the item already exists in the store,
     * it will be reindexed.
     *
     * @param item item to on
     * @return true if item did not previously exist in the store.
     * @throws IndexException thrown if one or more indexes failed with exceptions.
     */
    @Override
    boolean add(V item) throws IndexException;

    /**
     * Adds all item to the store and indexes them. If an item already exists in the store,
     * it will be reindexed.
     *
     * @param items items to on
     * @return true if one or more items did not previously exist in the store.
     * @throws IndexException thrown if one or more indexes failed with exceptions.
     */
    @Override
    boolean addAll(Collection items) throws IndexException;

    /**
     * Adds all item to the store and indexes them. If an item already exists in the store,
     * it will be re-indexed.
     *
     * @param items items to on
     * @return true if one or more items did not previously exist in the store.
     * @throws IndexException thrown if one or more indexes failed with exceptions.
     */
    default boolean addAll(final V[] items) throws IndexException
    {
        return addAll(Arrays.asList(items));
    }

    /**
     * Create a copy of this store. This can be an expensive operation depending
     * on the number of items and indexes present. The copied store will be fully
     * independent from this store. Any changes made to the copy will not reflect back
     * onto this store.
     *
     * @return copy
     */
    Store copy();

    /**
     * Returns an unmodifiable view of this store. This method allows
     * modules to provide users with "read-only" access to internal
     * collections. Query operations on the returned store "read through"
     * the backed store, and attempts to modify the returned
     * store, whether direct or via its iterator, result in an
     * UnsupportedOperationException.

* * @return an unmodifiable view of this store. */ default Store unmodifiableStore() { return new UnmodifiableStore<>(this); } /** * Returns a synchronized (thread-safe) map Store backed by this store. * In order to guarantee serial access, it is critical that * all access to the backing store is accomplished * through the returned store.

Any references held to {@link Index}es * should be discarded. Call {@link Store#getIndex(String)} on the synchronized * store to obtain synchronized indexes. * * It is imperative that the user manually synchronize on the returned * Store when iterating over it: *

     *  Store store = oldStore.synchronizedStore();
     *      ...
     *  synchronized (store) {
     *      Iterator i = store.iterator(); // Must be in synchronized block
     *      while (i.hasNext())
     *          foo(i.next());
     *  }
     * 
* Failure to follow this advice may result in non-deterministic behavior. * * @return synchronized store */ default Store synchronizedStore() { return new SynchronizedStore<>(this); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy