You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by ag...@apache.org on 2016/02/04 11:09:24 UTC
[21/50] [abbrv] ignite git commit: IGNITE-1906: .NET: Implemented
programmatic configuration.
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