blob: e37e8068120aa758c07711314df3150a37b0df31 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*/
/**
* @file
* Declares ignite::cache::Cache class.
*/
#ifndef _IGNITE_CACHE_CACHE
#define _IGNITE_CACHE_CACHE
#include <map>
#include <set>
#include <ignite/common/common.h>
#include <ignite/common/concurrent.h>
#include <ignite/ignite_error.h>
#include <ignite/cache/cache_peek_mode.h>
#include <ignite/cache/query/query_cursor.h>
#include <ignite/cache/query/query_fields_cursor.h>
#include <ignite/cache/query/query_scan.h>
#include <ignite/cache/query/query_sql.h>
#include <ignite/cache/query/query_text.h>
#include <ignite/cache/query/query_sql_fields.h>
#include <ignite/cache/query/continuous/continuous_query_handle.h>
#include <ignite/cache/query/continuous/continuous_query.h>
#include <ignite/impl/cache/cache_impl.h>
#include <ignite/impl/cache/cache_entry_processor_holder.h>
#include <ignite/impl/operations.h>
#include <ignite/impl/module_manager.h>
#include <ignite/ignite_error.h>
namespace ignite
{
namespace cache
{
/**
* Main entry point for all Data Grid APIs.
*
* Both key and value types should be default-constructable,
* copy-constructable and assignable. Also BinaryType class
* template should be specialized for both types.
*
* This class implemented as a reference to an implementation so copying
* of this class instance will only create another reference to the same
* underlying object. Underlying object released automatically once all
* the instances are destructed.
*
* @tparam K Cache key type.
* @tparam V Cache value type.
*/
template<typename K, typename V>
class IGNITE_IMPORT_EXPORT Cache
{
public:
/**
* Constructor.
*
* Internal method. Should not be used by user.
*
* @param impl Implementation.
*/
Cache(impl::cache::CacheImpl* impl) :
impl(impl)
{
// No-op.
}
/**
* Get name of this cache (null for default cache).
*
* This method should only be used on the valid instance.
*
* @return Name of this cache (null for default cache).
*/
const char* GetName() const
{
return impl.Get()->GetName();
}
/**
* Checks whether this cache contains no key-value mappings.
* Semantically equals to Cache.Size(CachePeekMode::PRIMARY) == 0.
*
* This method should only be used on the valid instance.
*
* @return True if cache is empty.
*/
bool IsEmpty()
{
IgniteError err;
bool res = IsEmpty(err);
IgniteError::ThrowIfNeeded(err);
return res;
}
/**
* Checks whether this cache contains no key-value mappings.
* Semantically equals to Cache.Size(CachePeekMode::PRIMARY) == 0.
*
* This method should only be used on the valid instance.
*
* @param err Error.
* @return True if cache is empty.
*/
bool IsEmpty(IgniteError& err)
{
return Size(err) == 0;
}
/**
* Check if cache contains mapping for this key.
*
* This method should only be used on the valid instance.
*
* @param key Key.
* @return True if cache contains mapping for this key.
*/
bool ContainsKey(const K& key)
{
IgniteError err;
bool res = ContainsKey(key, err);
IgniteError::ThrowIfNeeded(err);
return res;
}
/**
* Check if cache contains mapping for this key.
*
* This method should only be used on the valid instance.
*
* @param key Key.
* @param err Error.
* @return True if cache contains mapping for this key.
*/
bool ContainsKey(const K& key, IgniteError& err)
{
impl::In1Operation<K> op(key);
return impl.Get()->ContainsKey(op, err);
}
/**
* Check if cache contains mapping for these keys.
*
* This method should only be used on the valid instance.
*
* @param keys Keys.
* @return True if cache contains mapping for all these keys.
*/
bool ContainsKeys(const std::set<K>& keys)
{
IgniteError err;
bool res = ContainsKeys(keys, err);
IgniteError::ThrowIfNeeded(err);
return res;
}
/**
* Check if cache contains mapping for these keys.
*
* This method should only be used on the valid instance.
*
* @param begin Iterator pointing to the beggining of the key sequence.
* @param end Iterator pointing to the end of the key sequence.
* @return True if cache contains mapping for all these keys.
*/
template<typename InputIter>
bool ContainsKeys(InputIter begin, InputIter end)
{
IgniteError err;
impl::InIterOperation<K, V, InputIter> op(begin, end);
bool res = impl.Get()->ContainsKeys(op, err);
IgniteError::ThrowIfNeeded(err);
return res;
}
/**
* Check if cache contains mapping for these keys.
*
* This method should only be used on the valid instance.
*
* @param keys Keys.
* @param err Error.
* @return True if cache contains mapping for all these keys.
*/
bool ContainsKeys(const std::set<K>& keys, IgniteError& err)
{
impl::InSetOperation<K> op(keys);
return impl.Get()->ContainsKeys(op, err);
}
/**
* Peeks at cached value using optional set of peek modes. This method will sequentially
* iterate over given peek modes, and try to peek at value using each peek mode. Once a
* non-null value is found, it will be immediately returned.
* This method does not participate in any transactions, however, it may peek at transactional
* value depending on the peek modes used.
*
* This method should only be used on the valid instance.
*
* @param key Key.
* @param peekModes Peek modes.
* @return Value.
*/
V LocalPeek(const K& key, int32_t peekModes)
{
IgniteError err;
V res = LocalPeek(key, peekModes, err);
IgniteError::ThrowIfNeeded(err);
return res;
}
/**
* Peeks at cached value using optional set of peek modes. This method will sequentially
* iterate over given peek modes, and try to peek at value using each peek mode. Once a
* non-null value is found, it will be immediately returned.
* This method does not participate in any transactions, however, it may peek at transactional
* value depending on the peek modes used.
*
* This method should only be used on the valid instance.
*
* @param key Key.
* @param peekModes Peek modes.
* @param err Error.
* @return Value.
*/
V LocalPeek(const K& key, int32_t peekModes, IgniteError& err)
{
impl::InCacheLocalPeekOperation<K> inOp(key, peekModes);
impl::Out1Operation<V> outOp;
impl.Get()->LocalPeek(inOp, outOp, peekModes, err);
return outOp.GetResult();
}
/**
* Retrieves value mapped to the specified key from cache.
* If the value is not present in cache, then it will be looked up from swap storage. If
* it's not present in swap, or if swap is disabled, and if read-through is allowed, value
* will be loaded from persistent store.
* This method is transactional and will enlist the entry into ongoing transaction if there is one.
*
* This method should only be used on the valid instance.
*
* @param key Key.
* @return Value.
*/
V Get(const K& key)
{
IgniteError err;
V res = Get(key, err);
IgniteError::ThrowIfNeeded(err);
return res;
}
/**
* Retrieves value mapped to the specified key from cache.
* If the value is not present in cache, then it will be looked up from swap storage. If
* it's not present in swap, or if swap is disabled, and if read-through is allowed, value
* will be loaded from persistent store.
* This method is transactional and will enlist the entry into ongoing transaction if there is one.
*
* This method should only be used on the valid instance.
*
* @param key Key.
* @param err Error.
* @return Value.
*/
V Get(const K& key, IgniteError& err)
{
impl::In1Operation<K> inOp(key);
impl::Out1Operation<V> outOp;
impl.Get()->Get(inOp, outOp, err);
return outOp.GetResult();
}
/**
* Retrieves values mapped to the specified keys from cache.
* If some value is not present in cache, then it will be looked up from swap storage. If
* it's not present in swap, or if swap is disabled, and if read-through is allowed, value
* will be loaded from persistent store.
* This method is transactional and will enlist the entry into ongoing transaction if there is one.
*
* This method should only be used on the valid instance.
*
* @param keys Keys.
* @return Map of key-value pairs.
*/
std::map<K, V> GetAll(const std::set<K>& keys)
{
IgniteError err;
std::map<K, V> res = GetAll(keys, err);
IgniteError::ThrowIfNeeded(err);
return res;
}
/**
* Retrieves values mapped to the specified keys from cache.
* If some value is not present in cache, then it will be looked up from swap storage. If
* it's not present in swap, or if swap is disabled, and if read-through is allowed, value
* will be loaded from persistent store.
* This method is transactional and will enlist the entry into ongoing transaction if there is one.
*
* This method should only be used on the valid instance.
*
* @param keys Keys.
* @param err Error.
* @return Map of key-value pairs.
*/
std::map<K, V> GetAll(const std::set<K>& keys, IgniteError& err)
{
impl::InSetOperation<K> inOp(keys);
impl::OutMapOperation<K, V> outOp;
impl.Get()->GetAll(inOp, outOp, err);
return outOp.GetResult();
}
/**
* Retrieves values mapped to the specified keys from cache.
* If some value is not present in cache, then it will be looked up from swap storage. If
* it's not present in swap, or if swap is disabled, and if read-through is allowed, value
* will be loaded from persistent store.
* This method is transactional and will enlist the entry into ongoing transaction if there is one.
*
* This method should only be used on the valid instance.
*
* @param begin Iterator pointing to the beggining of the key sequence.
* @param end Iterator pointing to the end of the key sequence.
* @param dst Output iterator. Should dereference to std::pair or CacheEntry.
*/
template<typename InIter, typename OutIter>
void GetAll(InIter begin, InIter end, OutIter dst)
{
IgniteError err;
impl::InIterOperation<K, V, InIter> inOp(begin, end);
impl::OutMapIterOperation<K, V, OutIter> outOp(dst);
impl.Get()->GetAll(inOp, outOp, err);
IgniteError::ThrowIfNeeded(err);
}
/**
* Associates the specified value with the specified key in the cache.
* If the cache previously contained a mapping for the key,
* the old value is replaced by the specified value.
*
* This method should only be used on the valid instance.
*
* @param key Key with which the specified value is to be associated.
* @param val Value to be associated with the specified key.
*/
void Put(const K& key, const V& val)
{
IgniteError err;
Put(key, val, err);
IgniteError::ThrowIfNeeded(err);
}
/**
* Associates the specified value with the specified key in the cache.
* If the cache previously contained a mapping for the key,
* the old value is replaced by the specified value.
*
* This method should only be used on the valid instance.
*
* @param key Key with which the specified value is to be associated.
* @param val Value to be associated with the specified key.
* @param err Error.
*/
void Put(const K& key, const V& val, IgniteError& err)
{
impl::In2Operation<K, V> op(key, val);
impl.Get()->Put(op, err);
}
/**
* Stores given key-value pairs in cache.
* If write-through is enabled, the stored values will be persisted to store.
* This method is transactional and will enlist the entry into ongoing transaction if there is one.
*
* This method should only be used on the valid instance.
*
* @param vals Key-value pairs to store in cache.
*/
void PutAll(const std::map<K, V>& vals)
{
IgniteError err;
PutAll(vals, err);
IgniteError::ThrowIfNeeded(err);
}
/**
* Stores given key-value pairs in cache.
* If write-through is enabled, the stored values will be persisted to store.
* This method is transactional and will enlist the entry into ongoing transaction if there is one.
*
* This method should only be used on the valid instance.
*
* @param vals Key-value pairs to store in cache.
* @param err Error.
*/
void PutAll(const std::map<K, V>& vals, IgniteError& err)
{
impl::InMapOperation<K, V> op(vals);
impl.Get()->PutAll(op, err);
}
/**
* Stores given key-value pairs in cache.
* If write-through is enabled, the stored values will be persisted to store.
* This method is transactional and will enlist the entry into ongoing transaction if there is one.
*
* This method should only be used on the valid instance.
*
* @param begin Iterator pointing to the beggining of the key-value pair sequence.
* @param end Iterator pointing to the end of the key-value pair sequence.
*/
template<typename Iter>
void PutAll(Iter begin, Iter end)
{
IgniteError err;
impl::InIterOperation<K, V, Iter> op(begin, end);
impl.Get()->PutAll(op, err);
IgniteError::ThrowIfNeeded(err);
}
/**
* Associates the specified value with the specified key in this cache,
* returning an existing value if one existed.
*
* This method should only be used on the valid instance.
*
* @param key Key with which the specified value is to be associated.
* @param val Value to be associated with the specified key.
* @return The value associated with the key at the start of the
* operation or null if none was associated.
*/
V GetAndPut(const K& key, const V& val)
{
IgniteError err;
V res = GetAndPut(key, val, err);
IgniteError::ThrowIfNeeded(err);
return res;
}
/**
* Associates the specified value with the specified key in this cache,
* returning an existing value if one existed.
*
* This method should only be used on the valid instance.
*
* @param key Key with which the specified value is to be associated.
* @param val Value to be associated with the specified key.
* @param err Error.
* @return The value associated with the key at the start of the
* operation or null if none was associated.
*/
V GetAndPut(const K& key, const V& val, IgniteError& err)
{
impl::In2Operation<K, V> inOp(key, val);
impl::Out1Operation<V> outOp;
impl.Get()->GetAndPut(inOp, outOp, err);
return outOp.GetResult();
}
/**
* Atomically replaces the value for a given key if and only if there is
* a value currently mapped by the key.
*
* This method should only be used on the valid instance.
*
* @param key Key with which the specified value is to be associated.
* @param val Value to be associated with the specified key.
* @return The previous value associated with the specified key, or
* null if there was no mapping for the key.
*/
V GetAndReplace(const K& key, const V& val)
{
IgniteError err;
V res = GetAndReplace(key, val, err);
IgniteError::ThrowIfNeeded(err);
return res;
}
/**
* Atomically replaces the value for a given key if and only if there is
* a value currently mapped by the key.
*
* This method should only be used on the valid instance.
*
* @param key Key with which the specified value is to be associated.
* @param val Value to be associated with the specified key.
* @param err Error.
* @return The previous value associated with the specified key, or
* null if there was no mapping for the key.
*/
V GetAndReplace(const K& key, const V& val, IgniteError& err)
{
impl::In2Operation<K, V> inOp(key, val);
impl::Out1Operation<V> outOp;
impl.Get()->GetAndReplace(inOp, outOp, err);
return outOp.GetResult();
}
/**
* Atomically removes the entry for a key only if currently mapped to some value.
*
* This method should only be used on the valid instance.
*
* @param key Key with which the specified value is associated.
* @return The value if one existed or null if no mapping existed for this key.
*/
V GetAndRemove(const K& key)
{
IgniteError err;
V res = GetAndRemove(key, err);
IgniteError::ThrowIfNeeded(err);
return res;
}
/**
* Atomically removes the entry for a key only if currently mapped to some value.
*
* This method should only be used on the valid instance.
*
* @param key Key with which the specified value is associated.
* @param err Error.
* @return The value if one existed or null if no mapping existed for this key.
*/
V GetAndRemove(const K& key, IgniteError& err)
{
impl::In1Operation<K> inOp(key);
impl::Out1Operation<V> outOp;
impl.Get()->GetAndRemove(inOp, outOp, err);
return outOp.GetResult();
}
/**
* Atomically associates the specified key with the given value if it is not
* already associated with a value.
*
* This method should only be used on the valid instance.
*
* @param key Key with which the specified value is to be associated.
* @param val Value to be associated with the specified key.
* @return True if a value was set.
*/
bool PutIfAbsent(const K& key, const V& val)
{
IgniteError err;
bool res = PutIfAbsent(key, val, err);
IgniteError::ThrowIfNeeded(err);
return res;
}
/**
* Atomically associates the specified key with the given value if it is not
* already associated with a value.
*
* This method should only be used on the valid instance.
*
* @param key Key with which the specified value is to be associated.
* @param val Value to be associated with the specified key.
* @param err Error.
* @return True if a value was set.
*/
bool PutIfAbsent(const K& key, const V& val, IgniteError& err)
{
impl::In2Operation<K, V> op(key, val);
return impl.Get()->PutIfAbsent(op, err);
}
/**
* Stores given key-value pair in cache only if cache had no previous mapping for it.
* If cache previously contained value for the given key, then this value is returned.
* In case of PARTITIONED or REPLICATED caches, the value will be loaded from the primary node,
* which in its turn may load the value from the swap storage, and consecutively, if it's not
* in swap, from the underlying persistent storage.
* If the returned value is not needed, method putxIfAbsent() should be used instead of this one to
* avoid the overhead associated with returning of the previous value.
* If write-through is enabled, the stored value will be persisted to store.
* This method is transactional and will enlist the entry into ongoing transaction if there is one.
*
* This method should only be used on the valid instance.
*
* @param key Key to store in cache.
* @param val Value to be associated with the given key.
* @return Previously contained value regardless of whether put happened or not
* (null if there was no previous value).
*/
V GetAndPutIfAbsent(const K& key, const V& val)
{
IgniteError err;
V res = GetAndPutIfAbsent(key, val, err);
IgniteError::ThrowIfNeeded(err);
return res;
}
/**
* Stores given key-value pair in cache only if cache had no previous mapping for it.
* If cache previously contained value for the given key, then this value is returned.
* In case of PARTITIONED or REPLICATED caches, the value will be loaded from the primary node,
* which in its turn may load the value from the swap storage, and consecutively, if it's not
* in swap, from the underlying persistent storage.
* If the returned value is not needed, method putxIfAbsent() should be used instead of this one to
* avoid the overhead associated with returning of the previous value.
* If write-through is enabled, the stored value will be persisted to store.
* This method is transactional and will enlist the entry into ongoing transaction if there is one.
*
* This method should only be used on the valid instance.
*
* @param key Key to store in cache.
* @param val Value to be associated with the given key.
* @param err Error.
* @return Previously contained value regardless of whether put happened or not
* (null if there was no previous value).
*/
V GetAndPutIfAbsent(const K& key, const V& val, IgniteError& err)
{
impl::In2Operation<K, V> inOp(key, val);
impl::Out1Operation<V> outOp;
impl.Get()->GetAndPutIfAbsent(inOp, outOp, err);
return outOp.GetResult();
}
/**
* Stores given key-value pair in cache only if there is a previous mapping for it.
* If cache previously contained value for the given key, then this value is returned.
* In case of PARTITIONED or REPLICATED caches, the value will be loaded from the primary node,
* which in its turn may load the value from the swap storage, and consecutively, if it's not
* in swap, rom the underlying persistent storage.
* If write-through is enabled, the stored value will be persisted to store.
* This method is transactional and will enlist the entry into ongoing transaction if there is one.
*
* This method should only be used on the valid instance.
*
* @param key Key to store in cache.
* @param val Value to be associated with the given key.
* @return True if the value was replaced.
*/
bool Replace(const K& key, const V& val)
{
IgniteError err;
bool res = Replace(key, val, err);
IgniteError::ThrowIfNeeded(err);
return res;
}
/**
* Stores given key-value pair in cache only if there is a previous mapping for it.
* If cache previously contained value for the given key, then this value is returned.
* In case of PARTITIONED or REPLICATED caches, the value will be loaded from the primary node,
* which in its turn may load the value from the swap storage, and consecutively, if it's not
* in swap, rom the underlying persistent storage.
* If write-through is enabled, the stored value will be persisted to store.
* This method is transactional and will enlist the entry into ongoing transaction if there is one.
*
* This method should only be used on the valid instance.
*
* @param key Key to store in cache.
* @param val Value to be associated with the given key.
* @param err Error.
* @return True if the value was replaced.
*/
bool Replace(const K& key, const V& val, IgniteError& err)
{
impl::In2Operation<K, V> op(key, val);
return impl.Get()->Replace(op, err);
}
/**
* Stores given key-value pair in cache only if only if the previous value is equal to the
* old value passed as argument.
* This method is transactional and will enlist the entry into ongoing transaction if there is one.
*
* This method should only be used on the valid instance.
*
* @param key Key to store in cache.
* @param oldVal Old value to match.
* @param newVal Value to be associated with the given key.
* @return True if replace happened, false otherwise.
*/
bool Replace(const K& key, const V& oldVal, const V& newVal)
{
IgniteError err;
bool res = Replace(key, oldVal, newVal, err);
IgniteError::ThrowIfNeeded(err);
return res;
}
/**
* Stores given key-value pair in cache only if only if the previous value is equal to the
* old value passed as argument.
* This method is transactional and will enlist the entry into ongoing transaction if there is one.
*
* This method should only be used on the valid instance.
*
* @param key Key to store in cache.
* @param oldVal Old value to match.
* @param newVal Value to be associated with the given key.
* @param err Error.
* @return True if replace happened, false otherwise.
*/
bool Replace(const K& key, const V& oldVal, const V& newVal, IgniteError& err)
{
impl::In3Operation<K, V, V> op(key, oldVal, newVal);
return impl.Get()->ReplaceIfEqual(op, err);
}
/**
* Attempts to evict all entries associated with keys.
*
* @note Entry will be evicted only if it's not used (not
* participating in any locks or transactions).
*
* This method should only be used on the valid instance.
*
* @param keys Keys to evict from cache.
*/
void LocalEvict(const std::set<K>& keys)
{
IgniteError err;
LocalEvict(keys, err);
IgniteError::ThrowIfNeeded(err);
}
/**
* Attempts to evict all entries associated with keys.
*
* @note Entry will be evicted only if it's not used (not
* participating in any locks or transactions).
*
* This method should only be used on the valid instance.
*
* @param keys Keys to evict from cache.
* @param err Error.
*/
void LocalEvict(const std::set<K>& keys, IgniteError& err)
{
impl::InSetOperation<K> op(keys);
impl.Get()->LocalEvict(op, err);
}
/**
* Attempts to evict all entries associated with keys.
*
* @note Entry will be evicted only if it's not used (not
* participating in any locks or transactions).
*
* This method should only be used on the valid instance.
*
* @param begin Iterator pointing to the beggining of the key sequence.
* @param end Iterator pointing to the end of the key sequence.
*/
template<typename Iter>
void LocalEvict(Iter begin, Iter end)
{
IgniteError err;
impl::InIterOperation<K, V, Iter> op(begin, end);
impl.Get()->LocalEvict(op, err);
IgniteError::ThrowIfNeeded(err);
}
/**
* Clear cache.
*
* This method should only be used on the valid instance.
*/
void Clear()
{
IgniteError err;
Clear(err);
IgniteError::ThrowIfNeeded(err);
}
/**
* Clear cache.
*
* This method should only be used on the valid instance.
*
* @param err Error.
*/
void Clear(IgniteError& err)
{
impl.Get()->Clear(err);
}
/**
* Clear entry from the cache and swap storage, without notifying listeners or CacheWriters.
* Entry is cleared only if it is not currently locked, and is not participating in a transaction.
*
* This method should only be used on the valid instance.
*
* @param key Key to clear.
*/
void Clear(const K& key)
{
IgniteError err;
Clear(key, err);
IgniteError::ThrowIfNeeded(err);
}
/**
* Clear entry from the cache and swap storage, without notifying listeners or CacheWriters.
* Entry is cleared only if it is not currently locked, and is not participating in a transaction.
*
* This method should only be used on the valid instance.
*
* @param key Key to clear.
* @param err Error.
*/
void Clear(const K& key, IgniteError& err)
{
impl::In1Operation<K> op(key);
impl.Get()->Clear(op, err);
}
/**
* Clear entries from the cache and swap storage, without notifying listeners or CacheWriters.
* Entry is cleared only if it is not currently locked, and is not participating in a transaction.
*
* This method should only be used on the valid instance.
*
* @param keys Keys to clear.
*/
void ClearAll(const std::set<K>& keys)
{
IgniteError err;
ClearAll(keys, err);
IgniteError::ThrowIfNeeded(err);
}
/**
* Clear entries from the cache and swap storage, without notifying listeners or CacheWriters.
* Entry is cleared only if it is not currently locked, and is not participating in a transaction.
*
* This method should only be used on the valid instance.
*
* @param keys Keys to clear.
* @param err Error.
*/
void ClearAll(const std::set<K>& keys, IgniteError& err)
{
impl::InSetOperation<K> op(keys);
impl.Get()->ClearAll(op, err);
}
/**
* Clear entries from the cache and swap storage, without notifying listeners or CacheWriters.
* Entry is cleared only if it is not currently locked, and is not participating in a transaction.
*
* This method should only be used on the valid instance.
*
* @param begin Iterator pointing to the beggining of the key sequence.
* @param end Iterator pointing to the end of the key sequence.
*/
template<typename Iter>
void ClearAll(Iter begin, Iter end)
{
IgniteError err;
impl::InIterOperation<K, V, Iter> op(begin, end);
impl.Get()->ClearAll(op, err);
IgniteError::ThrowIfNeeded(err);
}
/**
* Clear entry from the cache and swap storage, without notifying listeners or CacheWriters.
* Entry is cleared only if it is not currently locked, and is not participating in a transaction.
*
* @note This operation is local as it merely clears an entry from local cache, it does not
* remove entries from remote caches.
*
* This method should only be used on the valid instance.
*
* @param key Key to clear.
*/
void LocalClear(const K& key)
{
IgniteError err;
LocalClear(key, err);
IgniteError::ThrowIfNeeded(err);
}
/**
* Clear entry from the cache and swap storage, without notifying listeners or CacheWriters.
* Entry is cleared only if it is not currently locked, and is not participating in a transaction.
*
* @note This operation is local as it merely clears an entry from local cache, it does not
* remove entries from remote caches.
*
* This method should only be used on the valid instance.
*
* @param key Key to clear.
* @param err Error.
*/
void LocalClear(const K& key, IgniteError& err)
{
impl::In1Operation<K> op(key);
impl.Get()->LocalClear(op, err);
}
/**
* Clear entries from the cache and swap storage, without notifying listeners or CacheWriters.
* Entry is cleared only if it is not currently locked, and is not participating in a transaction.
*
* @note This operation is local as it merely clears entries from local cache, it does not
* remove entries from remote caches.
*
* This method should only be used on the valid instance.
*
* @param keys Keys to clear.
*/
void LocalClearAll(const std::set<K>& keys)
{
IgniteError err;
LocalClearAll(keys, err);
IgniteError::ThrowIfNeeded(err);
}
/**
* Clear entries from the cache and swap storage, without notifying listeners or CacheWriters.
* Entry is cleared only if it is not currently locked, and is not participating in a transaction.
*
* @note This operation is local as it merely clears entries from local cache, it does not
* remove entries from remote caches.
*
* This method should only be used on the valid instance.
*
* @param keys Keys to clear.
* @param err Error.
*/
void LocalClearAll(const std::set<K>& keys, IgniteError& err)
{
impl::InSetOperation<K> op(keys);
impl.Get()->LocalClearAll(op, err);
}
/**
* Clear entries from the cache and swap storage, without notifying listeners or CacheWriters.
* Entry is cleared only if it is not currently locked, and is not participating in a transaction.
*
* @note This operation is local as it merely clears entries from local cache, it does not
* remove entries from remote caches.
*
* This method should only be used on the valid instance.
*
* @param begin Iterator pointing to the beggining of the key sequence.
* @param end Iterator pointing to the end of the key sequence.
*/
template<typename Iter>
void LocalClearAll(Iter begin, Iter end)
{
IgniteError err;
impl::InIterOperation<K, V, Iter> op(begin, end);
impl.Get()->LocalClearAll(op, err);
IgniteError::ThrowIfNeeded(err);
}
/**
* Removes given key mapping from cache. If cache previously contained value for the given key,
* then this value is returned. In case of PARTITIONED or REPLICATED caches, the value will be
* loaded from the primary node, which in its turn may load the value from the disk-based swap
* storage, and consecutively, if it's not in swap, from the underlying persistent storage.
* If the returned value is not needed, method removex() should always be used instead of this
* one to avoid the overhead associated with returning of the previous value.
* If write-through is enabled, the value will be removed from store.
* This method is transactional and will enlist the entry into ongoing transaction if there is one.
*
* This method should only be used on the valid instance.
*
* @param key Key whose mapping is to be removed from cache.
* @return False if there was no matching key.
*/
bool Remove(const K& key)
{
IgniteError err;
bool res = Remove(key, err);
IgniteError::ThrowIfNeeded(err);
return res;
}
/**
* Removes given key mapping from cache. If cache previously contained value for the given key,
* then this value is returned. In case of PARTITIONED or REPLICATED caches, the value will be
* loaded from the primary node, which in its turn may load the value from the disk-based swap
* storage, and consecutively, if it's not in swap, from the underlying persistent storage.
* If the returned value is not needed, method removex() should always be used instead of this
* one to avoid the overhead associated with returning of the previous value.
* If write-through is enabled, the value will be removed from store.
* This method is transactional and will enlist the entry into ongoing transaction if there is one.
*
* This method should only be used on the valid instance.
*
* @param key Key whose mapping is to be removed from cache.
* @param err Error.
* @return False if there was no matching key.
*/
bool Remove(const K& key, IgniteError& err)
{
impl::In1Operation<K> op(key);
return impl.Get()->Remove(op, err);
}
/**
* Removes given key mapping from cache if one exists and value is equal to the passed in value.
* If write-through is enabled, the value will be removed from store.
* This method is transactional and will enlist the entry into ongoing transaction if there is one.
*
* This method should only be used on the valid instance.
*
* @param key Key whose mapping is to be removed from cache.
* @param val Value to match against currently cached value.
* @return True if entry was removed, false otherwise.
*/
bool Remove(const K& key, const V& val)
{
IgniteError err;
bool res = Remove(key, val, err);
IgniteError::ThrowIfNeeded(err);
return res;
}
/**
* Removes given key mapping from cache if one exists and value is equal to the passed in value.
* If write-through is enabled, the value will be removed from store.
* This method is transactional and will enlist the entry into ongoing transaction if there is one.
*
* This method should only be used on the valid instance.
*
* @param key Key whose mapping is to be removed from cache.
* @param val Value to match against currently cached value.
* @param err Error.
* @return True if entry was removed, false otherwise.
*/
bool Remove(const K& key, const V& val, IgniteError& err)
{
impl::In2Operation<K, V> op(key, val);
return impl.Get()->RemoveIfEqual(op, err);
}
/**
* Removes given key mappings from cache.
* If write-through is enabled, the value will be removed from store.
* This method is transactional and will enlist the entry into ongoing transaction if there is one.
*
* This method should only be used on the valid instance.
*
* @param keys Keys whose mappings are to be removed from cache.
*/
void RemoveAll(const std::set<K>& keys)
{
IgniteError err;
RemoveAll(keys, err);
IgniteError::ThrowIfNeeded(err);
}
/**
* Removes given key mappings from cache.
* If write-through is enabled, the value will be removed from store.
* This method is transactional and will enlist the entry into ongoing transaction if there is one.
*
* This method should only be used on the valid instance.
*
* @param keys Keys whose mappings are to be removed from cache.
* @param err Error.
*/
void RemoveAll(const std::set<K>& keys, IgniteError& err)
{
impl::InSetOperation<K> op(keys);
impl.Get()->RemoveAll(op, err);
}
/**
* Removes given key mappings from cache.
* If write-through is enabled, the value will be removed from store.
* This method is transactional and will enlist the entry into ongoing transaction if there is one.
*
* This method should only be used on the valid instance.
*
* @param begin Iterator pointing to the beggining of the key sequence.
* @param end Iterator pointing to the end of the key sequence.
*/
template<typename Iter>
void RemoveAll(Iter begin, Iter end)
{
IgniteError err;
impl::InIterOperation<K, V, Iter> op(begin, end);
impl.Get()->RemoveAll(op, err);
IgniteError::ThrowIfNeeded(err);
}
/**
* Removes all mappings from cache.
* If write-through is enabled, the value will be removed from store.
* This method is transactional and will enlist the entry into ongoing transaction if there is one.
*
* This method should only be used on the valid instance.
*
*/
void RemoveAll()
{
IgniteError err;
RemoveAll(err);
IgniteError::ThrowIfNeeded(err);
}
/**
* Removes all mappings from cache.
* If write-through is enabled, the value will be removed from store.
* This method is transactional and will enlist the entry into ongoing transaction if there is one.
*
* This method should only be used on the valid instance.
*
* @param err Error.
*/
void RemoveAll(IgniteError& err)
{
return impl.Get()->RemoveAll(err);
}
/**
* Gets the number of all entries cached on this node.
*
* This method should only be used on the valid instance.
*
* @return Cache size on this node.
*/
int32_t LocalSize()
{
return LocalSize(CachePeekMode::ALL);
}
/**
* Gets the number of all entries cached on this node.
*
* This method should only be used on the valid instance.
*
* @param err Error.
* @return Cache size on this node.
*/
int32_t LocalSize(IgniteError& err)
{
return LocalSize(CachePeekMode::ALL, err);
}
/**
* Gets the number of all entries cached on this node.
*
* This method should only be used on the valid instance.
*
* @param peekModes Peek modes.
* @return Cache size on this node.
*/
int32_t LocalSize(int32_t peekModes)
{
IgniteError err;
int32_t res = LocalSize(peekModes, err);
IgniteError::ThrowIfNeeded(err);
return res;
}
/**
* Gets the number of all entries cached on this node.
*
* This method should only be used on the valid instance.
*
* @param peekModes Peek modes.
* @param err Error.
* @return Cache size on this node.
*/
int32_t LocalSize(int32_t peekModes, IgniteError& err)
{
return impl.Get()->Size(peekModes, true, err);
}
/**
* Gets the number of all entries cached across all nodes.
* @note this operation is distributed and will query all participating nodes for their cache sizes.
*
* This method should only be used on the valid instance.
*
* @return Cache size across all nodes.
*/
int32_t Size()
{
return Size(ignite::cache::CachePeekMode::ALL);
}
/**
* Gets the number of all entries cached across all nodes.
* @note This operation is distributed and will query all participating nodes for their cache sizes.
*
* This method should only be used on the valid instance.
*
* @param err Error.
* @return Cache size across all nodes.
*/
int32_t Size(IgniteError& err)
{
return Size(ignite::cache::CachePeekMode::ALL, err);
}
/**
* Gets the number of all entries cached across all nodes.
* @note This operation is distributed and will query all participating nodes for their cache sizes.
*
* This method should only be used on the valid instance.
*
* @param peekModes Peek modes.
* @return Cache size across all nodes.
*/
int32_t Size(int32_t peekModes)
{
IgniteError err;
int32_t res = Size(peekModes, err);
IgniteError::ThrowIfNeeded(err);
return res;
}
/**
* Gets the number of all entries cached across all nodes.
* @note This operation is distributed and will query all participating nodes for their cache sizes.
*
* This method should only be used on the valid instance.
*
* @param peekModes Peek modes.
* @param err Error.
* @return Cache size across all nodes.
*/
int32_t Size(int32_t peekModes, IgniteError& err)
{
return impl.Get()->Size(peekModes, false, err);
}
/**
* Perform SQL query.
*
* This method should only be used on the valid instance.
*
* @param qry Query.
* @return Query cursor.
*/
query::QueryCursor<K, V> Query(const query::SqlQuery& qry)
{
IgniteError err;
query::QueryCursor<K, V> res = Query(qry, err);
IgniteError::ThrowIfNeeded(err);
return res;
}
/**
* Perform SQL query.
*
* This method should only be used on the valid instance.
*
* @param qry Query.
* @param err Error.
* @return Query cursor.
*/
query::QueryCursor<K, V> Query(const query::SqlQuery& qry, IgniteError& err)
{
impl::cache::query::QueryCursorImpl* cursorImpl = impl.Get()->QuerySql(qry, err);
return query::QueryCursor<K, V>(cursorImpl);
}
/**
* Perform text query.
*
* This method should only be used on the valid instance.
*
* @param qry Query.
* @return Query cursor.
*/
query::QueryCursor<K, V> Query(const query::TextQuery& qry)
{
IgniteError err;
query::QueryCursor<K, V> res = Query(qry, err);
IgniteError::ThrowIfNeeded(err);
return res;
}
/**
* Perform text query.
*
* This method should only be used on the valid instance.
*
* @param qry Query.
* @param err Error.
* @return Query cursor.
*/
query::QueryCursor<K, V> Query(const query::TextQuery& qry, IgniteError& err)
{
impl::cache::query::QueryCursorImpl* cursorImpl = impl.Get()->QueryText(qry, err);
return query::QueryCursor<K, V>(cursorImpl);
}
/**
* Perform scan query.
*
* This method should only be used on the valid instance.
*
* @param qry Query.
* @return Query cursor.
*/
query::QueryCursor<K, V> Query(const query::ScanQuery& qry)
{
IgniteError err;
query::QueryCursor<K, V> res = Query(qry, err);
IgniteError::ThrowIfNeeded(err);
return res;
}
/**
* Perform scan query.
*
* This method should only be used on the valid instance.
*
* @param qry Query.
* @param err Error.
* @return Query cursor.
*/
query::QueryCursor<K, V> Query(const query::ScanQuery& qry, IgniteError& err)
{
impl::cache::query::QueryCursorImpl* cursorImpl = impl.Get()->QueryScan(qry, err);
return query::QueryCursor<K, V>(cursorImpl);
}
/**
* Perform sql fields query.
*
* This method should only be used on the valid instance.
*
* @param qry Query.
* @return Query cursor.
*/
query::QueryFieldsCursor Query(const query::SqlFieldsQuery& qry)
{
IgniteError err;
query::QueryFieldsCursor res = Query(qry, err);
IgniteError::ThrowIfNeeded(err);
return res;
}
/**
* Perform sql fields query.
*
* This method should only be used on the valid instance.
*
* @param qry Query.
* @param err Error.
* @return Query cursor.
*/
query::QueryFieldsCursor Query(const query::SqlFieldsQuery& qry, IgniteError& err)
{
impl::cache::query::QueryCursorImpl* cursorImpl = impl.Get()->QuerySqlFields(qry, err);
return query::QueryFieldsCursor(cursorImpl);
}
/**
* Invokes an CacheEntryProcessor against the MutableCacheEntry
* specified by the provided key. If an entry does not exist for the
* specified key, an attempt is made to load it (if a loader is
* configured) or a surrogate entry, consisting of the key with a
* null value is used instead.
*
* Return value, processor and argument classes should all be
* default-constructable, copy-constructable and assignable. Also,
* BinaryType class template should be specialized for every custom
* class.
*
* Processor class should be registered as a cache entry processor using
* IgniteBinding::RegisterCacheEntryProcessor() method. You can declare
* #IgniteModuleInit() function to register your cache processors upon
* module loading. There should be at most one instance of such function
* per module.
*
* See the example below for details:
* @code{.cpp}
* IGNITE_EXPORTED_CALL void IgniteModuleInit(ignite::IgniteBindingContext& context)
* {
* IgniteBinding binding = context.GetBingding();
*
* binding.RegisterCacheEntryProcessor<MyProcessor1>();
* binding.RegisterCacheEntryProcessor<MyProcessor2>();
* // ...
* binding.RegisterCacheEntryProcessor<MyProcessorN>();
* }
* @endcode
*
* Additionally, processor class should be derived from the
* ignite::CacheEntryProcessor class.
*
* @throw IgniteError on fail.
*
* @param key The key.
* @param processor The processor.
* @param arg The argument.
* @return Result of the processing.
*/
template<typename R, typename P, typename A>
R Invoke(const K& key, const P& processor, const A& arg)
{
IgniteError err;
R res = Invoke<R>(key, processor, arg, err);
IgniteError::ThrowIfNeeded(err);
return res;
}
/**
* Invokes an CacheEntryProcessor against the MutableCacheEntry
* specified by the provided key. If an entry does not exist for the
* specified key, an attempt is made to load it (if a loader is
* configured) or a surrogate entry, consisting of the key with a
* null value is used instead.
*
* Return value, processor and argument classes should all be
* default-constructable, copy-constructable and assignable. Also,
* BinaryType class template should be specialized for every custom
* class.
*
* Processor class should be registered as a cache entry processor using
* IgniteBinding::RegisterCacheEntryProcessor() method. You can declare
* #IgniteModuleInit() function to register your cache processors upon
* module loading. There should be at most one instance of such function
* per module.
*
* See the example below for details:
* @code{.cpp}
* IGNITE_EXPORTED_CALL void IgniteModuleInit(ignite::IgniteBindingContext& context)
* {
* IgniteBinding binding = context.GetBingding();
*
* binding.RegisterCacheEntryProcessor<MyProcessor1>();
* binding.RegisterCacheEntryProcessor<MyProcessor2>();
* // ...
* binding.RegisterCacheEntryProcessor<MyProcessorN>();
* }
* @endcode
*
* Additionally, processor class should be derived from the
* ignite::CacheEntryProcessor class.
*
* Sets err param which should be checked for the operation result.
*
* @param key The key.
* @param processor The processor.
* @param arg The argument.
* @param err Error.
* @return Result of the processing. Default-constructed value on error.
*/
template<typename R, typename P, typename A>
R Invoke(const K& key, const P& processor, const A& arg, IgniteError& err)
{
typedef impl::cache::CacheEntryProcessorHolder<P, A> ProcessorHolder;
ProcessorHolder procHolder(processor, arg);
impl::In2Operation<K, ProcessorHolder> inOp(key, procHolder);
impl::Out1Operation<R> outOp;
impl.Get()->Invoke(inOp, outOp, err);
return outOp.GetResult();
}
/**
* Start continuous query execution.
*
* @param qry Continuous query.
* @return Continuous query handle.
*/
query::continuous::ContinuousQueryHandle<K, V> QueryContinuous(
const query::continuous::ContinuousQuery<K, V>& qry)
{
IgniteError err;
query::continuous::ContinuousQueryHandle<K, V> res = QueryContinuous(qry, err);
IgniteError::ThrowIfNeeded(err);
return res;
}
/**
* Start continuous query execution.
*
* @param qry Continuous query.
* @param err Error.
* @return Continuous query handle.
*/
query::continuous::ContinuousQueryHandle<K, V> QueryContinuous(
const query::continuous::ContinuousQuery<K, V>& qry, IgniteError& err)
{
using namespace impl::cache::query::continuous;
using namespace common::concurrent;
const SharedPointer<ContinuousQueryImpl<K, V> >& qryImpl = qry.impl;
if (!qryImpl.IsValid() || !qryImpl.Get()->HasListener())
{
err = IgniteError(IgniteError::IGNITE_ERR_GENERIC,
"Event listener is not set for ContinuousQuery instance");
return query::continuous::ContinuousQueryHandle<K, V>();
}
ContinuousQueryHandleImpl* cqImpl = impl.Get()->QueryContinuous(qryImpl, err);
return query::continuous::ContinuousQueryHandle<K, V>(cqImpl);
}
/**
* Start continuous query execution with the initial query.
*
* @param qry Continuous query.
* @param initialQry Initial query to be executed.
* @return Continuous query handle.
*/
template<typename Q>
query::continuous::ContinuousQueryHandle<K, V> QueryContinuous(
const query::continuous::ContinuousQuery<K, V>& qry,
const Q& initialQry)
{
IgniteError err;
query::continuous::ContinuousQueryHandle<K, V> res = QueryContinuous(qry, initialQry, err);
IgniteError::ThrowIfNeeded(err);
return res;
}
/**
* Start continuous query execution with the initial query.
*
* @param qry Continuous query.
* @param initialQry Initial query to be executed.
* @param err Error.
* @return Continuous query handle.
*/
template<typename Q>
query::continuous::ContinuousQueryHandle<K, V> QueryContinuous(
const query::continuous::ContinuousQuery<K, V>& qry,
const Q& initialQry, IgniteError& err)
{
using namespace impl::cache::query::continuous;
using namespace common::concurrent;
const SharedPointer<ContinuousQueryImpl<K, V> >& qryImpl = qry.impl;
if (!qryImpl.IsValid() || !qryImpl.Get()->HasListener())
{
err = IgniteError(IgniteError::IGNITE_ERR_GENERIC,
"Event listener is not set for ContinuousQuery instance");
return query::continuous::ContinuousQueryHandle<K, V>();
}
ContinuousQueryHandleImpl* cqImpl = impl.Get()->QueryContinuous(qryImpl, initialQry, err);
return query::continuous::ContinuousQueryHandle<K, V>(cqImpl);
}
/**
* Check if the instance is valid.
*
* Invalid instance can be returned if some of the previous
* operations have resulted in a failure. For example invalid
* instance can be returned by not-throwing version of method
* in case of error. Invalid instances also often can be
* created using default constructor.
*
* @return True if the instance is valid and can be used.
*/
bool IsValid() const
{
return impl.IsValid();
}
/**
* Executes LocalLoadCache on all cache nodes.
*/
void LoadCache()
{
IgniteError err;
impl.Get()->LoadCache(err);
IgniteError::ThrowIfNeeded(err);
}
/**
* Loads state from the underlying persistent storage.
*
* This method is not transactional and may end up loading a stale value into
* cache if another thread has updated the value immediately after it has been
* loaded. It is mostly useful when pre-loading the cache from underlying
* data store before start, or for read-only caches.
*/
void LocalLoadCache()
{
IgniteError err;
impl.Get()->LocalLoadCache(err);
IgniteError::ThrowIfNeeded(err);
}
private:
/** Implementation delegate. */
common::concurrent::SharedPointer<impl::cache::CacheImpl> impl;
};
}
}
#endif //_IGNITE_CACHE_CACHE