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

com.tectonica.kvs.KeyValueStore Maven / Gradle / Ivy

Go to download

Simple yet powerful facade for Key-Value store engine, capable of supporting many underlying data-stores

The newest version!
/*
 * Copyright (C) 2014 Zach Melamed
 * 
 * Latest version available online at https://github.com/zach-m/tectonica-kvs
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.tectonica.kvs;

import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import com.tectonica.kvs.Index.IndexMapper;
import com.tectonica.kvs.KeyValueStore.KeyValue;

/**
 * Simple, yet powerful, framework (and approach) for handling a key-value store. It allows for multiple concurrent readers but a single
 * concurrent writer on each entry. It also provides a read-before-update mechanism which makes life simpler and keeps data consistent.
 * Indexing is also supported as part of the framework. The interface is intuitive and straightforward. This class itself is abstract and
 * subclasses are included for several backend persistence engines, including in-memory (which is great for development).
 * 

* The usage of this framework would probably yield the most benefit when used to prototype a data model, where changes are frequent and not * backwards-compatible. However, in more than a few scenarios, this framework can be used in production. The heavy-lifting is done by the * backend database and cache either way. * * @author Zach Melamed */ public interface KeyValueStore extends Iterable> { public static interface KeyValue { K getKey(); V getValue(); } public static interface KeyMapper { public K getKeyOf(V value); } public static interface ValueGenerator { V generate(K key); } public static enum EventType { PreUpdate, PrePersistUpdate, PreAdd, PrePut; } public interface EventHandler { public void handle(EventType type, K key, V value); } // GETTERS V get(K key); V get(K key, boolean cacheResult); /** * Executes {@link #iteratorFor(Collection, boolean)} with {@code postponeCaching} set to false */ Iterator> iteratorFor(Collection keys); /** * Returns an iterator for a list of entries whose keys were passed to the method *

* IMPORTANT: Unlike simple 'SELECT WHERE KEY IN (..)', the list returned here is guaranteed to be at the exact same order of the * keys passed. Moreover, if a certain key is passed more than once, so will its corresponding entry. Clearly, if a key doesn't exist in * the store, it will be skipped (i.e. the returning list will never contain nulls). * * @param keys * ordered collection of keys to lookup (this is not necessarily a set, as keys can appear more than once in the collection) * @param postponeCaching * indicates whether cache entries individually as each is read from the backend storage, or cache them all in a single call * at the end of the iteration (use only if you'll certainly iterate through the entire result) */ Iterator> iteratorFor(Collection keys, boolean postponeCaching); Iterator keyIterator(); Iterator valueIterator(); Iterator valueIteratorFor(Collection keys); Iterator valueIteratorFor(Collection keys, boolean postponeCaching); Set keySet(); List values(); List valuesFor(Collection keys); boolean containsKey(K key); // SETTERS /** * inserts a new entry, whose key doesn't already exist in storage. it's a faster and more resource-efficient way to insert entries * compared to {@link #put(Object, Object)} as it doesn't use any locking. do not use if you're not completely sure whether the key * already exists. the behavior of the store in such case is undetermined and implementation-dependent. */ void add(K key, V value); /** * inserts or updates an entry. if you're sure that the entry is new (i.e. its key doesn't already exist), use the more efficient * {@link #add(Object, Object)} instead */ void put(K key, V value); /** * insert and entry only if the key is not yet taken * * @return * the newly added value, or null if nothing was inserted */ V putIfAbsent(K key, ValueGenerator generator); V update(K key, Updater updater); int update(Collection keys, Updater updater); /** * convenience method to update all entries */ int updateAll(Updater updater); /** * convenience method applicable when {@code keyMapper} is provided * * @see {@link #update(Object, Updater)} */ V updateValue(V value, Updater updater); /** * convenience method applicable when {@code keyMapper} is provided * * @see {@link #add(Object, Object)} */ void addValue(V value); /** * convenience method applicable when {@code keyMapper} is provided * * @see {@link #put(Object, Object)} */ void putValue(V value); // DELETERS boolean delete(K key); int deleteAll(); // ETC /** * returns an object representing an {@link Index} on the stored entries. The index allows quick search of keys by a certain expression, * calculated whenever an entry is stored / modified. *

* NOTE: When the underlying storage engine is SQL-based, use {@link #createTypedIndex(String, Class, IndexMapper)} instead. */ Index createIndex(String indexName, IndexMapper mapFunc); /** * returns an object representing an {@link Index} on the stored entries. The index allows quick search of keys by a certain expression, * calculated whenever an entry is stored / modified. *

* The {@code indexClz} parameter can be null, when the underlying storage engine is not typed (true for most NoSQL engines) */ Index createTypedIndex(String indexName, Class indexClz, IndexMapper mapFunc); void clearCache(); void addListener(EventType type, EventHandler handler); }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy