http://git-wip-us.apache.org/repos/asf/ignite/blob/5cec202c/modules/platform/src/main/dotnet/Apache.Ignite.Core/Cache/Event/ICacheEntryEventListener.cs ---------------------------------------------------------------------- diff --git a/modules/platform/src/main/dotnet/Apache.Ignite.Core/Cache/Event/ICacheEntryEventListener.cs b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Cache/Event/ICacheEntryEventListener.cs new file mode 100644 index 0000000..76ae04c --- /dev/null +++ b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Cache/Event/ICacheEntryEventListener.cs @@ -0,0 +1,33 @@ +/* + * 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. + */ + +namespace Apache.Ignite.Core.Cache.Event +{ + using System.Collections.Generic; + + /// <summary> + /// Cache entry event listener. + /// </summary> + public interface ICacheEntryEventListener<TK, TV> + { + /// <summary> + /// Event callback. + /// </summary> + /// <param name="evts">Events.</param> + void OnEvent(IEnumerable<ICacheEntryEvent<TK, TV>> evts); + } +}
http://git-wip-us.apache.org/repos/asf/ignite/blob/5cec202c/modules/platform/src/main/dotnet/Apache.Ignite.Core/Cache/Expiry/ExpiryPolicy.cs ---------------------------------------------------------------------- diff --git a/modules/platform/src/main/dotnet/Apache.Ignite.Core/Cache/Expiry/ExpiryPolicy.cs b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Cache/Expiry/ExpiryPolicy.cs new file mode 100644 index 0000000..1feccbd --- /dev/null +++ b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Cache/Expiry/ExpiryPolicy.cs @@ -0,0 +1,89 @@ +/* + * 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. + */ + +namespace Apache.Ignite.Core.Cache.Expiry +{ + using System; + + /// <summary> + /// Default expiry policy implementation with all durations deinfed explicitly. + /// </summary> + public class ExpiryPolicy : IExpiryPolicy + { + /** Expiry for create. */ + private readonly TimeSpan? _create; + + /** Expiry for update. */ + private readonly TimeSpan? _update; + + /** Expiry for access. */ + private readonly TimeSpan? _access; + + /// <summary> + /// Constructor. + /// </summary> + /// <param name="create">Expiry for create.</param> + /// <param name="update">Expiry for udpate.</param> + /// <param name="access">Expiry for access.</param> + public ExpiryPolicy(TimeSpan? create, TimeSpan? update, TimeSpan? access) + { + _create = create; + _update = update; + _access = access; + } + + /// <summary> + /// Gets expiry for create operation. + /// <para /> + /// If <c>TimeSpan.ZERO</c> is returned, cache entry is considered immediately expired + /// and will not be added to cache. + /// <para /> + /// If <c>null</c> is returned, no change to previously understood expiry is performed. + /// </summary> + /// <returns>Expiry for create opeartion.</returns> + public TimeSpan? GetExpiryForCreate() + { + return _create; + } + + /// <summary> + /// Gets expiry for update operation. + /// <para /> + /// If <c>TimeSpan.ZERO</c> is returned, cache entry is considered immediately expired. + /// <para /> + /// If <c>null</c> is returned, no change to previously understood expiry is performed. + /// </summary> + /// <returns>Expiry for update operation.</returns> + public TimeSpan? GetExpiryForUpdate() + { + return _update; + } + + /// <summary> + /// Gets expiry for access operation. + /// <para /> + /// If <c>TimeSpan.ZERO</c> is returned, cache entry is considered immediately expired. + /// <para /> + /// If <c>null</c> is returned, no change to previously understood expiry is performed. + /// </summary> + /// <returns>Expiry for access operation.</returns> + public TimeSpan? GetExpiryForAccess() + { + return _access; + } + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/5cec202c/modules/platform/src/main/dotnet/Apache.Ignite.Core/Cache/Expiry/IExpiryPolicy.cs ---------------------------------------------------------------------- diff --git a/modules/platform/src/main/dotnet/Apache.Ignite.Core/Cache/Expiry/IExpiryPolicy.cs b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Cache/Expiry/IExpiryPolicy.cs new file mode 100644 index 0000000..ff627ae --- /dev/null +++ b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Cache/Expiry/IExpiryPolicy.cs @@ -0,0 +1,59 @@ +/* + * 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. + */ + +namespace Apache.Ignite.Core.Cache.Expiry +{ + using System; + + /// <summary> + /// Defines functions to determine when cache entries will expire based on + /// creation, access and modification operations. + /// </summary> + public interface IExpiryPolicy + { + /// <summary> + /// Gets expiry for create operation. + /// <para /> + /// If <c>TimeSpan.ZERO</c> is returned, cache entry is considered immediately expired + /// and will not be added to cache. + /// <para /> + /// If <c>null</c> is returned, no change to previously understood expiry is performed. + /// </summary> + /// <returns>Expiry for create opeartion.</returns> + TimeSpan? GetExpiryForCreate(); + + /// <summary> + /// Gets expiry for update operation. + /// <para /> + /// If <c>TimeSpan.ZERO</c> is returned, cache entry is considered immediately expired. + /// <para /> + /// If <c>null</c> is returned, no change to previously understood expiry is performed. + /// </summary> + /// <returns>Expiry for update operation.</returns> + TimeSpan? GetExpiryForUpdate(); + + /// <summary> + /// Gets expiry for access operation. + /// <para /> + /// If <c>TimeSpan.ZERO</c> is returned, cache entry is considered immediately expired. + /// <para /> + /// If <c>null</c> is returned, no change to previously understood expiry is performed. + /// </summary> + /// <returns>Expiry for access operation.</returns> + TimeSpan? GetExpiryForAccess(); + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/5cec202c/modules/platform/src/main/dotnet/Apache.Ignite.Core/Cache/ICache.cs ---------------------------------------------------------------------- diff --git a/modules/platform/src/main/dotnet/Apache.Ignite.Core/Cache/ICache.cs b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Cache/ICache.cs new file mode 100644 index 0000000..3ee812a --- /dev/null +++ b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Cache/ICache.cs @@ -0,0 +1,542 @@ +/* + * 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. + */ + +namespace Apache.Ignite.Core.Cache +{ + using System; + using System.Collections; + using System.Collections.Generic; + using Apache.Ignite.Core.Cache.Expiry; + using Apache.Ignite.Core.Cache.Query; + using Apache.Ignite.Core.Cache.Query.Continuous; + using Apache.Ignite.Core.Cache.Store; + using Apache.Ignite.Core.Common; + using Apache.Ignite.Core.Transactions; + + /// <summary> + /// Main entry point for Ignite cache APIs. You can get a named cache by calling + /// <see cref="IIgnite.Cache{K, V}(string)"/> method. + /// <para /> + /// Cache API supports distributed transactions. All <c>Get(...)</c>, <c>Put(...)</c>, <c>Replace(...)</c>, + /// and <c>Remove(...)</c> operations are transactional and will participate in an ongoing transaction, + /// if any. Other methods like <c>Peek(...)</c> or various <c>Contains(...)</c> methods may + /// be transaction-aware, i.e. check in-transaction entries first, but will not affect the current + /// state of transaction. See <see cref="ITransaction"/> documentation for more information + /// about transactions. + /// <para /> + /// Neither <c>null</c> keys or values are allowed to be stored in cache. If a <c>null</c> value + /// happens to be in cache (e.g. after invalidation or remove), then cache will treat this case + /// as there is no value at all. + /// <para /> + /// Note that cache is generic and you can only work with provided key and value types. If cache also + /// contains keys or values of other types, any attempt to retrieve them will result in + /// <see cref="InvalidCastException"/>. Use <see cref="ICache{Object, Object}"/> in order to work with entries + /// of arbitrary types. + /// <para/> + /// All members are thread-safe and may be used concurrently from multiple threads. + /// </summary> + /// <typeparam name="TK">Key type.</typeparam> + /// <typeparam name="TV">Value type.</typeparam> + public interface ICache<TK, TV> : IAsyncSupport<ICache<TK, TV>>, IEnumerable<ICacheEntry<TK, TV>> + { + /// <summary> + /// Name of this cache (<c>null</c> for default cache). + /// </summary> + string Name { get; } + + /// <summary> + /// Ignite hosting this cache. + /// </summary> + IIgnite Ignite { get; } + + /// <summary> + /// Checks whether this cache contains no key-value mappings. + /// <para /> + /// Semantically equals to <c>ICache.Size(CachePeekMode.PRIMARY) == 0</c>. + /// </summary> + bool IsEmpty { get; } + + /// <summary> + /// Gets a value indicating whether to keep values in portable form. + /// </summary> + bool KeepPortable { get; } + + /// <summary> + /// Get another cache instance with read-through and write-through behavior disabled. + /// </summary> + /// <returns>Cache with read-through and write-through behavior disabled.</returns> + ICache<TK, TV> WithSkipStore(); + + /// <summary> + /// Returns cache with the specified expired policy set. This policy will be used for each operation + /// invoked on the returned cache. + /// <para /> + /// Expiry durations for each operation are calculated only once and then used as constants. Please + /// consider this when implementing customg expiry policy implementations. + /// </summary> + /// <param name="plc">Expiry policy to use.</param> + /// <returns>Cache instance with the specified expiry policy set.</returns> + ICache<TK, TV> WithExpiryPolicy(IExpiryPolicy plc); + + /// <summary> + /// Gets cache with KeepPortable mode enabled, changing key and/or value types if necessary. + /// You can only change key/value types when transitioning from non-portable to portable cache; + /// Changing type of portable cache is not allowed and will throw an <see cref="InvalidOperationException"/> + /// </summary> + /// <typeparam name="TK1">Key type in portable mode.</typeparam> + /// <typeparam name="TV1">Value type in protable mode.</typeparam> + /// <returns>Cache instance with portable mode enabled.</returns> + ICache<TK1, TV1> WithKeepPortable<TK1, TV1>(); + + /// <summary> + /// Executes <see cref="LocalLoadCache"/> on all cache nodes. + /// </summary> + /// <param name="p"> + /// Optional predicate. If provided, will be used to filter values to be put into cache. + /// </param> + /// <param name="args"> + /// Optional user arguments to be passed into <see cref="ICacheStore.LoadCache" />. + /// </param> + [AsyncSupported] + void LoadCache(ICacheEntryFilter<TK, TV> p, params object[] args); + + /// <summary> + /// Delegates to <see cref="ICacheStore.LoadCache" /> method to load state + /// from the underlying persistent storage. The loaded values will then be given + /// to the optionally passed in predicate, and, if the predicate returns true, + /// will be stored in cache. If predicate is null, then all loaded values will be stored in cache. + /// </summary> + /// <param name="p"> + /// Optional predicate. If provided, will be used to filter values to be put into cache. + /// </param> + /// <param name="args"> + /// Optional user arguments to be passed into <see cref="ICacheStore.LoadCache" />. + /// </param> + [AsyncSupported] + void LocalLoadCache(ICacheEntryFilter<TK, TV> p, params object[] args); + + /// <summary> + /// Check if cache contains mapping for this key. + /// </summary> + /// <param name="key">Key.</param> + /// <returns>True if cache contains mapping for this key.</returns> + [AsyncSupported] + bool ContainsKey(TK key); + + /// <summary> + /// Check if cache contains mapping for these keys. + /// </summary> + /// <param name="keys">Keys.</param> + /// <returns>True if cache contains mapping for all these keys.</returns> + [AsyncSupported] + bool ContainsKeys(IEnumerable<TK> keys); + + /// <summary> + /// 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. + /// </summary> + /// <param name="key">Key.</param> + /// <param name="modes">Peek modes.</param> + /// <returns>Peeked value.</returns> + TV LocalPeek(TK key, params CachePeekMode[] modes); + + /// <summary> + /// 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 disable, 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. + /// </summary> + /// <param name="key">Key.</param> + /// <returns>Value.</returns> + [AsyncSupported] + TV Get(TK key); + + /// <summary> + /// 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. + /// </summary> + /// <param name="keys">Keys.</param> + /// <returns>Map of key-value pairs.</returns> + [AsyncSupported] + IDictionary<TK, TV> GetAll(IEnumerable<TK> keys); + + /// <summary> + /// Associates the specified value with the specified key in the cache. + /// <para /> + /// If the cache previously contained a mapping for the key, + /// the old value is replaced by the specified value. + /// </summary> + /// <param name="key">Key with which the specified value is to be associated.</param> + /// <param name="val">Value to be associated with the specified key.</param> + [AsyncSupported] + void Put(TK key, TV val); + + /// <summary> + /// Associates the specified value with the specified key in this cache, + /// returning an existing value if one existed. + /// </summary> + /// <param name="key">Key with which the specified value is to be associated.</param> + /// <param name="val">Value to be associated with the specified key.</param> + /// <returns> + /// The value associated with the key at the start of the operation or null if none was associated. + /// </returns> + [AsyncSupported] + TV GetAndPut(TK key, TV val); + + /// <summary> + /// Atomically replaces the value for a given key if and only if there is a value currently mapped by the key. + /// </summary> + /// <param name="key">Key with which the specified value is to be associated.</param> + /// <param name="val">Value to be associated with the specified key.</param> + /// <returns> + /// The previous value associated with the specified key, or null if there was no mapping for the key. + /// </returns> + [AsyncSupported] + TV GetAndReplace(TK key, TV val); + + /// <summary> + /// Atomically removes the entry for a key only if currently mapped to some value. + /// </summary> + /// <param name="key">Key with which the specified value is associated.</param> + /// <returns>The value if one existed or null if no mapping existed for this key.</returns> + [AsyncSupported] + TV GetAndRemove(TK key); + + /// <summary> + /// Atomically associates the specified key with the given value if it is not already associated with a value. + /// </summary> + /// <param name="key">Key with which the specified value is to be associated.</param> + /// <param name="val">Value to be associated with the specified key.</param> + /// <returns>True if a value was set.</returns> + [AsyncSupported] + bool PutIfAbsent(TK key, TV val); + + /// <summary> + /// 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. + /// </summary> + /// <param name="key">Key to store in cache.</param> + /// <param name="val">Value to be associated with the given key.</param> + /// <returns> + /// Previously contained value regardless of whether put happened or not (null if there was no previous value). + /// </returns> + [AsyncSupported] + TV GetAndPutIfAbsent(TK key, TV val); + + /// <summary> + /// 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. + /// </summary> + /// <param name="key">Key to store in cache.</param> + /// <param name="val">Value to be associated with the given key.</param> + /// <returns>True if the value was replaced.</returns> + [AsyncSupported] + bool Replace(TK key, TV val); + + /// <summary> + /// 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. + /// </summary> + /// <param name="key">Key to store in cache.</param> + /// <param name="oldVal">Old value to match.</param> + /// <param name="newVal">Value to be associated with the given key.</param> + /// <returns>True if replace happened, false otherwise.</returns> + [AsyncSupported] + bool Replace(TK key, TV oldVal, TV newVal); + + /// <summary> + /// 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. + /// </summary> + /// <param name="vals">Key-value pairs to store in cache.</param> + [AsyncSupported] + void PutAll(IDictionary<TK, TV> vals); + + /// <summary> + /// Attempts to evict all entries associated with keys. Note, that entry will be evicted only + /// if it's not used (not participating in any locks or transactions). + /// </summary> + /// <param name="keys">Keys to evict from cache.</param> + void LocalEvict(IEnumerable<TK> keys); + + /// <summary> + /// Clears the contents of the cache, without notifying listeners or CacheWriters. + /// </summary> + [AsyncSupported] + void Clear(); + + /// <summary> + /// 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. + /// </summary> + /// <param name="key">Key to clear.</param> + [AsyncSupported] + void Clear(TK key); + + /// <summary> + /// 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. + /// </summary> + /// <param name="keys">Keys to clear.</param> + [AsyncSupported] + void ClearAll(IEnumerable<TK> keys); + + /// <summary> + /// 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. + /// <para /> + /// Note that this operation is local as it merely clears + /// an entry from local cache, it does not remove entries from remote caches. + /// </summary> + /// <param name="key">Key to clear.</param> + void LocalClear(TK key); + + /// <summary> + /// 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. + /// <para /> + /// Note that this operation is local as it merely clears + /// entries from local cache, it does not remove entries from remote caches. + /// </summary> + /// <param name="keys">Keys to clear.</param> + void LocalClearAll(IEnumerable<TK> keys); + + /// <summary> + /// 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. + /// </summary> + /// <param name="key">Key whose mapping is to be removed from cache.</param> + /// <returns>False if there was no matching key.</returns> + [AsyncSupported] + bool Remove(TK key); + + /// <summary> + /// 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. + /// </summary> + /// <param name="key">Key whose mapping is to be removed from cache.</param> + /// <param name="val">Value to match against currently cached value.</param> + /// <returns>True if entry was removed, false otherwise.</returns> + [AsyncSupported] + bool Remove(TK key, TV val); + + /// <summary> + /// 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. + /// </summary> + /// <param name="keys">Keys whose mappings are to be removed from cache.</param> + [AsyncSupported] + void RemoveAll(IEnumerable<TK> keys); + + /// <summary> + /// 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. + /// </summary> + [AsyncSupported] + void RemoveAll(); + + /// <summary> + /// Gets the number of all entries cached on this node. + /// </summary> + /// <param name="modes">Optional peek modes. If not provided, then total cache size is returned.</param> + /// <returns>Cache size on this node.</returns> + int LocalSize(params CachePeekMode[] modes); + + /// <summary> + /// Gets the number of all entries cached across all nodes. + /// <para /> + /// NOTE: this operation is distributed and will query all participating nodes for their cache sizes. + /// </summary> + /// <param name="modes">Optional peek modes. If not provided, then total cache size is returned.</param> + /// <returns>Cache size across all nodes.</returns> + [AsyncSupported] + int Size(params CachePeekMode[] modes); + + /// <summary> + /// This method unswaps cache entries by given keys, if any, from swap storage into memory. + /// </summary> + /// <param name="keys">Keys to promote entries for.</param> + void LocalPromote(IEnumerable<TK> keys); + + /// <summary> + /// Queries cache. + /// </summary> + /// <param name="qry">Query.</param> + /// <returns>Cursor.</returns> + IQueryCursor<ICacheEntry<TK, TV>> Query(QueryBase qry); + + /// <summary> + /// Queries separate entry fields. + /// </summary> + /// <param name="qry">SQL fields query.</param> + /// <returns>Cursor.</returns> + IQueryCursor<IList> QueryFields(SqlFieldsQuery qry); + + /// <summary> + /// Start continuous query execution. + /// </summary> + /// <param name="qry">Continuous query.</param> + /// <returns>Handle to stop query execution.</returns> + IContinuousQueryHandle QueryContinuous(ContinuousQuery<TK, TV> qry); + + /// <summary> + /// Start continuous query execution. + /// </summary> + /// <param name="qry">Continuous query.</param> + /// <param name="initialQry"> + /// The initial query. This query will be executed before continuous listener is registered which allows + /// to iterate through entries which have already existed at the time continuous query is executed. + /// </param> + /// <returns> + /// Handle to get initial query cursor or stop query execution. + /// </returns> + IContinuousQueryHandle<ICacheEntry<TK, TV>> QueryContinuous(ContinuousQuery<TK, TV> qry, QueryBase initialQry); + + /// <summary> + /// Get local cache entries. + /// </summary> + /// <param name="peekModes">Peek modes.</param> + /// <returns>Enumerable instance.</returns> + IEnumerable<ICacheEntry<TK, TV>> GetLocalEntries(params CachePeekMode[] peekModes); + + /// <summary> + /// Invokes an <see cref="ICacheEntryProcessor{K, V, A, R}"/> against the + /// <see cref="IMutableCacheEntry{K, V}"/> 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. + /// </summary> + /// <typeparam name="TR">The type of the result.</typeparam> + /// <typeparam name="TA">The type of the argument.</typeparam> + /// <param name="key">The key.</param> + /// <param name="processor">The processor.</param> + /// <param name="arg">The argument.</param> + /// <returns>Result of the processing.</returns> + /// <exception cref="CacheEntryProcessorException">If an exception has occured during processing.</exception> + [AsyncSupported] + TR Invoke<TR, TA>(TK key, ICacheEntryProcessor<TK, TV, TA, TR> processor, TA arg); + + /// <summary> + /// Invokes an <see cref="ICacheEntryProcessor{K, V, A, R}"/> against a set of keys. + /// 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. + /// + /// The order that the entries for the keys are processed is undefined. + /// Implementations may choose to process the entries in any order, including concurrently. + /// Furthermore there is no guarantee implementations will use the same processor instance + /// to process each entry, as the case may be in a non-local cache topology. + /// </summary> + /// <typeparam name="TR">The type of the result.</typeparam> + /// <typeparam name="TA">The type of the argument.</typeparam> + /// <param name="keys">The keys.</param> + /// <param name="processor">The processor.</param> + /// <param name="arg">The argument.</param> + /// <returns> + /// Map of <see cref="ICacheEntryProcessorResult{R}" /> of the processing per key, if any, + /// defined by the <see cref="ICacheEntryProcessor{K,V,A,R}"/> implementation. + /// No mappings will be returned for processors that return a null value for a key. + /// </returns> + /// <exception cref="CacheEntryProcessorException">If an exception has occured during processing.</exception> + [AsyncSupported] + IDictionary<TK, ICacheEntryProcessorResult<TR>> InvokeAll<TR, TA>(IEnumerable<TK> keys, + ICacheEntryProcessor<TK, TV, TA, TR> processor, TA arg); + + /// <summary> + /// Creates an <see cref="ICacheLock"/> instance associated with passed key. + /// This method does not acquire lock immediately, you have to call appropriate method on returned instance. + /// </summary> + /// <param name="key">Key for lock.</param> + /// <returns>New <see cref="ICacheLock"/> instance associated with passed key.</returns> + ICacheLock Lock(TK key); + + /// <summary> + /// Creates an <see cref="ICacheLock"/> instance associated with passed keys. + /// This method does not acquire lock immediately, you have to call appropriate method on returned instance. + /// </summary> + /// <param name="keys">Keys for lock.</param> + /// <returns>New <see cref="ICacheLock"/> instance associated with passed keys.</returns> + ICacheLock LockAll(IEnumerable<TK> keys); + + /// <summary> + /// Checks if specified key is locked. + /// <para /> + /// This is a local operation and does not involve any network trips + /// or access to persistent storage in any way. + /// </summary> + /// <param name="key">Key to check.</param> + /// <param name="byCurrentThread"> + /// If true, checks that current thread owns a lock on this key; + /// otherwise, checks that any thread on any node owns a lock on this key. + /// </param> + /// <returns>True if specified key is locked; otherwise, false.</returns> + bool IsLocalLocked(TK key, bool byCurrentThread); + + /// <summary> + /// Gets snapshot metrics (statistics) for this cache. + /// </summary> + /// <returns>Cache metrics.</returns> + ICacheMetrics GetMetrics(); + + /// <summary> + /// Rebalances cache partitions. This method is usually used when rebalanceDelay configuration parameter + /// has non-zero value. When many nodes are started or stopped almost concurrently, + /// it is more efficient to delay rebalancing until the node topology is stable to make sure that no redundant + /// re-partitioning happens. + /// <para /> + /// In case of partitioned caches, for better efficiency user should usually make sure that new nodes get + /// placed on the same place of consistent hash ring as the left nodes, and that nodes are restarted before + /// rebalanceDelay expires. + /// </summary> + /// <returns>Future that will be completed when rebalancing is finished.</returns> + IFuture Rebalance(); + + /// <summary> + /// Get another cache instance with no-retries behavior enabled. + /// </summary> + /// <returns>Cache with no-retries behavior enabled.</returns> + ICache<TK, TV> WithNoRetries(); + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/5cec202c/modules/platform/src/main/dotnet/Apache.Ignite.Core/Cache/ICacheAffinity.cs ---------------------------------------------------------------------- diff --git a/modules/platform/src/main/dotnet/Apache.Ignite.Core/Cache/ICacheAffinity.cs b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Cache/ICacheAffinity.cs new file mode 100644 index 0000000..03a4e50 --- /dev/null +++ b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Cache/ICacheAffinity.cs @@ -0,0 +1,161 @@ +/* + * 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. + */ + +namespace Apache.Ignite.Core.Cache +{ + using System.Collections.Generic; + using Apache.Ignite.Core.Cluster; + + /// <summary> + /// Provides affinity information to detect which node is primary and which nodes are + /// backups for a partitioned cache. You can get an instance of this interface by calling + /// <see cref="IIgnite.Affinity(string)"/> method. + /// <para /> + /// Mapping of a key to a node is a three-step operation. First step will get an affinity key for + /// given key using <c>CacheAffinityKeyMapper</c>. If mapper is not specified, the original key + /// will be used. Second step will map affinity key to partition using + /// <c>CacheAffinityFunction.partition(Object)</c> method. Third step will map obtained partition + /// to nodes for current grid topology version. + /// <para /> + /// Interface provides various <c>mapKeysToNodes(...)</c> methods which provide node affinity mapping + /// for given keys. All <c>mapKeysToNodes(...)</c> methods are not transactional and will not enlist + /// keys into ongoing transaction. + /// <para/> + /// All members are thread-safe and may be used concurrently from multiple threads. + /// </summary> + public interface ICacheAffinity + { + /// <summary> + /// Gets number of partitions in cache according to configured affinity function. + /// </summary> + /// <returns>Number of cache partitions.</returns> + int Partitions + { + get; + } + + /// <summary> + /// Gets partition id for the given key. + /// </summary> + /// <param name="key">Key to get partition id for.</param> + /// <returns>Partition id.</returns> + int Partition<TK>(TK key); + + /// <summary> + /// Returns 'true' if given node is the primary node for given key. + /// </summary> + /// <param name="n">Node.</param> + /// <param name="key">Key.</param> + /// <returns>'True' if given node is the primary node for given key.</returns> + bool IsPrimary<TK>(IClusterNode n, TK key); + + /// <summary> + /// Returns 'true' if given node is the backup node for given key. + /// </summary> + /// <param name="n">Node.</param> + /// <param name="key">Key.</param> + /// <returns>'True' if given node is the backup node for given key.</returns> + bool IsBackup<TK>(IClusterNode n, TK key); + + /// <summary> + /// Returns 'true' if given node is either primary or backup node for given key. + /// </summary> + /// <param name="n">Node.</param> + /// <param name="key">Key.</param> + /// <returns>'True' if given node is either primary or backup node for given key.</returns> + bool IsPrimaryOrBackup<TK>(IClusterNode n, TK key); + + /// <summary> + /// Gets partition ids for which nodes of the given projection has primary + /// ownership. + /// </summary> + /// <param name="n">Node.</param> + /// <returns>Partition ids for which given projection has primary ownership.</returns> + int[] PrimaryPartitions(IClusterNode n); + + /// <summary> + /// Gets partition ids for which nodes of the given projection has backup + /// ownership. + /// </summary> + /// <param name="n">Node.</param> + /// <returns>Partition ids for which given projection has backup ownership.</returns> + int[] BackupPartitions(IClusterNode n); + + /// <summary> + /// Gets partition ids for which nodes of the given projection has ownership + /// (either primary or backup). + /// </summary> + /// <param name="n">Node.</param> + /// <returns>Partition ids for which given projection has ownership.</returns> + int[] AllPartitions(IClusterNode n); + + /// <summary> + /// Maps passed in key to a key which will be used for node affinity. + /// </summary> + /// <param name="key">Key to map.</param> + /// <returns>Key to be used for node-to-affinity mapping (may be the same key as passed in).</returns> + TR AffinityKey<TK, TR>(TK key); + + /// <summary> + /// This method provides ability to detect which keys are mapped to which nodes. + /// Use it to determine which nodes are storing which keys prior to sending + /// jobs that access these keys. + /// </summary> + /// <param name="keys">Keys to map to nodes.</param> + /// <returns>Map of nodes to keys or empty map if there are no alive nodes for this cache.</returns> + IDictionary<IClusterNode, IList<TK>> MapKeysToNodes<TK>(IList<TK> keys); + + /// <summary> + /// This method provides ability to detect to which primary node the given key + /// is mapped. Use it to determine which nodes are storing which keys prior to sending + /// jobs that access these keys. + /// </summary> + /// <param name="key">Keys to map to a node.</param> + /// <returns>Primary node for the key or null if there are no alive nodes for this cache.</returns> + IClusterNode MapKeyToNode<TK>(TK key); + + /// <summary> + /// Gets primary and backup nodes for the key. Note that primary node is always + /// first in the returned collection. + /// </summary> + /// <param name="key"></param> + /// <returns></returns> + IList<IClusterNode> MapKeyToPrimaryAndBackups<TK>(TK key); + + /// <summary> + /// Gets primary node for the given partition. + /// </summary> + /// <param name="part">Partition id.</param> + /// <returns>Primary node for the given partition.</returns> + IClusterNode MapPartitionToNode(int part); + + /// <summary> + /// Gets primary nodes for the given partitions. + /// </summary> + /// <param name="parts">Partition ids.</param> + /// <returns>Mapping of given partitions to their primary nodes.</returns> + IDictionary<int, IClusterNode> MapPartitionsToNodes(IList<int> parts); + + /// <summary> + /// Gets primary and backup nodes for partition. Note that primary node is always + /// first in the returned collection. + /// </summary> + /// <param name="part">Partition to get affinity nodes for.</param> + /// <returns>Collection of primary and backup nodes for partition with primary node always first</returns> + IList<IClusterNode> MapPartitionToPrimaryAndBackups(int part); + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/5cec202c/modules/platform/src/main/dotnet/Apache.Ignite.Core/Cache/ICacheEntry.cs ---------------------------------------------------------------------- diff --git a/modules/platform/src/main/dotnet/Apache.Ignite.Core/Cache/ICacheEntry.cs b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Cache/ICacheEntry.cs new file mode 100644 index 0000000..49ebfec --- /dev/null +++ b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Cache/ICacheEntry.cs @@ -0,0 +1,37 @@ +/* + * 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. + */ + +namespace Apache.Ignite.Core.Cache +{ + /// <summary> + /// Cache entry interface. + /// </summary> + /// <typeparam name="TK">Key type.</typeparam> + /// <typeparam name="TV">Value type.</typeparam> + public interface ICacheEntry<out TK, out TV> + { + /// <summary> + /// Gets the key. + /// </summary> + TK Key { get; } + + /// <summary> + /// Gets the value. + /// </summary> + TV Value { get; } + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/5cec202c/modules/platform/src/main/dotnet/Apache.Ignite.Core/Cache/ICacheEntryFilter.cs ---------------------------------------------------------------------- diff --git a/modules/platform/src/main/dotnet/Apache.Ignite.Core/Cache/ICacheEntryFilter.cs b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Cache/ICacheEntryFilter.cs new file mode 100644 index 0000000..9c7ee88 --- /dev/null +++ b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Cache/ICacheEntryFilter.cs @@ -0,0 +1,34 @@ +/* + * 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. + */ + +namespace Apache.Ignite.Core.Cache +{ + /// <summary> + /// Cache entry predicate. + /// </summary> + /// <typeparam name="TK">Key type.</typeparam> + /// <typeparam name="TV">Value type.</typeparam> + public interface ICacheEntryFilter<in TK, in TV> + { + /// <summary> + /// Returns a value indicating whether provided cache entry satisfies this predicate. + /// </summary> + /// <param name="entry">Cache entry.</param> + /// <returns>Value indicating whether provided cache entry satisfies this predicate.</returns> + bool Invoke(ICacheEntry<TK, TV> entry); + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ignite/blob/5cec202c/modules/platform/src/main/dotnet/Apache.Ignite.Core/Cache/ICacheEntryProcessor.cs ---------------------------------------------------------------------- diff --git a/modules/platform/src/main/dotnet/Apache.Ignite.Core/Cache/ICacheEntryProcessor.cs b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Cache/ICacheEntryProcessor.cs new file mode 100644 index 0000000..c8614c0 --- /dev/null +++ b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Cache/ICacheEntryProcessor.cs @@ -0,0 +1,45 @@ +/* + * 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. + */ + +namespace Apache.Ignite.Core.Cache +{ + /// <summary> + /// An invocable function that allows applications to perform compound operations + /// on a cache entry atomically, according the defined consistency of a cache. + /// <para /> + /// Any cache entry mutations will not take effect until after + /// the <see cref="Process" /> method has completedS execution. + /// <para /> + /// If an exception is thrown by an entry processor, a Caching Implementation + /// must wrap any exception thrown wrapped in an <see cref="CacheEntryProcessorException" /> + /// If this occurs no mutations will be made to the cache entry. + /// </summary> + /// <typeparam name="TK">Key type.</typeparam> + /// <typeparam name="TV">Value type.</typeparam> + /// <typeparam name="TA">The type of the processor argument.</typeparam> + /// <typeparam name="TR">The type of the processor result.</typeparam> + public interface ICacheEntryProcessor<in TK, TV, in TA, out TR> + { + /// <summary> + /// Process an entry. + /// </summary> + /// <param name="entry">The entry to process.</param> + /// <param name="arg">The argument.</param> + /// <returns>Processing result.</returns> + TR Process(IMutableCacheEntry<TK, TV> entry, TA arg); + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ignite/blob/5cec202c/modules/platform/src/main/dotnet/Apache.Ignite.Core/Cache/ICacheEntryProcessorResult.cs ---------------------------------------------------------------------- diff --git a/modules/platform/src/main/dotnet/Apache.Ignite.Core/Cache/ICacheEntryProcessorResult.cs b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Cache/ICacheEntryProcessorResult.cs new file mode 100644 index 0000000..2d0f709 --- /dev/null +++ b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Cache/ICacheEntryProcessorResult.cs @@ -0,0 +1,40 @@ +/* + * 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. + */ + +namespace Apache.Ignite.Core.Cache +{ + /// <summary> + /// Represents a result of processing <see cref="ICacheEntry{K, V}"/> + /// by <see cref="ICacheEntryProcessor{K, V, A, R}"/>. + /// </summary> + /// <typeparam name="T">Processor result type.</typeparam> + public interface ICacheEntryProcessorResult<out T> + { + /// <summary> + /// Gets the result of processing an entry. + /// <para /> + /// If an exception was thrown during the processing of an entry, + /// either by the <see cref="ICacheEntryProcessor{K, V, A, R}"/> itself + /// or by the Caching implementation, the exceptions will be wrapped and re-thrown as a + /// <see cref="CacheEntryProcessorException"/> when calling this property. + /// </summary> + /// <value> + /// The result. + /// </value> + T Result { get; } + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ignite/blob/5cec202c/modules/platform/src/main/dotnet/Apache.Ignite.Core/Cache/ICacheLock.cs ---------------------------------------------------------------------- diff --git a/modules/platform/src/main/dotnet/Apache.Ignite.Core/Cache/ICacheLock.cs b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Cache/ICacheLock.cs new file mode 100644 index 0000000..a930961 --- /dev/null +++ b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Cache/ICacheLock.cs @@ -0,0 +1,58 @@ +/* + * 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. + */ + +namespace Apache.Ignite.Core.Cache +{ + using System; + using System.Threading; + + /// <summary> + /// Cache locking interface. + /// <para/> + /// All members are thread-safe and may be used concurrently from multiple threads. + /// </summary> + public interface ICacheLock : IDisposable + { + /// <summary> + /// Acquires an exclusive lock. + /// </summary> + void Enter(); + + /// <summary> + /// Acquires an exclusive lock only if it is free at the time of invocation. + /// </summary> + /// <returns>True if the current thread acquires the lock; otherwise, false.</returns> + bool TryEnter(); + + /// <summary> + /// Attempts, for the specified amount of time, to acquire an exclusive lock. + /// </summary> + /// <param name="timeout"> + /// A <see cref="TimeSpan" /> representing the amount of time to wait for the lock. + /// A value of â1 millisecond specifies an infinite wait. + /// </param> + /// <returns>True if the current thread acquires the lock; otherwise, false.</returns> + bool TryEnter(TimeSpan timeout); + + /// <summary> + /// Releases an exclusive lock on the specified object. + /// <see cref="IDisposable.Dispose"/> does not call this method and will throw + /// <see cref="SynchronizationLockException"/> if this lock is acquired. + /// </summary> + void Exit(); + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ignite/blob/5cec202c/modules/platform/src/main/dotnet/Apache.Ignite.Core/Cache/ICacheMetrics.cs ---------------------------------------------------------------------- diff --git a/modules/platform/src/main/dotnet/Apache.Ignite.Core/Cache/ICacheMetrics.cs b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Cache/ICacheMetrics.cs new file mode 100644 index 0000000..3405625 --- /dev/null +++ b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Cache/ICacheMetrics.cs @@ -0,0 +1,486 @@ +/* + * 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. + */ + +namespace Apache.Ignite.Core.Cache +{ + /// <summary> + /// Cache metrics used to obtain statistics on cache itself. + /// </summary> + public interface ICacheMetrics + { + /// <summary> + /// The number of get requests that were satisfied by the cache. + /// </summary> + /// <returns> + /// The number of hits + /// </returns> + long CacheHits { get; } + + /// <summary> + /// This is a measure of cache efficiency. + /// </summary> + /// <returns> + /// The percentage of successful hits, as a decimal e.g 75. + /// </returns> + float CacheHitPercentage { get; } + + /// <summary> + /// A miss is a get request that is not satisfied. + /// </summary> + /// <returns> + /// The number of misses + /// </returns> + long CacheMisses { get; } + + /// <summary> + /// Returns the percentage of cache accesses that did not find a requested entry in the cache. + /// </summary> + /// <returns> + /// The percentage of accesses that failed to find anything. + /// </returns> + float CacheMissPercentage { get; } + + /// <summary> + /// The total number of requests to the cache. This will be equal to the sum of the hits and misses. + /// </summary> + /// <returns> + /// The number of gets. + /// </returns> + long CacheGets { get; } + + /// <summary> + /// The total number of puts to the cache. + /// </summary> + /// <returns> + /// The number of puts. + /// </returns> + long CachePuts { get; } + + /// <summary> + /// The total number of removals from the cache. This does not include evictions, where the cache itself + /// initiates the removal to make space. + /// </summary> + /// <returns> + /// The number of removals. + /// </returns> + long CacheRemovals { get; } + + /// <summary> + /// The total number of evictions from the cache. An eviction is a removal initiated by the cache itself + /// to free up space. An eviction is not treated as a removal and does not appear in the removal counts. + /// </summary> + /// <returns> + /// The number of evictions. + /// </returns> + long CacheEvictions { get; } + + /// <summary> + /// The mean time to execute gets. + /// </summary> + /// <returns> + /// The time in �s. + /// </returns> + float AverageGetTime { get; } + + /// <summary> + /// The mean time to execute puts. + /// </summary> + /// <returns> + /// The time in �s. + /// </returns> + float AveragePutTime { get; } + + /// <summary> + /// The mean time to execute removes. + /// </summary> + /// <returns> + /// The time in �s. + /// </returns> + float AverageRemoveTime { get; } + + /// <summary> + /// The mean time to execute tx commit. + /// </summary> + /// <returns> + /// The time in �s. + /// </returns> + float AverageTxCommitTime { get; } + + /// <summary> + /// The mean time to execute tx rollbacks. + /// </summary> + /// <returns> + /// Number of transaction rollbacks. + /// </returns> + float AverageTxRollbackTime { get; } + + /// <summary> + /// Gets total number of transaction commits. + /// </summary> + /// <returns> + /// Number of transaction commits. + /// </returns> + long CacheTxCommits { get; } + + /// <summary> + /// Gets total number of transaction rollbacks. + /// </summary> + /// <returns> + /// Number of transaction rollbacks. + /// </returns> + long CacheTxRollbacks { get; } + + /// <summary> + /// Gets cache name. + /// </summary> + /// <returns> + /// Cache name. + /// </returns> + string CacheName { get; } + + /// <summary> + /// Gets number of entries that was swapped to disk. + /// </summary> + /// <returns> + /// Number of entries that was swapped to disk. + /// </returns> + long OverflowSize { get; } + + /// <summary> + /// Gets number of entries stored in off-heap memory. + /// </summary> + /// <returns> + /// Number of entries stored in off-heap memory. + /// </returns> + long OffHeapEntriesCount { get; } + + /// <summary> + /// Gets memory size allocated in off-heap. + /// </summary> + /// <returns> + /// Memory size allocated in off-heap. + /// </returns> + long OffHeapAllocatedSize { get; } + + /// <summary> + /// Gets number of non-null values in the cache. + /// </summary> + /// <returns> + /// Number of non-null values in the cache. + /// </returns> + int Size { get; } + + /// <summary> + /// Gets number of keys in the cache, possibly with null values. + /// </summary> + /// <returns> + /// Number of keys in the cache. + /// </returns> + int KeySize { get; } + + /// <summary> + /// Returns true if this cache is empty. + /// </summary> + /// <returns> + /// True if this cache is empty. + /// </returns> + bool IsEmpty { get; } + + /// <summary> + /// Gets current size of evict queue used to batch up evictions. + /// </summary> + /// <returns> + /// Current size of evict queue. + /// </returns> + int DhtEvictQueueCurrentSize { get; } + + /// <summary> + /// Gets transaction per-thread map size. + /// </summary> + /// <returns> + /// Thread map size. + /// </returns> + int TxThreadMapSize { get; } + + /// <summary> + /// Gets transaction per-Xid map size. + /// </summary> + /// <returns> + /// Transaction per-Xid map size. + /// </returns> + int TxXidMapSize { get; } + + /// <summary> + /// Gets committed transaction queue size. + /// </summary> + /// <returns> + /// Committed transaction queue size. + /// </returns> + int TxCommitQueueSize { get; } + + /// <summary> + /// Gets prepared transaction queue size. + /// </summary> + /// <returns> + /// Prepared transaction queue size. + /// </returns> + int TxPrepareQueueSize { get; } + + /// <summary> + /// Gets start version counts map size. + /// </summary> + /// <returns> + /// Start version counts map size. + /// </returns> + int TxStartVersionCountsSize { get; } + + /// <summary> + /// Gets number of cached committed transaction IDs. + /// </summary> + /// <returns> + /// Number of cached committed transaction IDs. + /// </returns> + int TxCommittedVersionsSize { get; } + + /// <summary> + /// Gets number of cached rolled back transaction IDs. + /// </summary> + /// <returns> + /// Number of cached rolled back transaction IDs. + /// </returns> + int TxRolledbackVersionsSize { get; } + + /// <summary> + /// Gets transaction DHT per-thread map size. + /// </summary> + /// <returns> + /// DHT thread map size. + /// </returns> + int TxDhtThreadMapSize { get; } + + /// <summary> + /// Gets transaction DHT per-Xid map size. + /// </summary> + /// <returns> + /// Transaction DHT per-Xid map size. + /// </returns> + int TxDhtXidMapSize { get; } + + /// <summary> + /// Gets committed DHT transaction queue size. + /// </summary> + /// <returns> + /// Committed DHT transaction queue size. + /// </returns> + int TxDhtCommitQueueSize { get; } + + /// <summary> + /// Gets prepared DHT transaction queue size. + /// </summary> + /// <returns> + /// Prepared DHT transaction queue size. + /// </returns> + int TxDhtPrepareQueueSize { get; } + + /// <summary> + /// Gets DHT start version counts map size. + /// </summary> + /// <returns> + /// DHT start version counts map size. + /// </returns> + int TxDhtStartVersionCountsSize { get; } + + /// <summary> + /// Gets number of cached committed DHT transaction IDs. + /// </summary> + /// <returns> + /// Number of cached committed DHT transaction IDs. + /// </returns> + int TxDhtCommittedVersionsSize { get; } + + /// <summary> + /// Gets number of cached rolled back DHT transaction IDs. + /// </summary> + /// <returns> + /// Number of cached rolled back DHT transaction IDs. + /// </returns> + int TxDhtRolledbackVersionsSize { get; } + + /// <summary> + /// Returns true if write-behind is enabled. + /// </summary> + /// <returns> + /// True if write-behind is enabled. + /// </returns> + bool IsWriteBehindEnabled { get; } + + /// <summary> + /// Gets the maximum size of the write-behind buffer. When the count of unique keys in write buffer exceeds + /// this value, the buffer is scheduled for write to the underlying store. + /// <para /> + /// If this value is 0, then flush is performed only on time-elapsing basis. + /// </summary> + /// <returns> + /// Buffer size that triggers flush procedure. + /// </returns> + int WriteBehindFlushSize { get; } + + /// <summary> + /// Gets the number of flush threads that will perform store update operations. + /// </summary> + /// <returns> + /// Count of worker threads. + /// </returns> + int WriteBehindFlushThreadCount { get; } + + /// <summary> + /// Gets the cache flush frequency. All pending operations on the underlying store will be performed + /// within time interval not less then this value. + /// <para /> If this value is 0, then flush is performed only when buffer size exceeds flush size. + /// </summary> + /// <returns> + /// Flush frequency in milliseconds. + /// </returns> + long WriteBehindFlushFrequency { get; } + + /// <summary> + /// Gets the maximum count of similar (put or remove) operations that can be grouped to a single batch. + /// </summary> + /// <returns> + /// Maximum size of batch. + /// </returns> + int WriteBehindStoreBatchSize { get; } + + /// <summary> + /// Gets count of write buffer overflow events since initialization. + /// Each overflow event causes the ongoing flush operation to be performed synchronously. + /// </summary> + /// <returns> + /// Count of cache overflow events since start. + /// </returns> + int WriteBehindTotalCriticalOverflowCount { get; } + + /// <summary> + /// Gets count of write buffer overflow events in progress at the moment. + /// Each overflow event causes the ongoing flush operation to be performed synchronously. + /// </summary> + /// <returns> + /// Count of cache overflow events since start. + /// </returns> + int WriteBehindCriticalOverflowCount { get; } + + /// <summary> + /// Gets count of cache entries that are in a store-retry state. + /// An entry is assigned a store-retry state when underlying store failed due some reason + /// and cache has enough space to retain this entry till the next try. + /// </summary> + /// <returns> + /// Count of entries in store-retry state. + /// </returns> + int WriteBehindErrorRetryCount { get; } + + /// <summary> + /// Gets count of entries that were processed by the write-behind store + /// and have not been flushed to the underlying store yet. + /// </summary> + /// <returns> + /// Total count of entries in cache store internal buffer. + /// </returns> + int WriteBehindBufferSize { get; } + + /// <summary> + /// Determines the required type of keys for this cache, if any. + /// </summary> + /// <returns> + /// The fully qualified class name of the key type, or "java.lang.Object" if the type is undefined. + /// </returns> + string KeyType { get; } + + /// <summary> + /// Determines the required type of values for this cache, if any. + /// </summary> + /// <returns> + /// The fully qualified class name of the value type, or "java.lang.Object" if the type is undefined. + /// </returns> + string ValueType { get; } + + /// <summary> + /// Whether storeByValue true or storeByReference false. When true, both keys and values are stored by value. + /// <para /> + /// When false, both keys and values are stored by reference. Caches stored by reference are capable of + /// mutation by any threads holding the reference. + /// The effects are: + /// - if the key is mutated, then the key may not be retrievable or removable + /// - if the value is mutated, then all threads in the JVM can potentially observe those mutations, subject + /// to the normal Java Memory Model rules. + /// Storage by reference only applies to the local heap. + /// If an entry is moved off heap it will need to be transformed into a representation. + /// Any mutations that occur after transformation may not be reflected in the cache. + /// <para /> + /// When a cache is storeByValue, any mutation to the key or value does not affect the key of value + /// stored in the cache. + /// <para /> + /// The default value is true. + /// </summary> + /// <returns> + /// True if the cache is store by value + /// </returns> + bool IsStoreByValue { get; } + + /// <summary> + /// Checks whether statistics collection is enabled in this cache. + /// <para /> + /// The default value is false. + /// </summary> + /// <returns> + /// True if statistics collection is enabled + /// </returns> + bool IsStatisticsEnabled { get; } + + /// <summary> + /// Checks whether management is enabled on this cache. + /// <para /> + /// The default value is false. + /// </summary> + /// <returns> + /// True if management is enabled + /// </returns> + bool IsManagementEnabled { get; } + + /// <summary> + /// Determines if a cache should operate in read-through mode. + /// <para /> + /// The default value is false + /// </summary> + /// <returns> + /// True when a cache is in "read-through" mode. + /// </returns> + bool IsReadThrough { get; } + + /// <summary> + /// Determines if a cache should operate in "write-through" mode. + /// <para /> + /// Will appropriately cause the configured CacheWriter to be invoked. + /// <para /> + /// The default value is false + /// </summary> + /// <returns> + /// True when a cache is in "write-through" mode. + /// </returns> + bool IsWriteThrough { get; } + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ignite/blob/5cec202c/modules/platform/src/main/dotnet/Apache.Ignite.Core/Cache/IMutableCacheEntry.cs ---------------------------------------------------------------------- diff --git a/modules/platform/src/main/dotnet/Apache.Ignite.Core/Cache/IMutableCacheEntry.cs b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Cache/IMutableCacheEntry.cs new file mode 100644 index 0000000..ae71be6 --- /dev/null +++ b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Cache/IMutableCacheEntry.cs @@ -0,0 +1,47 @@ +/* + * 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. + */ + +namespace Apache.Ignite.Core.Cache +{ + /// <summary> + /// Mutable representation of <see cref="ICacheEntry{K, V}"/> + /// </summary> + /// <typeparam name="TK">Key type.</typeparam> + /// <typeparam name="TV">Value type.</typeparam> + public interface IMutableCacheEntry<out TK, TV> : ICacheEntry<TK, TV> + { + /// <summary> + /// Gets a value indicating whether cache entry exists in cache. + /// </summary> + bool Exists { get; } + + /// <summary> + /// Removes the entry from the Cache. + /// </summary> + void Remove(); + + /// <summary> + /// Gets, sets or replaces the value associated with the key. + /// <para /> + /// If <see cref="Exists"/> is false and setter is called then a mapping is added to the cache + /// visible once the EntryProcessor completes. + /// <para /> + /// After setter invocation <see cref="Exists"/> will return true. + /// </summary> + new TV Value { get; set; } + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ignite/blob/5cec202c/modules/platform/src/main/dotnet/Apache.Ignite.Core/Cache/Query/Continuous/ContinuousQuery.cs ---------------------------------------------------------------------- diff --git a/modules/platform/src/main/dotnet/Apache.Ignite.Core/Cache/Query/Continuous/ContinuousQuery.cs b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Cache/Query/Continuous/ContinuousQuery.cs new file mode 100644 index 0000000..8f297a2 --- /dev/null +++ b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Cache/Query/Continuous/ContinuousQuery.cs @@ -0,0 +1,170 @@ +/* + * 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. + */ + +namespace Apache.Ignite.Core.Cache.Query.Continuous +{ + using System; + using System.Diagnostics.CodeAnalysis; + using Apache.Ignite.Core.Cache.Event; + + /// <summary> + /// API for configuring continuous cache queries. + /// <para /> + /// Continuous queries allow to register a remote and a listener for cache update events. + /// If an update event passes the filter, it will be sent to the node that executed the + /// query and listener will be notified on that node. + /// <para /> + /// Continuous query can either be executed on the whole topology or only on local node. + /// <para /> + /// In case query is distributed and a new node joins, it will get the filter for the query + /// during discovery process before it actually joins topology, so no updates will be missed. + /// <para /> + /// To execute the query use method + /// <see cref="ICache{K,V}.QueryContinuous(ContinuousQuery{K,V})"/>. + /// </summary> + public class ContinuousQuery<TK, TV> + { + /// <summary> + /// Default buffer size. + /// </summary> + [SuppressMessage("Microsoft.Design", "CA1000:DoNotDeclareStaticMembersOnGenericTypes")] + public const int DfltBufSize = 1; + + /// <summary> + /// Default time interval. + /// </summary> + [SuppressMessage("ReSharper", "StaticMemberInGenericType")] + [SuppressMessage("Microsoft.Design", "CA1000:DoNotDeclareStaticMembersOnGenericTypes")] + public static readonly TimeSpan DfltTimeInterval = new TimeSpan(0); + + /// <summary> + /// Default auto-unsubscribe flag value. + /// </summary> + [SuppressMessage("Microsoft.Design", "CA1000:DoNotDeclareStaticMembersOnGenericTypes")] + public const bool DfltAutoUnsubscribe = true; + + /// <summary> + /// Constructor. + /// </summary> + /// <param name="lsnr">Listener.</param> + public ContinuousQuery(ICacheEntryEventListener<TK, TV> lsnr) : this(lsnr, false) + { + // No-op. + } + + /// <summary> + /// Constructor. + /// </summary> + /// <param name="lsnr">Listener.</param> + /// <param name="loc">Whether query should be executed locally.</param> + public ContinuousQuery(ICacheEntryEventListener<TK, TV> lsnr, bool loc) : this(lsnr, null, loc) + { + // No-op. + } + + /// <summary> + /// Constructor. + /// </summary> + /// <param name="lsnr">Listener.</param> + /// <param name="filter">Filter.</param> + public ContinuousQuery(ICacheEntryEventListener<TK, TV> lsnr, ICacheEntryEventFilter<TK, TV> filter) + : this(lsnr, filter, false) + { + // No-op. + } + + /// <summary> + /// Constructor. + /// </summary> + /// <param name="lsnr">Listener.</param> + /// <param name="filter">Filter.</param> + /// <param name="loc">Whether query should be executed locally.</param> + public ContinuousQuery(ICacheEntryEventListener<TK, TV> lsnr, ICacheEntryEventFilter<TK, TV> filter, bool loc) + { + Listener = lsnr; + Filter = filter; + Local = loc; + + BufferSize = DfltBufSize; + TimeInterval = DfltTimeInterval; + AutoUnsubscribe = DfltAutoUnsubscribe; + } + + /// <summary> + /// Cache entry event listener. Invoked on the node where continuous query execution + /// has been started. + /// </summary> + public ICacheEntryEventListener<TK, TV> Listener { get; set; } + + /// <summary> + /// Optional cache entry filter. Invoked on a node where cache event occurred. If filter + /// returns <c>false</c>, then cache entry event will not be sent to a node where + /// continuous query has been started. + /// <para /> + /// Must be either portable or serializable in case query is not local. + /// </summary> + public ICacheEntryEventFilter<TK, TV> Filter { get; set; } + + /// <summary> + /// Buffer size. When a cache update happens, entry is first put into a buffer. + /// Entries from buffer will be sent to the master node only if the buffer is + /// full or time provided via <see cref="TimeInterval"/> is exceeded. + /// <para /> + /// Defaults to <see cref="DfltBufSize"/> + /// </summary> + public int BufferSize { get; set; } + + /// <summary> + /// Time interval. When a cache update happens, entry is first put into a buffer. + /// Entries from buffer will be sent to the master node only if the buffer is full + /// (its size can be provided via <see cref="BufferSize"/> property) or time provided + /// via this method is exceeded. + /// <para /> + /// Defaults to <c>0</c> which means that time check is disabled and entries will be + /// sent only when buffer is full. + /// </summary> + public TimeSpan TimeInterval { get; set; } + + /// <summary> + /// Automatic unsubscribe flag. This flag indicates that query filters on remote nodes + /// should be automatically unregistered if master node (node that initiated the query) + /// leaves topology. If this flag is <c>false</c>, filters will be unregistered only + /// when the query is cancelled from master node, and won't ever be unregistered if + /// master node leaves grid. + /// <para /> + /// Defaults to <c>true</c>. + /// </summary> + public bool AutoUnsubscribe { get; set; } + + /// <summary> + /// Local flag. When set query will be executed only on local node, so only local + /// entries will be returned as query result. + /// <para /> + /// Defaults to <c>false</c>. + /// </summary> + public bool Local { get; set; } + + /// <summary> + /// Validate continuous query state. + /// </summary> + internal void Validate() + { + if (Listener == null) + throw new ArgumentException("Listener cannot be null."); + } + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/5cec202c/modules/platform/src/main/dotnet/Apache.Ignite.Core/Cache/Query/Continuous/IContinuousQueryHandle.cs ---------------------------------------------------------------------- diff --git a/modules/platform/src/main/dotnet/Apache.Ignite.Core/Cache/Query/Continuous/IContinuousQueryHandle.cs b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Cache/Query/Continuous/IContinuousQueryHandle.cs new file mode 100644 index 0000000..0a6f154 --- /dev/null +++ b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Cache/Query/Continuous/IContinuousQueryHandle.cs @@ -0,0 +1,51 @@ +/* + * 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. + */ + +namespace Apache.Ignite.Core.Cache.Query.Continuous +{ + using System; + using System.Diagnostics.CodeAnalysis; + + /// <summary> + /// Represents a continuous query handle. + /// </summary> + [SuppressMessage("Microsoft.Design", "CA1040:AvoidEmptyInterfaces")] + public interface IContinuousQueryHandle : IDisposable + { + // No-op. + } + + /// <summary> + /// Represents a continuous query handle. + /// </summary> + /// <typeparam name="T">Type of the initial query cursor.</typeparam> + public interface IContinuousQueryHandle<T> : IContinuousQueryHandle + { + /// <summary> + /// Gets the cursor for initial query. + /// </summary> + [Obsolete("GetInitialQueryCursor() method should be used instead.")] + IQueryCursor<T> InitialQueryCursor { get; } + + /// <summary> + /// Gets the cursor for initial query. + /// Can be called only once, throws exception on consequent calls. + /// </summary> + /// <returns>Initial query cursor.</returns> + IQueryCursor<T> GetInitialQueryCursor(); + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ignite/blob/5cec202c/modules/platform/src/main/dotnet/Apache.Ignite.Core/Cache/Query/IQueryCursor.cs ---------------------------------------------------------------------- diff --git a/modules/platform/src/main/dotnet/Apache.Ignite.Core/Cache/Query/IQueryCursor.cs b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Cache/Query/IQueryCursor.cs new file mode 100644 index 0000000..9745765 --- /dev/null +++ b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Cache/Query/IQueryCursor.cs @@ -0,0 +1,40 @@ +/* + * 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. + */ + +namespace Apache.Ignite.Core.Cache.Query +{ + using System; + using System.Collections.Generic; + + /// <summary> + /// Query result cursor. Can be processed either in iterative mode, or by taking + /// all entries using <see cref="IQueryCursor{T}.GetAll()"/> method. + /// <para /> + /// Note that you get enumerator or call <code>GetAll()</code> method only once during + /// cursor lifetime. Any further attempts to get enumerator or all entries will result + /// in exception. + /// </summary> + public interface IQueryCursor<T> : IEnumerable<T>, IDisposable + { + /// <summary> + /// Gets all query results. Use this method when you know in advance that query + /// result is relatively small and will not cause memory utilization issues. + /// </summary> + /// <returns>List containing all query results.</returns> + IList<T> GetAll(); + } +}
