http://git-wip-us.apache.org/repos/asf/ignite/blob/ee20f1d9/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/CacheConfiguration.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/CacheConfiguration.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/CacheConfiguration.cs new file mode 100644 index 0000000..b319be9 --- /dev/null +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/CacheConfiguration.cs @@ -0,0 +1,601 @@ +/* + * 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. + */ + +// ReSharper disable MemberCanBePrivate.Global +// ReSharper disable UnusedMember.Global +// ReSharper disable UnusedAutoPropertyAccessor.Global +namespace Apache.Ignite.Core.Cache.Configuration +{ + using System; + using System.Collections.Generic; + using System.ComponentModel; + using System.Diagnostics.CodeAnalysis; + using System.Linq; + using Apache.Ignite.Core.Binary; + using Apache.Ignite.Core.Cache; + using Apache.Ignite.Core.Cache.Store; + using Apache.Ignite.Core.Common; + using Apache.Ignite.Core.Impl.Binary; + + /// <summary> + /// Defines grid cache configuration. + /// </summary> + public class CacheConfiguration + { + /// <summary> Default size of rebalance thread pool. </summary> + public const int DefaultRebalanceThreadPoolSize = 2; + + /// <summary> Default rebalance timeout.</summary> + public static readonly TimeSpan DefaultRebalanceTimeout = TimeSpan.FromMilliseconds(10000); + + /// <summary> Time to wait between rebalance messages to avoid overloading CPU. </summary> + public static readonly TimeSpan DefaultRebalanceThrottle = TimeSpan.Zero; + + /// <summary> Default number of backups. </summary> + public const int DefaultBackups = 0; + + /// <summary> Default caching mode. </summary> + public const CacheMode DefaultCacheMode = CacheMode.Partitioned; + + /// <summary> Default atomicity mode. </summary> + public const CacheAtomicityMode DefaultAtomicityMode = CacheAtomicityMode.Atomic; + + /// <summary> Default lock timeout. </summary> + public static readonly TimeSpan DefaultLockTimeout = TimeSpan.Zero; + + /// <summary> Initial default cache size. </summary> + public const int DefaultStartSize = 1500000; + + /// <summary> Default cache size to use with eviction policy. </summary> + public const int DefaultCacheSize = 100000; + + /// <summary> Default value for 'invalidate' flag that indicates if this is invalidation-based cache. </summary> + public const bool DefaultInvalidate = false; + + /// <summary> Default rebalance mode for distributed cache. </summary> + public const CacheRebalanceMode DefaultRebalanceMode = CacheRebalanceMode.Async; + + /// <summary> Default rebalance batch size in bytes. </summary> + public const int DefaultRebalanceBatchSize = 512*1024; // 512K + + /// <summary> Default maximum eviction queue ratio. </summary> + public const float DefaultMaxEvictionOverflowRatio = 10; + + /// <summary> Default eviction synchronized flag. </summary> + public const bool DefaultEvictSynchronized = false; + + /// <summary> Default eviction key buffer size for batching synchronized evicts. </summary> + public const int DefaultEvictSynchronizedKeyBufferSize = 1024; + + /// <summary> Default synchronous eviction timeout. </summary> + public static readonly TimeSpan DefaultEvictSynchronizedTimeout = TimeSpan.FromMilliseconds(10000); + + /// <summary> Default synchronous eviction concurrency level. </summary> + public const int DefaultEvictSynchronizedConcurrencyLevel = 4; + + /// <summary> Default value for eager ttl flag. </summary> + public const bool DefaultEagerTtl = true; + + /// <summary> Default off-heap storage size is {@code -1} which means that off-heap storage is disabled. </summary> + public const long DefaultOffHeapMaxMemory = -1; + + /// <summary> Default value for 'swapEnabled' flag. </summary> + public const bool DefaultEnableSwap = false; + + /// <summary> Default value for 'maxConcurrentAsyncOps'. </summary> + public const int DefaultMaxConcurrentAsyncOperations = 500; + + /// <summary> Default value for 'writeBehindEnabled' flag. </summary> + public const bool DefaultWriteBehindEnabled = false; + + /// <summary> Default flush size for write-behind cache store. </summary> + public const int DefaultWriteBehindFlushSize = 10240; // 10K + + /// <summary> Default flush frequency for write-behind cache store. </summary> + public static readonly TimeSpan DefaultWriteBehindFlushFrequency = TimeSpan.FromMilliseconds(5000); + + /// <summary> Default count of flush threads for write-behind cache store. </summary> + public const int DefaultWriteBehindFlushThreadCount = 1; + + /// <summary> Default batch size for write-behind cache store. </summary> + public const int DefaultWriteBehindBatchSize = 512; + + /// <summary> Default value for load previous value flag. </summary> + public const bool DefaultLoadPreviousValue = false; + + /// <summary> Default memory mode. </summary> + public const CacheMemoryMode DefaultMemoryMode = CacheMemoryMode.OnheapTiered; + + /// <summary> Default value for 'readFromBackup' flag. </summary> + public const bool DefaultReadFromBackup = true; + + /// <summary> Default timeout after which long query warning will be printed. </summary> + public static readonly TimeSpan DefaultLongQueryWarningTimeout = TimeSpan.FromMilliseconds(3000); + + /// <summary> Default size for onheap SQL row cache size. </summary> + public const int DefaultSqlOnheapRowCacheSize = 10*1024; + + /// <summary> Default value for keep portable in store behavior .</summary> + public const bool DefaultKeepVinaryInStore = true; + + /// <summary> Default value for 'copyOnRead' flag. </summary> + public const bool DefaultCopyOnRead = true; + + /// <summary> + /// Gets or sets the cache name. + /// </summary> + public string Name { get; set; } + + /// <summary> + /// Initializes a new instance of the <see cref="CacheConfiguration"/> class. + /// </summary> + public CacheConfiguration() : this((string) null) + { + // No-op. + } + + /// <summary> + /// Initializes a new instance of the <see cref="CacheConfiguration"/> class. + /// </summary> + /// <param name="name">Cache name.</param> + public CacheConfiguration(string name) + { + Name = name; + + Backups = DefaultBackups; + AtomicityMode = DefaultAtomicityMode; + CacheMode = DefaultCacheMode; + CopyOnRead = DefaultCopyOnRead; + EagerTtl = DefaultEagerTtl; + EvictSynchronizedKeyBufferSize = DefaultEvictSynchronizedKeyBufferSize; + EvictSynchronized = DefaultEvictSynchronized; + EvictSynchronizedConcurrencyLevel = DefaultEvictSynchronizedConcurrencyLevel; + EvictSynchronizedTimeout = DefaultEvictSynchronizedTimeout; + Invalidate = DefaultInvalidate; + KeepBinaryInStore = DefaultKeepVinaryInStore; + LoadPreviousValue = DefaultLoadPreviousValue; + LockTimeout = DefaultLockTimeout; + LongQueryWarningTimeout = DefaultLongQueryWarningTimeout; + MaxConcurrentAsyncOperations = DefaultMaxConcurrentAsyncOperations; + MaxEvictionOverflowRatio = DefaultMaxEvictionOverflowRatio; + MemoryMode = DefaultMemoryMode; + OffHeapMaxMemory = DefaultOffHeapMaxMemory; + ReadFromBackup = DefaultReadFromBackup; + RebalanceBatchSize = DefaultRebalanceBatchSize; + RebalanceMode = DefaultRebalanceMode; + RebalanceThrottle = DefaultRebalanceThrottle; + RebalanceTimeout = DefaultRebalanceTimeout; + SqlOnheapRowCacheSize = DefaultSqlOnheapRowCacheSize; + StartSize = DefaultStartSize; + EnableSwap = DefaultEnableSwap; + WriteBehindBatchSize = DefaultWriteBehindBatchSize; + WriteBehindEnabled = DefaultWriteBehindEnabled; + WriteBehindFlushFrequency = DefaultWriteBehindFlushFrequency; + WriteBehindFlushSize = DefaultWriteBehindFlushSize; + WriteBehindFlushThreadCount= DefaultWriteBehindFlushThreadCount; + } + + /// <summary> + /// Initializes a new instance of the <see cref="CacheConfiguration"/> class + /// and populates <see cref="QueryEntities"/> according to provided query types. + /// </summary> + /// <param name="name">Cache name.</param> + /// <param name="queryTypes"> + /// Collection of types to be registered as query entities. These types should use + /// <see cref="QuerySqlFieldAttribute"/> to configure query fields and properties. + /// </param> + public CacheConfiguration(string name, params Type[] queryTypes) : this(name) + { + QueryEntities = queryTypes.Select(type => new QueryEntity {ValueType = type}).ToArray(); + } + + /// <summary> + /// Initializes a new instance of the <see cref="CacheConfiguration"/> class. + /// </summary> + /// <param name="name">Cache name.</param> + /// <param name="queryEntities">Query entities.</param> + public CacheConfiguration(string name, params QueryEntity[] queryEntities) : this(name) + { + QueryEntities = queryEntities; + } + + /// <summary> + /// Initializes a new instance of the <see cref="CacheConfiguration"/> class. + /// </summary> + /// <param name="reader">The reader.</param> + internal CacheConfiguration(IBinaryRawReader reader) + { + AtomicityMode = (CacheAtomicityMode) reader.ReadInt(); + AtomicWriteOrderMode = (CacheAtomicWriteOrderMode) reader.ReadInt(); + Backups = reader.ReadInt(); + CacheMode = (CacheMode) reader.ReadInt(); + CopyOnRead = reader.ReadBoolean(); + EagerTtl = reader.ReadBoolean(); + EnableSwap = reader.ReadBoolean(); + EvictSynchronized = reader.ReadBoolean(); + EvictSynchronizedConcurrencyLevel = reader.ReadInt(); + EvictSynchronizedKeyBufferSize = reader.ReadInt(); + EvictSynchronizedTimeout = reader.ReadLongAsTimespan(); + Invalidate = reader.ReadBoolean(); + KeepBinaryInStore = reader.ReadBoolean(); + LoadPreviousValue = reader.ReadBoolean(); + LockTimeout = reader.ReadLongAsTimespan(); + LongQueryWarningTimeout = reader.ReadLongAsTimespan(); + MaxConcurrentAsyncOperations = reader.ReadInt(); + MaxEvictionOverflowRatio = reader.ReadFloat(); + MemoryMode = (CacheMemoryMode) reader.ReadInt(); + Name = reader.ReadString(); + OffHeapMaxMemory = reader.ReadLong(); + ReadFromBackup = reader.ReadBoolean(); + RebalanceBatchSize = reader.ReadInt(); + RebalanceDelay = reader.ReadLongAsTimespan(); + RebalanceMode = (CacheRebalanceMode) reader.ReadInt(); + RebalanceThrottle = reader.ReadLongAsTimespan(); + RebalanceTimeout = reader.ReadLongAsTimespan(); + SqlEscapeAll = reader.ReadBoolean(); + SqlOnheapRowCacheSize = reader.ReadInt(); + StartSize = reader.ReadInt(); + WriteBehindBatchSize = reader.ReadInt(); + WriteBehindEnabled = reader.ReadBoolean(); + WriteBehindFlushFrequency = reader.ReadLongAsTimespan(); + WriteBehindFlushSize = reader.ReadInt(); + WriteBehindFlushThreadCount = reader.ReadInt(); + WriteSynchronizationMode = (CacheWriteSynchronizationMode) reader.ReadInt(); + CacheStoreFactory = reader.ReadObject<IFactory<ICacheStore>>(); + + var count = reader.ReadInt(); + QueryEntities = count == 0 ? null : Enumerable.Range(0, count).Select(x => new QueryEntity(reader)).ToList(); + } + + /// <summary> + /// Writes this instane to the specified writer. + /// </summary> + /// <param name="writer">The writer.</param> + internal void Write(IBinaryRawWriter writer) + { + writer.WriteInt((int) AtomicityMode); + writer.WriteInt((int) AtomicWriteOrderMode); + writer.WriteInt(Backups); + writer.WriteInt((int) CacheMode); + writer.WriteBoolean(CopyOnRead); + writer.WriteBoolean(EagerTtl); + writer.WriteBoolean(EnableSwap); + writer.WriteBoolean(EvictSynchronized); + writer.WriteInt(EvictSynchronizedConcurrencyLevel); + writer.WriteInt(EvictSynchronizedKeyBufferSize); + writer.WriteLong((long) EvictSynchronizedTimeout.TotalMilliseconds); + writer.WriteBoolean(Invalidate); + writer.WriteBoolean(KeepBinaryInStore); + writer.WriteBoolean(LoadPreviousValue); + writer.WriteLong((long) LockTimeout.TotalMilliseconds); + writer.WriteLong((long) LongQueryWarningTimeout.TotalMilliseconds); + writer.WriteInt(MaxConcurrentAsyncOperations); + writer.WriteFloat(MaxEvictionOverflowRatio); + writer.WriteInt((int) MemoryMode); + writer.WriteString(Name); + writer.WriteLong(OffHeapMaxMemory); + writer.WriteBoolean(ReadFromBackup); + writer.WriteInt(RebalanceBatchSize); + writer.WriteLong((long) RebalanceDelay.TotalMilliseconds); + writer.WriteInt((int) RebalanceMode); + writer.WriteLong((long) RebalanceThrottle.TotalMilliseconds); + writer.WriteLong((long) RebalanceTimeout.TotalMilliseconds); + writer.WriteBoolean(SqlEscapeAll); + writer.WriteInt(SqlOnheapRowCacheSize); + writer.WriteInt(StartSize); + writer.WriteInt(WriteBehindBatchSize); + writer.WriteBoolean(WriteBehindEnabled); + writer.WriteLong((long) WriteBehindFlushFrequency.TotalMilliseconds); + writer.WriteInt(WriteBehindFlushSize); + writer.WriteInt(WriteBehindFlushThreadCount); + writer.WriteInt((int) WriteSynchronizationMode); + writer.WriteObject(CacheStoreFactory); + + if (QueryEntities != null) + { + writer.WriteInt(QueryEntities.Count); + + foreach (var entity in QueryEntities) + { + if (entity == null) + throw new InvalidOperationException("Invalid cache configuration: QueryEntity can't be null."); + + entity.Write(writer); + } + } + else + writer.WriteInt(0); + } + + /// <summary> + /// Gets or sets write synchronization mode. This mode controls whether the main + /// caller should wait for update on other nodes to complete or not. + /// </summary> + public CacheWriteSynchronizationMode WriteSynchronizationMode { get; set; } + + /// <summary> + /// Gets or sets flag indicating whether eviction is synchronized between primary, backup and near nodes. + /// If this parameter is true and swap is disabled then <see cref="ICache{TK,TV}.LocalEvict"/> + /// will involve all nodes where an entry is kept. + /// If this property is set to false then eviction is done independently on different cache nodes. + /// Note that it's not recommended to set this value to true if cache store is configured since it will allow + /// to significantly improve cache performance. + /// </summary> + [DefaultValue(DefaultEvictSynchronized)] + public bool EvictSynchronized { get; set; } + + /// <summary> + /// Gets or sets size of the key buffer for synchronized evictions. + /// </summary> + [DefaultValue(DefaultEvictSynchronizedKeyBufferSize)] + public int EvictSynchronizedKeyBufferSize { get; set; } + + /// <summary> + /// Gets or sets concurrency level for synchronized evictions. + /// This flag only makes sense with <see cref="EvictSynchronized"/> set to true. + /// When synchronized evictions are enabled, it is possible that local eviction policy will try + /// to evict entries faster than evictions can be synchronized with backup or near nodes. + /// This value specifies how many concurrent synchronous eviction sessions should be allowed + /// before the system is forced to wait and let synchronous evictions catch up with the eviction policy. + /// </summary> + [DefaultValue(DefaultEvictSynchronizedConcurrencyLevel)] + public int EvictSynchronizedConcurrencyLevel { get; set; } + + /// <summary> + /// Gets or sets timeout for synchronized evictions + /// </summary> + [DefaultValue(typeof(TimeSpan), "00:00:10")] + public TimeSpan EvictSynchronizedTimeout { get; set; } + + /// <summary> + /// This value denotes the maximum size of eviction queue in percents of cache size + /// in case of distributed cache (replicated and partitioned) and using synchronized eviction + /// <para/> + /// That queue is used internally as a buffer to decrease network costs for synchronized eviction. + /// Once queue size reaches specified value all required requests for all entries in the queue + /// are sent to remote nodes and the queue is cleared. + /// </summary> + [DefaultValue(DefaultMaxEvictionOverflowRatio)] + public float MaxEvictionOverflowRatio { get; set; } + + /// <summary> + /// Gets or sets flag indicating whether expired cache entries will be eagerly removed from cache. + /// When set to false, expired entries will be removed on next entry access. + /// </summary> + [DefaultValue(DefaultEagerTtl)] + public bool EagerTtl { get; set; } + + /// <summary> + /// Gets or sets initial cache size which will be used to pre-create internal hash table after start. + /// </summary> + [DefaultValue(DefaultStartSize)] + public int StartSize { get; set; } + + /// <summary> + /// Gets or sets flag indicating whether value should be loaded from store if it is not in the cache + /// for the following cache operations: + /// <list type="bullet"> + /// <item><term><see cref="ICache{TK,TV}.PutIfAbsent"/></term></item> + /// <item><term><see cref="ICache{TK,TV}.Replace(TK,TV)"/></term></item> + /// <item><term><see cref="ICache{TK,TV}.Remove(TK)"/></term></item> + /// <item><term><see cref="ICache{TK,TV}.GetAndPut"/></term></item> + /// <item><term><see cref="ICache{TK,TV}.GetAndRemove"/></term></item> + /// <item><term><see cref="ICache{TK,TV}.GetAndReplace"/></term></item> + /// <item><term><see cref="ICache{TK,TV}.GetAndPutIfAbsent"/></term></item> + /// </list> + /// </summary> + [DefaultValue(DefaultLoadPreviousValue)] + public bool LoadPreviousValue { get; set; } + + /// <summary> + /// Gets or sets the flag indicating whether <see cref="ICacheStore"/> is working with binary objects + /// instead of deserialized objects. + /// </summary> + [DefaultValue(DefaultKeepVinaryInStore)] + public bool KeepBinaryInStore { get; set; } + + /// <summary> + /// Gets or sets caching mode to use. + /// </summary> + [DefaultValue(DefaultCacheMode)] + public CacheMode CacheMode { get; set; } + + /// <summary> + /// Gets or sets cache atomicity mode. + /// </summary> + [DefaultValue(DefaultAtomicityMode)] + public CacheAtomicityMode AtomicityMode { get; set; } + + /// <summary> + /// Gets or sets cache write ordering mode. + /// </summary> + public CacheAtomicWriteOrderMode AtomicWriteOrderMode { get; set; } + + /// <summary> + /// Gets or sets number of nodes used to back up single partition for + /// <see cref="Configuration.CacheMode.Partitioned"/> cache. + /// </summary> + [DefaultValue(DefaultBackups)] + public int Backups { get; set; } + + /// <summary> + /// Gets or sets default lock acquisition timeout. + /// </summary> + [DefaultValue(typeof(TimeSpan), "00:00:00")] + public TimeSpan LockTimeout { get; set; } + + /// <summary> + /// Invalidation flag. If true, values will be invalidated (nullified) upon commit in near cache. + /// </summary> + [DefaultValue(DefaultInvalidate)] + public bool Invalidate { get; set; } + + /// <summary> + /// Gets or sets cache rebalance mode. + /// </summary> + [DefaultValue(DefaultRebalanceMode)] + public CacheRebalanceMode RebalanceMode { get; set; } + + /// <summary> + /// Gets or sets size (in number bytes) to be loaded within a single rebalance message. + /// Rebalancing algorithm will split total data set on every node into multiple batches prior to sending data. + /// </summary> + [DefaultValue(DefaultRebalanceBatchSize)] + public int RebalanceBatchSize { get; set; } + + /// <summary> + /// Flag indicating whether Ignite should use swap storage by default. + /// </summary> + [DefaultValue(DefaultEnableSwap)] + public bool EnableSwap { get; set; } + + /// <summary> + /// Gets or sets maximum number of allowed concurrent asynchronous operations, 0 for unlimited. + /// </summary> + [DefaultValue(DefaultMaxConcurrentAsyncOperations)] + public int MaxConcurrentAsyncOperations { get; set; } + + /// <summary> + /// Flag indicating whether Ignite should use write-behind behaviour for the cache store. + /// </summary> + [DefaultValue(DefaultWriteBehindEnabled)] + public bool WriteBehindEnabled { get; set; } + + /// <summary> + /// Maximum size of the write-behind cache. If cache size exceeds this value, all cached items are flushed + /// to the cache store and write cache is cleared. + /// </summary> + [DefaultValue(DefaultWriteBehindFlushSize)] + public int WriteBehindFlushSize { get; set; } + + /// <summary> + /// Frequency with which write-behind cache is flushed to the cache store. + /// This value defines the maximum time interval between object insertion/deletion from the cache + /// at the moment when corresponding operation is applied to the cache store. + /// <para/> + /// If this value is 0, then flush is performed according to the flush size. + /// <para/> + /// Note that you cannot set both + /// <see cref="WriteBehindFlushSize"/> and <see cref="WriteBehindFlushFrequency"/> to 0. + /// </summary> + [DefaultValue(typeof(TimeSpan), "00:00:05")] + public TimeSpan WriteBehindFlushFrequency { get; set; } + + /// <summary> + /// Number of threads that will perform cache flushing. Cache flushing is performed when cache size exceeds + /// value defined by <see cref="WriteBehindFlushSize"/>, or flush interval defined by + /// <see cref="WriteBehindFlushFrequency"/> is elapsed. + /// </summary> + [DefaultValue(DefaultWriteBehindFlushThreadCount)] + public int WriteBehindFlushThreadCount { get; set; } + + /// <summary> + /// Maximum batch size for write-behind cache store operations. + /// Store operations (get or remove) are combined in a batch of this size to be passed to + /// <see cref="ICacheStore.WriteAll"/> or <see cref="ICacheStore.DeleteAll"/> methods. + /// </summary> + [DefaultValue(DefaultWriteBehindBatchSize)] + public int WriteBehindBatchSize { get; set; } + + /// <summary> + /// Gets or sets rebalance timeout. + /// </summary> + [DefaultValue(typeof(TimeSpan), "00:00:10")] + public TimeSpan RebalanceTimeout { get; set; } + + /// <summary> + /// Gets or sets delay upon a node joining or leaving topology (or crash) + /// after which rebalancing should be started automatically. + /// Rebalancing should be delayed if you plan to restart nodes + /// after they leave topology, or if you plan to start multiple nodes at once or one after another + /// and don't want to repartition and rebalance until all nodes are started. + /// </summary> + public TimeSpan RebalanceDelay { get; set; } + + /// <summary> + /// Time to wait between rebalance messages to avoid overloading of CPU or network. + /// When rebalancing large data sets, the CPU or network can get over-consumed with rebalancing messages, + /// which consecutively may slow down the application performance. This parameter helps tune + /// the amount of time to wait between rebalance messages to make sure that rebalancing process + /// does not have any negative performance impact. Note that application will continue to work + /// properly while rebalancing is still in progress. + /// <para/> + /// Value of 0 means that throttling is disabled. + /// </summary> + public TimeSpan RebalanceThrottle { get; set; } + + /// <summary> + /// Gets or sets maximum amount of memory available to off-heap storage. Possible values are + /// -1 means that off-heap storage is disabled. 0 means that Ignite will not limit off-heap storage + /// (it's up to user to properly add and remove entries from cache to ensure that off-heap storage + /// does not grow indefinitely. + /// Any positive value specifies the limit of off-heap storage in bytes. + /// </summary> + [DefaultValue(DefaultOffHeapMaxMemory)] + public long OffHeapMaxMemory { get; set; } + + /// <summary> + /// Gets or sets memory mode for cache. + /// </summary> + [DefaultValue(DefaultMemoryMode)] + public CacheMemoryMode MemoryMode { get; set; } + + /// <summary> + /// Gets or sets flag indicating whether data can be read from backup. + /// </summary> + [DefaultValue(DefaultReadFromBackup)] + public bool ReadFromBackup { get; set; } + + /// <summary> + /// Gets or sets flag indicating whether copy of of the value stored in cache should be created + /// for cache operation implying return value. + /// </summary> + [DefaultValue(DefaultCopyOnRead)] + public bool CopyOnRead { get; set; } + + /// <summary> + /// Gets or sets the timeout after which long query warning will be printed. + /// </summary> + [DefaultValue(typeof(TimeSpan), "00:00:03")] + public TimeSpan LongQueryWarningTimeout { get; set; } + + /// <summary> + /// If true all the SQL table and field names will be escaped with double quotes like + /// ({ "tableName"."fieldsName"}). This enforces case sensitivity for field names and + /// also allows having special characters in table and field names. + /// </summary> + public bool SqlEscapeAll { get; set; } + + /// <summary> + /// Number of SQL rows which will be cached onheap to avoid deserialization on each SQL index access. + /// This setting only makes sense when offheap is enabled for this cache. + /// </summary> + [DefaultValue(DefaultSqlOnheapRowCacheSize)] + public int SqlOnheapRowCacheSize { get; set; } + + /// <summary> + /// Gets or sets the factory for underlying persistent storage for read-through and write-through operations. + /// </summary> + public IFactory<ICacheStore> CacheStoreFactory { get; set; } + + /// <summary> + /// Gets or sets the query entity configuration. + /// </summary> + [SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")] + public ICollection<QueryEntity> QueryEntities { get; set; } + } +}
http://git-wip-us.apache.org/repos/asf/ignite/blob/ee20f1d9/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/CacheMemoryMode.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/CacheMemoryMode.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/CacheMemoryMode.cs new file mode 100644 index 0000000..a072302 --- /dev/null +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/CacheMemoryMode.cs @@ -0,0 +1,60 @@ +/* + * 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.Configuration +{ + /// <summary> + /// Memory modes define whether cache entries are stored on heap memory, offheap memory, or in swap space. + /// </summary> + public enum CacheMemoryMode + { + /// <summary> + /// Entries will be stored on-heap first. The onheap tiered storage works as follows: + /// <list type="bullet"> + /// <item><description> + /// Entries are cached on heap memory first. + /// </description></item> + /// <item><description> + /// If offheap memory is enabled and eviction policy evicts an entry from heap memory, + /// entry will be moved to offheap memory. If offheap memory is disabled, then entry is simply discarded. + /// </description></item> + /// <item><description> + /// If swap space is enabled and offheap memory fills up, then entry will be evicted into swap space. + /// If swap space is disabled, then entry will be discarded. If swap is enabled and offheap memory is disabled, + /// then entry will be evicted directly from heap memory into swap. + /// </description></item> + /// </list> + /// <para /> + /// Note that heap memory evictions are handled by configured EvictionPolicy implementation. By default, + /// no eviction policy is enabled, so entries never leave heap memory space unless explicitly removed. + /// </summary> + OnheapTiered, + + /// <summary> + /// Works the same as <see cref="OnheapTiered"/>, except that entries never end up in heap memory and get + /// stored in offheap memory right away. Entries get cached in offheap memory first and then + /// get evicted to swap, if one is configured. + /// </summary> + OffheapTiered, + + /// <summary> + /// Entry keys will be stored on heap memory, and values will be stored in offheap memory. + /// Note that in this mode entries can be evicted only to swap. + /// </summary> + OffheapValues + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ignite/blob/ee20f1d9/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/CacheMode.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/CacheMode.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/CacheMode.cs new file mode 100644 index 0000000..6608354 --- /dev/null +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/CacheMode.cs @@ -0,0 +1,52 @@ +/* + * 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.Configuration +{ + /// <summary> + /// Caching modes. + /// </summary> + public enum CacheMode + { + /// <summary> + /// Specifies local-only cache behaviour. In this mode caches residing on + /// different grid nodes will not know about each other. + /// <para /> + /// Other than distribution, <see cref="Local"/> caches still have all + /// the caching features, such as eviction, expiration, swapping, + /// querying, etc... This mode is very useful when caching read-only data + /// or data that automatically expires at a certain interval and + /// then automatically reloaded from persistence store. + /// </summary> + Local, + + /// <summary> + /// Specifies fully replicated cache behavior. In this mode all the keys are distributed + /// to all participating nodes. + /// </summary> + Replicated, + + /// <summary> + /// Specifies partitioned cache behaviour. In this mode the overall + /// key set will be divided into partitions and all partitions will be split + /// equally between participating nodes. + /// <para /> + /// Note that partitioned cache is always fronted by local 'near' cache which stores most recent data. + /// </summary> + Partitioned + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ignite/blob/ee20f1d9/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/CacheRebalanceMode.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/CacheRebalanceMode.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/CacheRebalanceMode.cs new file mode 100644 index 0000000..2ef2115 --- /dev/null +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/CacheRebalanceMode.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.Configuration +{ + /// <summary> + /// Cache rebalance mode. When rebalancing is enabled (i.e. has value other than <see cref="None"/>), + /// distributed caches will attempt to rebalance all necessary values from other grid nodes. + /// <para /> + /// Replicated caches will try to load the full set of cache entries from other nodes, + /// while partitioned caches will only load the entries for which current node is primary or backup. + /// <para /> + /// Note that rebalance mode only makes sense for <see cref="CacheMode.Replicated"/> + /// and <see cref="CacheMode.Partitioned"/> caches. Caches with <see cref="CacheMode.Local"/> + /// mode are local by definition and therefore cannot rebalance any values from neighboring nodes. + /// </summary> + public enum CacheRebalanceMode + { + /// <summary> + /// Synchronous rebalance mode. Distributed caches will not start until all necessary data + /// is loaded from other available grid nodes. + /// </summary> + Sync, + + /// <summary> + /// Asynchronous rebalance mode. Distributed caches will start immediately and will load all necessary + /// data from other available grid nodes in the background. + /// </summary> + Async, + + /// <summary> + /// In this mode no rebalancing will take place which means that caches will be either loaded on + /// demand from persistent store whenever data is accessed, or will be populated explicitly. + /// </summary> + None + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ignite/blob/ee20f1d9/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/CacheWriteSynchronizationMode.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/CacheWriteSynchronizationMode.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/CacheWriteSynchronizationMode.cs new file mode 100644 index 0000000..3257f15 --- /dev/null +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/CacheWriteSynchronizationMode.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.Configuration +{ + /// <summary> + /// Mode indicating how Ignite should wait for write replies from other nodes. + /// </summary> + public enum CacheWriteSynchronizationMode + { + /// <summary> + /// Mode indicating that Ignite should wait for write or commit replies from all nodes. + /// This behavior guarantees that whenever any of the atomic or transactional writes + /// complete, all other participating nodes which cache the written data have been updated. + /// </summary> + FullSync, + + /// <summary> + /// Flag indicating that Ignite will not wait for write or commit responses from participating nodes, + /// which means that remote nodes may get their state updated a bit after any of the cache write methods + /// complete, or after {@link Transaction#commit()} method completes. + /// </summary> + FullAsync, + + /// <summary> + /// This flag only makes sense for {@link CacheMode#PARTITIONED} mode. When enabled, Ignite will wait + /// for write or commit to complete on primary node, but will not wait for backups to be updated. + /// </summary> + PrimarySync + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ignite/blob/ee20f1d9/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/QueryAlias.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/QueryAlias.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/QueryAlias.cs new file mode 100644 index 0000000..33849c7 --- /dev/null +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/QueryAlias.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.Configuration +{ + using Apache.Ignite.Core.Impl.Common; + + /// <summary> + /// Represents cache query configuration alias. + /// </summary> + public class QueryAlias + { + /// <summary> + /// Initializes a new instance of the <see cref="QueryAlias"/> class. + /// </summary> + public QueryAlias() + { + // No-op. + } + + /// <summary> + /// Initializes a new instance of the <see cref="QueryAlias"/> class. + /// </summary> + /// <param name="fullName">The full name.</param> + /// <param name="alias">The alias.</param> + public QueryAlias(string fullName, string alias) + { + IgniteArgumentCheck.NotNullOrEmpty(fullName, "fullName"); + IgniteArgumentCheck.NotNullOrEmpty(alias, "alias"); + + FullName = fullName; + Alias = alias; + } + + /// <summary> + /// Gets or sets the full name of the query field. + /// </summary> + public string FullName { get; set; } + + /// <summary> + /// Gets or sets the alias for the full name. + /// </summary> + public string Alias { get; set; } + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/ee20f1d9/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/QueryEntity.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/QueryEntity.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/QueryEntity.cs new file mode 100644 index 0000000..4151540 --- /dev/null +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/QueryEntity.cs @@ -0,0 +1,401 @@ +/* + * 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. + */ + +// ReSharper disable UnusedAutoPropertyAccessor.Global +// ReSharper disable MemberCanBePrivate.Global +namespace Apache.Ignite.Core.Cache.Configuration +{ + using System; + using System.Collections.Generic; + using System.Diagnostics; + using System.Diagnostics.CodeAnalysis; + using System.Linq; + using System.Reflection; + using Apache.Ignite.Core.Binary; + using Apache.Ignite.Core.Impl.Binary; + + /// <summary> + /// Query entity is a description of cache entry (composed of key and value) + /// in a way of how it must be indexed and can be queried. + /// </summary> + public class QueryEntity + { + /** */ + private Type _keyType; + + /** */ + private Type _valueType; + + /** */ + private string _valueTypeName; + + /** */ + private string _keyTypeName; + + /// <summary> + /// Initializes a new instance of the <see cref="QueryEntity"/> class. + /// </summary> + public QueryEntity() + { + // No-op. + } + + /// <summary> + /// Initializes a new instance of the <see cref="QueryEntity"/> class. + /// </summary> + /// <param name="valueType">Type of the cache entry value.</param> + public QueryEntity(Type valueType) + { + ValueType = valueType; + } + + /// <summary> + /// Initializes a new instance of the <see cref="QueryEntity"/> class. + /// </summary> + /// <param name="keyType">Type of the key.</param> + /// <param name="valueType">Type of the value.</param> + public QueryEntity(Type keyType, Type valueType) + { + KeyType = keyType; + ValueType = valueType; + } + + /// <summary> + /// Gets or sets key Java type name. + /// </summary> + public string KeyTypeName + { + get { return _keyTypeName; } + set + { + _keyTypeName = value; + _keyType = null; + } + } + + /// <summary> + /// Gets or sets the type of the key. + /// <para /> + /// This is a shortcut for <see cref="KeyTypeName"/>. Getter will return null for non-primitive types. + /// <para /> + /// Setting this property will overwrite <see cref="Fields"/> and <see cref="Indexes"/> according to + /// <see cref="QuerySqlFieldAttribute"/>, if any. + /// </summary> + public Type KeyType + { + get { return _keyType ?? JavaTypes.GetDotNetType(KeyTypeName); } + set + { + RescanAttributes(value, _valueType); // Do this first because it can throw + + KeyTypeName = value == null + ? null + : (JavaTypes.GetJavaTypeName(value) ?? BinaryUtils.GetTypeName(value)); + + _keyType = value; + } + } + + /// <summary> + /// Gets or sets value Java type name. + /// </summary> + public string ValueTypeName + { + get { return _valueTypeName; } + set + { + _valueTypeName = value; + _valueType = null; + } + } + + /// <summary> + /// Gets or sets the type of the value. + /// <para /> + /// This is a shortcut for <see cref="ValueTypeName"/>. Getter will return null for non-primitive types. + /// <para /> + /// Setting this property will overwrite <see cref="Fields"/> and <see cref="Indexes"/> according to + /// <see cref="QuerySqlFieldAttribute"/>, if any. + /// </summary> + public Type ValueType + { + get { return _valueType ?? JavaTypes.GetDotNetType(ValueTypeName); } + set + { + RescanAttributes(_keyType, value); // Do this first because it can throw + + ValueTypeName = value == null + ? null + : (JavaTypes.GetJavaTypeName(value) ?? BinaryUtils.GetTypeName(value)); + + _valueType = value; + } + } + + /// <summary> + /// Gets or sets query fields, a map from field name to Java type name. + /// The order of fields defines the order of columns returned by the 'select *' queries. + /// </summary> + [SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")] + public ICollection<QueryField> Fields { get; set; } + + /// <summary> + /// Gets or sets field name aliases: mapping from full name in dot notation to an alias + /// that will be used as SQL column name. + /// Example: {"parent.name" -> "parentName"}. + /// </summary> + [SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")] + public ICollection<QueryAlias> Aliases { get; set; } + + /// <summary> + /// Gets or sets the query indexes. + /// </summary> + [SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")] + public ICollection<QueryIndex> Indexes { get; set; } + + /// <summary> + /// Initializes a new instance of the <see cref="QueryEntity"/> class. + /// </summary> + /// <param name="reader">The reader.</param> + internal QueryEntity(IBinaryRawReader reader) + { + KeyTypeName = reader.ReadString(); + ValueTypeName = reader.ReadString(); + + var count = reader.ReadInt(); + Fields = count == 0 ? null : Enumerable.Range(0, count).Select(x => + new QueryField(reader.ReadString(), reader.ReadString())).ToList(); + + count = reader.ReadInt(); + Aliases = count == 0 ? null : Enumerable.Range(0, count) + .Select(x=> new QueryAlias(reader.ReadString(), reader.ReadString())).ToList(); + + count = reader.ReadInt(); + Indexes = count == 0 ? null : Enumerable.Range(0, count).Select(x => new QueryIndex(reader)).ToList(); + } + + /// <summary> + /// Writes this instance. + /// </summary> + internal void Write(IBinaryRawWriter writer) + { + writer.WriteString(KeyTypeName); + writer.WriteString(ValueTypeName); + + if (Fields != null) + { + writer.WriteInt(Fields.Count); + + foreach (var field in Fields) + { + writer.WriteString(field.Name); + writer.WriteString(field.FieldTypeName); + } + } + else + writer.WriteInt(0); + + + if (Aliases != null) + { + writer.WriteInt(Aliases.Count); + + foreach (var queryAlias in Aliases) + { + writer.WriteString(queryAlias.FullName); + writer.WriteString(queryAlias.Alias); + } + } + else + writer.WriteInt(0); + + if (Indexes != null) + { + writer.WriteInt(Indexes.Count); + + foreach (var index in Indexes) + { + if (index == null) + throw new InvalidOperationException("Invalid cache configuration: QueryIndex can't be null."); + + index.Write(writer); + } + } + else + writer.WriteInt(0); + } + + + /// <summary> + /// Rescans the attributes in <see cref="KeyType"/> and <see cref="ValueType"/>. + /// </summary> + private void RescanAttributes(params Type[] types) + { + if (types.Length == 0 || types.All(t => t == null)) + return; + + var fields = new List<QueryField>(); + var indexes = new List<QueryIndexEx>(); + + foreach (var type in types.Where(t => t != null)) + ScanAttributes(type, fields, indexes, null, new HashSet<Type>()); + + if (fields.Any()) + Fields = fields; + + if (indexes.Any()) + Indexes = GetGroupIndexes(indexes).ToArray(); + } + + /// <summary> + /// Gets the group indexes. + /// </summary> + /// <param name="indexes">Ungrouped indexes with their group names.</param> + /// <returns></returns> + private static IEnumerable<QueryIndex> GetGroupIndexes(List<QueryIndexEx> indexes) + { + return indexes.Where(idx => idx.IndexGroups != null) + .SelectMany(idx => idx.IndexGroups.Select(g => new {Index = idx, GroupName = g})) + .GroupBy(x => x.GroupName) + .Select(g => + { + var idxs = g.Select(pair => pair.Index).ToArray(); + + var first = idxs.First(); + + return new QueryIndex(idxs.SelectMany(i => i.Fields).ToArray()) + { + IndexType = first.IndexType, + Name = first.Name + }; + }) + .Concat(indexes.Where(idx => idx.IndexGroups == null)); + } + + /// <summary> + /// Scans specified type for occurences of <see cref="QuerySqlFieldAttribute"/>. + /// </summary> + /// <param name="type">The type.</param> + /// <param name="fields">The fields.</param> + /// <param name="indexes">The indexes.</param> + /// <param name="parentPropName">Name of the parent property.</param> + /// <param name="visitedTypes">The visited types.</param> + private static void ScanAttributes(Type type, List<QueryField> fields, List<QueryIndexEx> indexes, + string parentPropName, ISet<Type> visitedTypes) + { + Debug.Assert(type != null); + Debug.Assert(fields != null); + Debug.Assert(indexes != null); + + if (visitedTypes.Contains(type)) + throw new InvalidOperationException("Recursive Query Field definition detected: " + type); + + visitedTypes.Add(type); + + foreach (var memberInfo in GetFieldsAndProperties(type)) + { + var customAttributes = memberInfo.Key.GetCustomAttributes(true); + + foreach (var attr in customAttributes.OfType<QuerySqlFieldAttribute>()) + { + var columnName = attr.Name ?? memberInfo.Key.Name; + + // Dot notation is required for nested SQL fields + if (parentPropName != null) + columnName = parentPropName + "." + columnName; + + fields.Add(new QueryField(columnName, memberInfo.Value)); + + if (attr.IsIndexed) + indexes.Add(new QueryIndexEx(columnName, attr.IsDescending, QueryIndexType.Sorted, + attr.IndexGroups)); + + ScanAttributes(memberInfo.Value, fields, indexes, columnName, visitedTypes); + } + + foreach (var attr in customAttributes.OfType<QueryTextFieldAttribute>()) + { + var columnName = attr.Name ?? memberInfo.Key.Name; + + // No dot notation for FullText index names + indexes.Add(new QueryIndexEx(columnName, false, QueryIndexType.FullText, null)); + + if (parentPropName != null) + columnName = parentPropName + "." + columnName; + + fields.Add(new QueryField(columnName, memberInfo.Value)); + + ScanAttributes(memberInfo.Value, fields, indexes, columnName, visitedTypes); + } + } + + visitedTypes.Remove(type); + } + + /// <summary> + /// Gets the fields and properties. + /// </summary> + /// <param name="type">The type.</param> + /// <returns></returns> + private static IEnumerable<KeyValuePair<MemberInfo, Type>> GetFieldsAndProperties(Type type) + { + Debug.Assert(type != null); + + if (type.IsPrimitive) + yield break; + + var bindingFlags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | + BindingFlags.DeclaredOnly; + + while (type != typeof (object) && type != null) + { + foreach (var fieldInfo in type.GetFields(bindingFlags)) + yield return new KeyValuePair<MemberInfo, Type>(fieldInfo, fieldInfo.FieldType); + + foreach (var propertyInfo in type.GetProperties(bindingFlags)) + yield return new KeyValuePair<MemberInfo, Type>(propertyInfo, propertyInfo.PropertyType); + + type = type.BaseType; + } + } + + /// <summary> + /// Extended index with group names. + /// </summary> + private class QueryIndexEx : QueryIndex + { + /// <summary> + /// Initializes a new instance of the <see cref="QueryIndexEx"/> class. + /// </summary> + /// <param name="fieldName">Name of the field.</param> + /// <param name="isDescending">if set to <c>true</c> [is descending].</param> + /// <param name="indexType">Type of the index.</param> + /// <param name="groups">The groups.</param> + public QueryIndexEx(string fieldName, bool isDescending, QueryIndexType indexType, + ICollection<string> groups) + : base(isDescending, indexType, fieldName) + { + IndexGroups = groups; + } + + /// <summary> + /// Gets or sets the index groups. + /// </summary> + public ICollection<string> IndexGroups { get; set; } + } + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/ee20f1d9/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/QueryField.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/QueryField.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/QueryField.cs new file mode 100644 index 0000000..8c70a29 --- /dev/null +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/QueryField.cs @@ -0,0 +1,109 @@ +/* + * 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. + */ + +// ReSharper disable UnusedAutoPropertyAccessor.Global +// ReSharper disable MemberCanBePrivate.Global +namespace Apache.Ignite.Core.Cache.Configuration +{ + using System; + using Apache.Ignite.Core.Impl.Binary; + using Apache.Ignite.Core.Impl.Common; + + /// <summary> + /// Represents a queryable field. + /// </summary> + public class QueryField + { + /** */ + private Type _type; + + /** */ + private string _fieldTypeName; + + /// <summary> + /// Initializes a new instance of the <see cref="QueryField"/> class. + /// </summary> + public QueryField() + { + // No-op. + } + + /// <summary> + /// Initializes a new instance of the <see cref="QueryField"/> class. + /// </summary> + /// <param name="name">Name.</param> + /// <param name="javaFieldTypeName">Java type name.</param> + public QueryField(string name, string javaFieldTypeName) + { + IgniteArgumentCheck.NotNullOrEmpty(name, "name"); + IgniteArgumentCheck.NotNullOrEmpty(javaFieldTypeName, "typeName"); + + Name = name; + FieldTypeName = javaFieldTypeName; + } + + /// <summary> + /// Initializes a new instance of the <see cref="QueryField" /> class. + /// </summary> + /// <param name="name">Name.</param> + /// <param name="fieldType">Type.</param> + public QueryField(string name, Type fieldType) + { + IgniteArgumentCheck.NotNullOrEmpty(name, "name"); + IgniteArgumentCheck.NotNull(fieldType, "type"); + + Name = name; + FieldType = fieldType; + } + + /// <summary> + /// Gets the field name. + /// </summary> + public string Name { get; set; } + + /// <summary> + /// Gets or sets the type of the value. + /// <para /> + /// This is a shortcut for <see cref="FieldTypeName"/>. Getter will return null for non-primitive types. + /// </summary> + public Type FieldType + { + get { return _type ?? JavaTypes.GetDotNetType(FieldTypeName); } + set + { + FieldTypeName = value == null + ? null + : (JavaTypes.GetJavaTypeName(value) ?? BinaryUtils.GetTypeName(value)); + + _type = value; + } + } + + /// <summary> + /// Gets the Java type name. + /// </summary> + public string FieldTypeName + { + get { return _fieldTypeName; } + set + { + _fieldTypeName = value; + _type = null; + } + } + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ignite/blob/ee20f1d9/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/QueryIndex.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/QueryIndex.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/QueryIndex.cs new file mode 100644 index 0000000..7079606 --- /dev/null +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/QueryIndex.cs @@ -0,0 +1,137 @@ +/* + * 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. + */ + +// ReSharper disable UnusedMember.Global +namespace Apache.Ignite.Core.Cache.Configuration +{ + using System; + using System.Collections.Generic; + using System.Linq; + using Apache.Ignite.Core.Binary; + + /// <summary> + /// Represents cache query index configuration. + /// </summary> + public class QueryIndex + { + /// <summary> + /// Initializes a new instance of the <see cref="QueryIndex"/> class. + /// </summary> + public QueryIndex() + { + // No-op. + } + + /// <summary> + /// Initializes a new instance of the <see cref="QueryIndex" /> class. + /// </summary> + /// <param name="fieldNames">Names of the fields to index.</param> + public QueryIndex(params string[] fieldNames) : this(false, fieldNames) + { + // No-op. + } + + /// <summary> + /// Initializes a new instance of the <see cref="QueryIndex" /> class. + /// </summary> + /// <param name="isDescending">Sort direction.</param> + /// <param name="fieldNames">Names of the fields to index.</param> + public QueryIndex(bool isDescending, params string[] fieldNames) + { + Fields = fieldNames.Select(f => new QueryIndexField(f, isDescending)).ToArray(); + } + + /// <summary> + /// Initializes a new instance of the <see cref="QueryIndex" /> class. + /// </summary> + /// <param name="isDescending">Sort direction.</param> + /// <param name="indexType">Type of the index.</param> + /// <param name="fieldNames">Names of the fields to index.</param> + public QueryIndex(bool isDescending, QueryIndexType indexType, params string[] fieldNames) + : this(isDescending, fieldNames) + { + IndexType = indexType; + } + + /// <summary> + /// Initializes a new instance of the <see cref="QueryIndex"/> class. + /// </summary> + /// <param name="fields">The fields.</param> + public QueryIndex(params QueryIndexField[] fields) + { + if (fields == null || fields.Length == 0) + throw new ArgumentException("Query index must have at least one field"); + + if (fields.Any(f => f == null)) + throw new ArgumentException("IndexField cannot be null."); + + Fields = fields; + } + + /// <summary> + /// Gets or sets the index name. + /// Will be set automatically if not specified. + /// </summary> + public string Name { get; set; } + + /// <summary> + /// Gets or sets the type of the index. + /// </summary> + public QueryIndexType IndexType { get; set; } + + /// <summary> + /// Gets or sets a collection of fields to be indexed. + /// </summary> + public ICollection<QueryIndexField> Fields { get; private set; } + + /// <summary> + /// Initializes a new instance of the <see cref="QueryIndex"/> class. + /// </summary> + /// <param name="reader">The reader.</param> + internal QueryIndex(IBinaryRawReader reader) + { + Name = reader.ReadString(); + IndexType = (QueryIndexType) reader.ReadByte(); + + var count = reader.ReadInt(); + Fields = count == 0 ? null : Enumerable.Range(0, count).Select(x => + new QueryIndexField(reader.ReadString(), reader.ReadBoolean())).ToList(); + } + + /// <summary> + /// Writes this instance. + /// </summary> + internal void Write(IBinaryRawWriter writer) + { + writer.WriteString(Name); + writer.WriteByte((byte) IndexType); + + if (Fields != null) + { + writer.WriteInt(Fields.Count); + + foreach (var field in Fields) + { + writer.WriteString(field.Name); + writer.WriteBoolean(field.IsDescending); + } + } + else + writer.WriteInt(0); + } + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ignite/blob/ee20f1d9/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/QueryIndexField.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/QueryIndexField.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/QueryIndexField.cs new file mode 100644 index 0000000..0b11e9c --- /dev/null +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/QueryIndexField.cs @@ -0,0 +1,66 @@ +/* + * 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.Configuration +{ + using Apache.Ignite.Core.Impl.Common; + + /// <summary> + /// Represents an indexed field. + /// </summary> + public class QueryIndexField + { + /// <summary> + /// Initializes a new instance of the <see cref="QueryIndexField"/> class. + /// </summary> + public QueryIndexField() + { + // No-op. + } + + /// <summary> + /// Initializes a new instance of the <see cref="QueryIndexField"/> class. + /// </summary> + /// <param name="name">The name.</param> + public QueryIndexField(string name) + { + IgniteArgumentCheck.NotNullOrEmpty(name, "name"); + + Name = name; + } + + /// <summary> + /// Initializes a new instance of the <see cref="QueryIndexField"/> class. + /// </summary> + /// <param name="name">The name.</param> + /// <param name="isDescending">Sort direction.</param> + public QueryIndexField(string name, bool isDescending) : this (name) + { + IsDescending = isDescending; + } + + /// <summary> + /// Gets the name. + /// </summary> + public string Name { get; set; } + + /// <summary> + /// Gets a value indicating whether this index is descending. Default is false. + /// </summary> + public bool IsDescending { get; set; } + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/ee20f1d9/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/QueryIndexType.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/QueryIndexType.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/QueryIndexType.cs new file mode 100644 index 0000000..25fed62 --- /dev/null +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/QueryIndexType.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.Configuration +{ + /// <summary> + /// Query index type. + /// </summary> + public enum QueryIndexType + { + /// <summary> + /// Sorted index. + /// </summary> + Sorted, + + /// <summary> + /// Fulltext index. + /// </summary> + FullText, + + /// <summary> + /// Geo-spatial index. + /// </summary> + Geospatial + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ignite/blob/ee20f1d9/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/QuerySqlFieldAttribute.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/QuerySqlFieldAttribute.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/QuerySqlFieldAttribute.cs new file mode 100644 index 0000000..a522115 --- /dev/null +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/QuerySqlFieldAttribute.cs @@ -0,0 +1,60 @@ +/* + * 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.Configuration +{ + using System; + using System.Diagnostics.CodeAnalysis; + + /// <summary> + /// Marks field or property for SQL queries. + /// <para /> + /// Using this attribute is an alternative to <see cref="QueryEntity.Fields"/> in <see cref="CacheConfiguration"/>. + /// </summary> + [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)] + public sealed class QuerySqlFieldAttribute : Attribute + { + /// <summary> + /// Gets or sets the sql field name. + /// If not provided, property or field name will be used. + /// </summary> + public string Name { get; set; } + + /// <summary> + /// Gets or sets a value indicating whether corresponding field should be indexed. + /// Just like with databases, field indexing may require additional overhead during updates, + /// but makes select operations faster. + /// </summary> + public bool IsIndexed { get; set; } + + /// <summary> + /// Gets or sets a value indicating whether index for this field should be descending. + /// Ignored when <see cref="IsIndexed"/> is <c>false</c>. + /// </summary> + public bool IsDescending { get; set; } + + /// <summary> + /// Gets or sets the collection of index groups this field belongs to. + /// Groups are used for compound indexes, + /// whenever index should be created on more than one field. + /// All fields within the same group will belong to the same index. + /// </summary> + [SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays", + Justification = "Attribute initializers do not allow collections")] + public string[] IndexGroups { get; set; } + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/ee20f1d9/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/QueryTextFieldAttribute.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/QueryTextFieldAttribute.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/QueryTextFieldAttribute.cs new file mode 100644 index 0000000..6386496 --- /dev/null +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/QueryTextFieldAttribute.cs @@ -0,0 +1,36 @@ +/* + * 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.Configuration +{ + using System; + + /// <summary> + /// Marks field or property for Text queries. + /// <para /> + /// Using this attribute is an alternative to <see cref="QueryEntity.Fields"/> in <see cref="CacheConfiguration"/>. + /// </summary> + [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)] + public sealed class QueryTextFieldAttribute : Attribute + { + /// <summary> + /// Gets or sets the text field name. + /// If not provided, property or field name will be used. + /// </summary> + public string Name { get; set; } + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ignite/blob/ee20f1d9/modules/platforms/dotnet/Apache.Ignite.Core/Cache/ICache.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Cache/ICache.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Cache/ICache.cs index 192dabf..f5e7cd2 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core/Cache/ICache.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Cache/ICache.cs @@ -22,6 +22,7 @@ namespace Apache.Ignite.Core.Cache using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Threading.Tasks; + using Apache.Ignite.Core.Cache.Configuration; using Apache.Ignite.Core.Cache.Expiry; using Apache.Ignite.Core.Cache.Query; using Apache.Ignite.Core.Cache.Query.Continuous; @@ -66,6 +67,11 @@ namespace Apache.Ignite.Core.Cache IIgnite Ignite { get; } /// <summary> + /// Gets the cache configuration. + /// </summary> + CacheConfiguration GetConfiguration(); + + /// <summary> /// Checks whether this cache contains no key-value mappings. /// <para /> /// Semantically equals to <c>ICache.Size(CachePeekMode.PRIMARY) == 0</c>. http://git-wip-us.apache.org/repos/asf/ignite/blob/ee20f1d9/modules/platforms/dotnet/Apache.Ignite.Core/Common/IFactory.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Common/IFactory.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Common/IFactory.cs new file mode 100644 index 0000000..67c2683 --- /dev/null +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Common/IFactory.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.Common +{ + using System; + + /// <summary> + /// Factory that produces instances of a specific type. + /// Implementation can be passed over the wire and thus should be marked with <see cref="SerializableAttribute"/>. + /// </summary> + public interface IFactory<out T> + { + /// <summary> + /// Creates an instance of the cache store. + /// </summary> + /// <returns>New instance of the cache store.</returns> + T CreateInstance(); + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/ee20f1d9/modules/platforms/dotnet/Apache.Ignite.Core/Discovery/IDiscoverySpi.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Discovery/IDiscoverySpi.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Discovery/IDiscoverySpi.cs new file mode 100644 index 0000000..2fcafbf --- /dev/null +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Discovery/IDiscoverySpi.cs @@ -0,0 +1,32 @@ +/* + * 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.Discovery +{ + using System.Diagnostics.CodeAnalysis; + using Apache.Ignite.Core.Discovery.Tcp; + + /// <summary> + /// Represents a discovery service provider interface. + /// Only predefined implementation is supported now: <see cref="TcpDiscoverySpi"/>. + /// </summary> + [SuppressMessage("Microsoft.Design", "CA1040:AvoidEmptyInterfaces")] + public interface IDiscoverySpi + { + // No-op. + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ignite/blob/ee20f1d9/modules/platforms/dotnet/Apache.Ignite.Core/Discovery/Tcp/ITcpDiscoveryIpFinder.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Discovery/Tcp/ITcpDiscoveryIpFinder.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Discovery/Tcp/ITcpDiscoveryIpFinder.cs new file mode 100644 index 0000000..c2f4329 --- /dev/null +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Discovery/Tcp/ITcpDiscoveryIpFinder.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.Discovery.Tcp +{ + using System.Diagnostics.CodeAnalysis; + using Apache.Ignite.Core.Discovery.Tcp.Multicast; + using Apache.Ignite.Core.Discovery.Tcp.Static; + + /// <summary> + /// Represents an IP finder for <see cref="TcpDiscoverySpi"/>. + /// Only predefined implementations are supported now: + /// <see cref="TcpDiscoveryStaticIpFinder"/>, <see cref="TcpDiscoveryMulticastIpFinder"/>. + /// </summary> + [SuppressMessage("Microsoft.Design", "CA1040:AvoidEmptyInterfaces")] + public interface ITcpDiscoveryIpFinder + { + // No-op. + } +} \ No newline at end of file