IGNITE-5784 .NET: QueryIndex.InlineSize
authorPavel Tupitsyn <ptupitsyn@apache.org>
Fri, 29 Sep 2017 08:35:38 +0000 (11:35 +0300)
committerPavel Tupitsyn <ptupitsyn@apache.org>
Fri, 29 Sep 2017 08:35:38 +0000 (11:35 +0300)
This closes #2771

16 files changed:
modules/core/src/main/java/org/apache/ignite/cache/QueryIndex.java
modules/core/src/main/java/org/apache/ignite/cache/query/annotations/QueryGroupIndex.java
modules/core/src/main/java/org/apache/ignite/internal/processors/platform/utils/PlatformConfigurationUtils.java
modules/platforms/dotnet/Apache.Ignite.Core.Tests/Apache.Ignite.Core.Tests.csproj
modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/CacheConfigurationTest.cs
modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/CacheQueriesCodeConfigurationTest.cs
modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/CacheQueriesTest.cs
modules/platforms/dotnet/Apache.Ignite.Core.Tests/Config/cache-query.xml
modules/platforms/dotnet/Apache.Ignite.Core.Tests/Config/full-config.xml [new file with mode: 0644]
modules/platforms/dotnet/Apache.Ignite.Core.Tests/IgniteConfigurationSerializerTest.cs
modules/platforms/dotnet/Apache.Ignite.Core.Tests/IgniteConfigurationTest.cs
modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/CacheConfiguration.cs
modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/QueryEntity.cs
modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/QueryIndex.cs
modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/QuerySqlFieldAttribute.cs
modules/platforms/dotnet/Apache.Ignite.Core/IgniteConfigurationSection.xsd

index f83f85c..8dc9c79 100644 (file)
@@ -21,6 +21,9 @@ import java.util.Arrays;
 import java.util.Collection;
 import java.util.LinkedHashMap;
 import java.util.Objects;
+
+import org.apache.ignite.cache.query.annotations.QueryGroupIndex;
+import org.apache.ignite.configuration.CacheConfiguration;
 import org.apache.ignite.internal.util.tostring.GridToStringInclude;
 import org.apache.ignite.internal.util.typedef.F;
 import org.apache.ignite.internal.util.typedef.internal.S;
@@ -252,16 +255,38 @@ public class QueryIndex implements Serializable {
     }
 
     /**
-     * Gets inline size.
+     * Gets index inline size in bytes. When enabled part of indexed value will be placed directly to index pages,
+     * thus minimizing data page accesses, thus increasing query performance.
+     * <p>
+     * Allowed values:
+     * <ul>
+     *     <li>{@code -1} (default) - determine inline size automatically (see below)</li>
+     *     <li>{@code 0} - index inline is disabled (not recommended)</li>
+     *     <li>positive value - fixed index inline</li>
+     * </ul>
+     * When set to {@code -1}, Ignite will try to detect inline size automatically. It will be no more than
+     * {@link CacheConfiguration#getSqlIndexMaxInlineSize()}. Index inline will be enabled for all fixed-length types,
+     * but <b>will not be enabled</b> for {@code String}.
      *
-     * @return inline size.
+     * @return Index inline size in bytes.
      */
     public int getInlineSize() {
         return inlineSize;
     }
 
     /**
-     * Sets inline size.
+     * Sets index inline size in bytes. When enabled part of indexed value will be placed directly to index pages,
+     * thus minimizing data page accesses, thus increasing query performance.
+     * <p>
+     * Allowed values:
+     * <ul>
+     *     <li>{@code -1} (default) - determine inline size automatically (see below)</li>
+     *     <li>{@code 0} - index inline is disabled (not recommended)</li>
+     *     <li>positive value - fixed index inline</li>
+     * </ul>
+     * When set to {@code -1}, Ignite will try to detect inline size automatically. It will be no more than
+     * {@link CacheConfiguration#getSqlIndexMaxInlineSize()}. Index inline will be enabled for all fixed-length types,
+     * but <b>will not be enabled</b> for {@code String}.
      *
      * @param inlineSize Inline size.
      * @return {@code this} for chaining.
index a947d0f..9670c32 100644 (file)
@@ -39,7 +39,7 @@ public @interface QueryGroupIndex {
 
     /**
      * Index inline size in bytes. When enabled part of indexed value will be placed directly to index pages,
-     * thus minimizing data page accesses, thus incraesing query performance.
+     * thus minimizing data page accesses, thus increasing query performance.
      * <p>
      * Allowed values:
      * <ul>
index aa4f168..e223193 100644 (file)
@@ -194,6 +194,8 @@ public class PlatformConfigurationUtils {
         if (storeFactory != null)
             ccfg.setCacheStoreFactory(new PlatformDotNetCacheStoreFactoryNative(storeFactory));
 
+        ccfg.setSqlIndexMaxInlineSize(in.readInt());
+
         int qryEntCnt = in.readInt();
 
         if (qryEntCnt > 0) {
@@ -518,6 +520,7 @@ public class PlatformConfigurationUtils {
 
         res.setName(in.readString());
         res.setIndexType(QueryIndexType.values()[in.readByte()]);
+        res.setInlineSize(in.readInt());
 
         int cnt = in.readInt();
 
@@ -869,6 +872,8 @@ public class PlatformConfigurationUtils {
         else
             writer.writeObject(null);
 
+        writer.writeInt(ccfg.getSqlIndexMaxInlineSize());
+
         Collection<QueryEntity> qryEntities = ccfg.getQueryEntities();
 
         if (qryEntities != null) {
@@ -985,6 +990,7 @@ public class PlatformConfigurationUtils {
 
         writer.writeString(index.getName());
         writeEnumByte(writer, index.getIndexType());
+        writer.writeInt(index.getInlineSize());
 
         LinkedHashMap<String, Boolean> fields = index.getFields();
 
index 7f5f4b8..ec85ca2 100644 (file)
     <Content Include="Config\Dynamic\dynamic-data.xml">
       <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
     </Content>
+    <Content Include="Config\full-config.xml">
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+    </Content>
     <Content Include="Config\Lifecycle\lifecycle-beans.xml">
       <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
     </Content>
index b400ef6..4e5d443 100644 (file)
@@ -302,6 +302,7 @@ namespace Apache.Ignite.Core.Tests.Cache
             Assert.AreEqual(x.WriteBehindCoalescing, y.WriteBehindCoalescing);
             Assert.AreEqual(x.GroupName, y.GroupName);
             Assert.AreEqual(x.WriteSynchronizationMode, y.WriteSynchronizationMode);
+            Assert.AreEqual(x.SqlIndexMaxInlineSize, y.SqlIndexMaxInlineSize);
 
             if (x.ExpiryPolicyFactory != null)
             {
@@ -494,6 +495,7 @@ namespace Apache.Ignite.Core.Tests.Cache
 
             Assert.AreEqual(x.Name, y.Name);
             Assert.AreEqual(x.IndexType, y.IndexType);
+            Assert.AreEqual(x.InlineSize, y.InlineSize);
 
             AssertConfigsAreEqual(x.Fields, y.Fields);
         }
@@ -594,7 +596,8 @@ namespace Apache.Ignite.Core.Tests.Cache
                             new QueryIndex(new QueryIndexField("location", true))
                             {
                                 Name= "index2",
-                                IndexType = QueryIndexType.FullText
+                                IndexType = QueryIndexType.FullText,
+                                InlineSize = 1024
                             }
                         }
                     }
@@ -624,7 +627,8 @@ namespace Apache.Ignite.Core.Tests.Cache
                 EnableStatistics = true,
                 MemoryPolicyName = "myMemPolicy",
                 PartitionLossPolicy = PartitionLossPolicy.ReadOnlySafe,
-                PluginConfigurations = new[] { new MyPluginConfiguration() }
+                PluginConfigurations = new[] { new MyPluginConfiguration() },
+                SqlIndexMaxInlineSize = 10000
             };
         }
         /// <summary>
@@ -795,7 +799,7 @@ namespace Apache.Ignite.Core.Tests.Cache
 
             public void WriteBinary(IBinaryRawWriter writer)
             {
-                throw new NotImplementedException();
+                throw new NotSupportedException();
             }
         }
     }
index e25ddc0..7421b95 100644 (file)
@@ -42,21 +42,35 @@ namespace Apache.Ignite.Core.Tests.Cache.Query
         {
             var cfg = new IgniteConfiguration(TestUtils.GetTestConfiguration())
             {
-                BinaryConfiguration = new BinaryConfiguration(typeof (QueryPerson)),
+                BinaryConfiguration = new BinaryConfiguration(typeof(QueryPerson)),
                 CacheConfiguration = new[]
                 {
-                    new CacheConfiguration(CacheName, new QueryEntity(typeof (int), typeof (QueryPerson))
+                    new CacheConfiguration(CacheName, new QueryEntity(typeof(int), typeof(QueryPerson))
                     {
                         TableName = "CustomTableName",
                         Fields = new[]
                         {
-                            new QueryField("Name", typeof (string)),
-                            new QueryField("Age", typeof (int)),
+                            new QueryField("Name", typeof(string)),
+                            new QueryField("Age", typeof(int)),
                             new QueryField("Birthday", typeof(DateTime)),
                         },
                         Indexes = new[]
                         {
-                            new QueryIndex(false, QueryIndexType.FullText, "Name"), new QueryIndex("Age")
+                            new QueryIndex
+                            {
+                                InlineSize = 2048,
+                                IndexType = QueryIndexType.FullText,
+                                Fields = new[]
+                                {
+                                    new QueryIndexField
+                                    {
+                                        IsDescending = false,
+                                        Name = "Name"
+                                    }
+                                }
+
+                            },
+                            new QueryIndex("Age")
                         }
                     })
                 }
@@ -122,6 +136,11 @@ namespace Apache.Ignite.Core.Tests.Cache.Query
             CollectionAssert.AreEquivalent(new[] {"GroupIndex1", "GroupIndex3"}, idx[1].Fields.Select(f => f.Name));
             CollectionAssert.AreEquivalent(new[] {"IndexedField1"}, idx[2].Fields.Select(f => f.Name));
             CollectionAssert.AreEquivalent(new[] {"FullTextField"}, idx[3].Fields.Select(f => f.Name));
+
+            Assert.AreEqual(-1, idx[0].InlineSize);
+            Assert.AreEqual(-1, idx[1].InlineSize);
+            Assert.AreEqual(513, idx[2].InlineSize);
+            Assert.AreEqual(-1, idx[3].InlineSize);
         }
 
         /// <summary>
@@ -298,7 +317,7 @@ namespace Apache.Ignite.Core.Tests.Cache.Query
             [QuerySqlField]
             public double SqlField { get; set; }
 
-            [QuerySqlField(IsIndexed = true, Name = "IndexedField1", IsDescending = true)]
+            [QuerySqlField(IsIndexed = true, Name = "IndexedField1", IsDescending = true, IndexInlineSize = 513)]
             public int IndexedField { get; set; }
 
             [QueryTextField]
index 65ab18c..6361850 100644 (file)
@@ -421,6 +421,37 @@ namespace Apache.Ignite.Core.Tests.Cache.Query
         }
 
         /// <summary>
+        /// Tests that query configuration propagates from Spring XML correctly.
+        /// </summary>
+        [Test]
+        public void TestQueryConfiguration()
+        {
+            var qe = Cache().GetConfiguration().QueryEntities.Single();
+
+            Assert.AreEqual(typeof(QueryPerson).FullName, qe.ValueTypeName);
+
+            var age = qe.Fields.First();
+            Assert.AreEqual("age", age.Name);
+            Assert.AreEqual(typeof(int), age.FieldType);
+            Assert.IsFalse(age.IsKeyField);
+
+            var name = qe.Fields.Last();
+            Assert.AreEqual("name", name.Name);
+            Assert.AreEqual(typeof(string), name.FieldType);
+            Assert.IsFalse(name.IsKeyField);
+
+            var textIdx = qe.Indexes.First();
+            Assert.AreEqual(QueryIndexType.FullText, textIdx.IndexType);
+            Assert.AreEqual("name", textIdx.Fields.Single().Name);
+            Assert.AreEqual(QueryIndex.DefaultInlineSize, textIdx.InlineSize);
+
+            var sqlIdx = qe.Indexes.Last();
+            Assert.AreEqual(QueryIndexType.Sorted, sqlIdx.IndexType);
+            Assert.AreEqual("age", sqlIdx.Fields.Single().Name);
+            Assert.AreEqual(2345, sqlIdx.InlineSize);
+        }
+
+        /// <summary>
         /// Check text query.
         /// </summary>
         [Test]
index 2b41efa..3b61d8d 100644 (file)
@@ -83,6 +83,7 @@
                                                 </map>
                                             </property>
                                             <property name="indexType" value="SORTED"/>
+                                            <property name="inlineSize" value="2345"/>
                                         </bean>
                                     </list>
                                 </property>
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Config/full-config.xml b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Config/full-config.xml
new file mode 100644 (file)
index 0000000..f6854e1
--- /dev/null
@@ -0,0 +1,134 @@
+<?xml version="1.0" encoding="utf-8" ?>
+
+<!--
+  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.
+-->
+
+<!-- Full XML config with all properties having custom values. -->
+
+<igniteConfiguration
+              workDirectory='c:' JvmMaxMemoryMb='1024' MetricsLogFrequency='0:0:10' isDaemon='true' 
+              isLateAffinityAssignment='false' springConfigUrl='c:\myconfig.xml' autoGenerateIgniteInstanceName='true' 
+              peerAssemblyLoadingMode='CurrentAppDomain' longQueryWarningTimeout='1:2:3' isActiveOnStart='false' 
+              consistentId='someId012'>
+    <localhost>127.1.1.1</localhost>
+    <binaryConfiguration compactFooter='false' keepDeserialized='true'>
+        <nameMapper type='Apache.Ignite.Core.Tests.IgniteConfigurationSerializerTest+NameMapper' bar='testBar' />
+        <idMapper type='Apache.Ignite.Core.Tests.Binary.IdMapper' />
+        <types>
+            <string>Apache.Ignite.Core.Tests.IgniteConfigurationSerializerTest+FooClass, Apache.Ignite.Core.Tests</string>
+        </types>
+        <typeConfigurations>
+            <binaryTypeConfiguration affinityKeyFieldName='affKeyFieldName' isEnum='true' keepDeserialized='True' typeName='typeName'>
+                <idMapper type='Apache.Ignite.Core.Tests.Binary.IdMapper, Apache.Ignite.Core.Tests' />
+                <nameMapper type='Apache.Ignite.Core.Tests.IgniteConfigurationSerializerTest+NameMapper, Apache.Ignite.Core.Tests' />
+                <serializer type='Apache.Ignite.Core.Tests.IgniteConfigurationSerializerTest+TestSerializer, Apache.Ignite.Core.Tests' />
+            </binaryTypeConfiguration>
+        </typeConfigurations>
+    </binaryConfiguration>
+    <discoverySpi type='TcpDiscoverySpi' joinTimeout='0:1:0' localAddress='192.168.1.1' localPort='6655'>
+        <ipFinder type='TcpDiscoveryMulticastIpFinder' addressRequestAttempts='7' />
+    </discoverySpi>
+    <communicationSpi type='TcpCommunicationSpi' ackSendThreshold='33' idleConnectionTimeout='0:1:2' />
+    <jvmOptions>
+        <string>-Xms1g</string>
+        <string>-Xmx4g</string>
+    </jvmOptions>
+    <lifecycleHandlers>
+        <iLifecycleHandler type='Apache.Ignite.Core.Tests.IgniteConfigurationSerializerTest+LifecycleBean' foo='15' />
+    </lifecycleHandlers>
+    <cacheConfiguration>
+        <cacheConfiguration cacheMode='Replicated' readThrough='true' writeThrough='true' enableStatistics='true' writeBehindCoalescing='false' partitionLossPolicy='ReadWriteAll' groupName='fooGroup'>
+            <queryEntities>
+                <queryEntity keyType='System.Int32' valueType='System.String' tableName='myTable'>
+                    <fields>
+                        <queryField name='length' fieldType='System.Int32' isKeyField='true' />
+                    </fields>
+                    <aliases>
+                        <queryAlias fullName='somefield.field' alias='shortField' />
+                    </aliases>
+                    <indexes>
+                        <queryIndex name='idx' indexType='Geospatial' inlineSize='123'>
+                            <fields>
+                                <queryIndexField name='indexFld' isDescending='true' />
+                            </fields>
+                        </queryIndex>
+                    </indexes>
+                </queryEntity>
+            </queryEntities>
+            <evictionPolicy type='LruEvictionPolicy' batchSize='1' maxSize='2' maxMemorySize='3' />
+            <nearConfiguration nearStartSize='7'>
+                <evictionPolicy type='FifoEvictionPolicy' batchSize='10' maxSize='20' maxMemorySize='30' />
+            </nearConfiguration>
+            <affinityFunction type='RendezvousAffinityFunction' partitions='99' excludeNeighbors='true' />
+            <expiryPolicyFactory type='Apache.Ignite.Core.Tests.IgniteConfigurationSerializerTest+MyPolicyFactory, Apache.Ignite.Core.Tests' />
+            <pluginConfigurations>
+                <iCachePluginConfiguration type='Apache.Ignite.Core.Tests.IgniteConfigurationSerializerTest+MyPluginConfiguration, Apache.Ignite.Core.Tests' />
+            </pluginConfigurations>
+        </cacheConfiguration>
+        <cacheConfiguration name='secondCache' />
+    </cacheConfiguration>
+    <includedEventTypes>
+        <int>42</int>
+        <int>TaskFailed</int>
+        <int>JobFinished</int>
+    </includedEventTypes>
+    <userAttributes>
+        <pair key='myNode' value='true' />
+        <pair key='foo'>
+            <value type='Apache.Ignite.Core.Tests.IgniteConfigurationSerializerTest+FooClass, Apache.Ignite.Core.Tests'>
+                <bar>Baz</bar>
+            </value>
+        </pair>
+    </userAttributes>
+    <atomicConfiguration backups='2' cacheMode='Local' atomicSequenceReserveSize='250' />
+    <transactionConfiguration defaultTransactionConcurrency='Optimistic' defaultTransactionIsolation='RepeatableRead' defaultTimeout='0:1:2' pessimisticTransactionLogSize='15' pessimisticTransactionLogLinger='0:0:33' />
+    <logger type='Apache.Ignite.Core.Tests.IgniteConfigurationSerializerTest+TestLogger, Apache.Ignite.Core.Tests' />
+    <pluginConfigurations>
+        <iPluginConfiguration type='Apache.Ignite.Core.Tests.Plugin.TestIgnitePluginConfiguration, Apache.Ignite.Core.Tests' />
+    </pluginConfigurations>
+    <eventStorageSpi type='MemoryEventStorageSpi' expirationTimeout='00:00:23.45' maxEventCount='129' />
+    <memoryConfiguration concurrencyLevel='3' defaultMemoryPolicyName='dfPlc' pageSize='45' systemCacheInitialSize='67' systemCacheMaxSize='68'>
+        <memoryPolicies>
+            <memoryPolicyConfiguration emptyPagesPoolSize='1' evictionThreshold='0.2' name='dfPlc' pageEvictionMode='RandomLru' initialSize='89' maxSize='98' swapFilePath='abc' metricsEnabled='true' rateTimeInterval='0:1:2' subIntervals='9' />
+        </memoryPolicies>
+    </memoryConfiguration>
+    <sqlConnectorConfiguration host='bar' port='10' portRange='11' socketSendBufferSize='12' socketReceiveBufferSize='13' tcpNoDelay='true' maxOpenCursorsPerConnection='14' threadPoolSize='15' />
+    <clientConnectorConfiguration host='bar' port='10' portRange='11' socketSendBufferSize='12' socketReceiveBufferSize='13' tcpNoDelay='true' maxOpenCursorsPerConnection='14' threadPoolSize='15' />
+    <persistentStoreConfiguration alwaysWriteFullPages='true' checkpointingFrequency='00:00:1' checkpointingPageBufferSize='2' 
+                                  checkpointingThreads='3' lockWaitTime='00:00:04' persistentStorePath='foo' tlbSize='5' 
+                                  walArchivePath='bar' walFlushFrequency='00:00:06' walFsyncDelayNanos='7' walHistorySize='8' 
+                                  walMode='None' walRecordIteratorBufferSize='9' walSegments='10' walSegmentSize='11' 
+                                  walStorePath='baz' metricsEnabled='true' rateTimeInterval='0:0:6' subIntervals='3' 
+                                  checkpointWriteOrder='Random' writeThrottlingEnabled='true' />
+    <consistentId type='System.String'>someId012</consistentId>
+    <localEventListeners>
+        <localEventListener type='Apache.Ignite.Core.Events.LocalEventListener`1[[Apache.Ignite.Core.Events.CacheRebalancingEvent]]'>
+            <eventTypes>
+                <int>CacheObjectPut</int>
+                <int>81</int>
+            </eventTypes>
+            <listener type='Apache.Ignite.Core.Tests.EventsTestLocalListeners+Listener`1[[Apache.Ignite.Core.Events.CacheRebalancingEvent]]' />
+        </localEventListener>
+        <localEventListener type='Apache.Ignite.Core.Events.LocalEventListener`1[[Apache.Ignite.Core.Events.IEvent]]'>
+            <eventTypes>
+                <int>CacheObjectPut</int>
+                <int>81</int>
+            </eventTypes>
+            <listener type='Apache.Ignite.Core.Tests.IgniteConfigurationSerializerTest+MyEventListener' />
+        </localEventListener>
+    </localEventListeners>
+</igniteConfiguration>
\ No newline at end of file
index 83700cb..b04f466 100644 (file)
@@ -67,101 +67,7 @@ namespace Apache.Ignite.Core.Tests
         [Test]
         public void TestPredefinedXml()
         {
-            var xml = @"<igniteConfig workDirectory='c:' JvmMaxMemoryMb='1024' MetricsLogFrequency='0:0:10' isDaemon='true' isLateAffinityAssignment='false' springConfigUrl='c:\myconfig.xml' autoGenerateIgniteInstanceName='true' peerAssemblyLoadingMode='CurrentAppDomain' longQueryWarningTimeout='1:2:3' isActiveOnStart='false' consistentId='someId012'>
-                            <localhost>127.1.1.1</localhost>
-                            <binaryConfiguration compactFooter='false' keepDeserialized='true'>
-                                <nameMapper type='Apache.Ignite.Core.Tests.IgniteConfigurationSerializerTest+NameMapper' bar='testBar' />
-                                <idMapper type='Apache.Ignite.Core.Tests.Binary.IdMapper' />
-                                <types>
-                                    <string>Apache.Ignite.Core.Tests.IgniteConfigurationSerializerTest+FooClass, Apache.Ignite.Core.Tests</string>
-                                </types>
-                                <typeConfigurations>
-                                    <binaryTypeConfiguration affinityKeyFieldName='affKeyFieldName' isEnum='true' keepDeserialized='True' typeName='typeName'>
-                                        <idMapper type='Apache.Ignite.Core.Tests.Binary.IdMapper, Apache.Ignite.Core.Tests' />
-                                        <nameMapper type='Apache.Ignite.Core.Tests.IgniteConfigurationSerializerTest+NameMapper, Apache.Ignite.Core.Tests' />
-                                        <serializer type='Apache.Ignite.Core.Tests.IgniteConfigurationSerializerTest+TestSerializer, Apache.Ignite.Core.Tests' />
-                                    </binaryTypeConfiguration>
-                                </typeConfigurations>
-                            </binaryConfiguration>
-                            <discoverySpi type='TcpDiscoverySpi' joinTimeout='0:1:0' localAddress='192.168.1.1' localPort='6655'>
-                                <ipFinder type='TcpDiscoveryMulticastIpFinder' addressRequestAttempts='7' />
-                            </discoverySpi>
-                            <communicationSpi type='TcpCommunicationSpi' ackSendThreshold='33' idleConnectionTimeout='0:1:2' />
-                            <jvmOptions><string>-Xms1g</string><string>-Xmx4g</string></jvmOptions>
-                            <lifecycleHandlers>
-                                <iLifecycleHandler type='Apache.Ignite.Core.Tests.IgniteConfigurationSerializerTest+LifecycleBean' foo='15' />
-                            </lifecycleHandlers>
-                            <cacheConfiguration>
-                                <cacheConfiguration cacheMode='Replicated' readThrough='true' writeThrough='true' enableStatistics='true' writeBehindCoalescing='false' partitionLossPolicy='ReadWriteAll' groupName='fooGroup'>
-                                    <queryEntities>    
-                                        <queryEntity keyType='System.Int32' valueType='System.String' tableName='myTable'>
-                                            <fields>
-                                                <queryField name='length' fieldType='System.Int32' isKeyField='true' />
-                                            </fields>
-                                            <aliases>
-                                                <queryAlias fullName='somefield.field' alias='shortField' />
-                                            </aliases>
-                                            <indexes>
-                                                <queryIndex name='idx' indexType='Geospatial'>
-                                                    <fields>
-                                                        <queryIndexField name='indexFld' isDescending='true' />
-                                                    </fields>
-                                                </queryIndex>
-                                            </indexes>
-                                        </queryEntity>
-                                    </queryEntities>
-                                    <evictionPolicy type='LruEvictionPolicy' batchSize='1' maxSize='2' maxMemorySize='3' />
-                                    <nearConfiguration nearStartSize='7'>
-                                        <evictionPolicy type='FifoEvictionPolicy' batchSize='10' maxSize='20' maxMemorySize='30' />
-                                    </nearConfiguration>
-                                    <affinityFunction type='RendezvousAffinityFunction' partitions='99' excludeNeighbors='true' />
-                                    <expiryPolicyFactory type='Apache.Ignite.Core.Tests.IgniteConfigurationSerializerTest+MyPolicyFactory, Apache.Ignite.Core.Tests' />
-                                    <pluginConfigurations><iCachePluginConfiguration type='Apache.Ignite.Core.Tests.IgniteConfigurationSerializerTest+MyPluginConfiguration, Apache.Ignite.Core.Tests' /></pluginConfigurations>
-                                </cacheConfiguration>
-                                <cacheConfiguration name='secondCache' />
-                            </cacheConfiguration>
-                            <includedEventTypes>
-                                <int>42</int>
-                                <int>TaskFailed</int>
-                                <int>JobFinished</int>
-                            </includedEventTypes>
-                            <userAttributes>
-                                <pair key='myNode' value='true' />
-                                <pair key='foo'><value type='Apache.Ignite.Core.Tests.IgniteConfigurationSerializerTest+FooClass, Apache.Ignite.Core.Tests'><bar>Baz</bar></value></pair>
-                            </userAttributes>
-                            <atomicConfiguration backups='2' cacheMode='Local' atomicSequenceReserveSize='250' />
-                            <transactionConfiguration defaultTransactionConcurrency='Optimistic' defaultTransactionIsolation='RepeatableRead' defaultTimeout='0:1:2' pessimisticTransactionLogSize='15' pessimisticTransactionLogLinger='0:0:33' />
-                            <logger type='Apache.Ignite.Core.Tests.IgniteConfigurationSerializerTest+TestLogger, Apache.Ignite.Core.Tests' />
-                            <pluginConfigurations>
-                                <iPluginConfiguration type='Apache.Ignite.Core.Tests.Plugin.TestIgnitePluginConfiguration, Apache.Ignite.Core.Tests' />
-                            </pluginConfigurations>
-                            <eventStorageSpi type='MemoryEventStorageSpi' expirationTimeout='00:00:23.45' maxEventCount='129' />
-                            <memoryConfiguration concurrencyLevel='3' defaultMemoryPolicyName='dfPlc' pageSize='45' systemCacheInitialSize='67' systemCacheMaxSize='68'>
-                                <memoryPolicies>
-                                    <memoryPolicyConfiguration emptyPagesPoolSize='1' evictionThreshold='0.2' name='dfPlc' pageEvictionMode='RandomLru' initialSize='89' maxSize='98' swapFilePath='abc' metricsEnabled='true' rateTimeInterval='0:1:2' subIntervals='9' />
-                                </memoryPolicies>
-                            </memoryConfiguration>
-                            <sqlConnectorConfiguration host='bar' port='10' portRange='11' socketSendBufferSize='12' socketReceiveBufferSize='13' tcpNoDelay='true' maxOpenCursorsPerConnection='14' threadPoolSize='15' />
-                            <clientConnectorConfiguration host='bar' port='10' portRange='11' socketSendBufferSize='12' socketReceiveBufferSize='13' tcpNoDelay='true' maxOpenCursorsPerConnection='14' threadPoolSize='15' />
-                            <persistentStoreConfiguration alwaysWriteFullPages='true' checkpointingFrequency='00:00:1' checkpointingPageBufferSize='2' checkpointingThreads='3' lockWaitTime='00:00:04' persistentStorePath='foo' tlbSize='5' walArchivePath='bar' walFlushFrequency='00:00:06' walFsyncDelayNanos='7' walHistorySize='8' walMode='None' walRecordIteratorBufferSize='9' walSegments='10' walSegmentSize='11' walStorePath='baz' metricsEnabled='true' rateTimeInterval='0:0:6' subIntervals='3' checkpointWriteOrder='Random' writeThrottlingEnabled='true' />
-                            <consistentId type='System.String'>someId012</consistentId>
-                            <localEventListeners>
-                              <localEventListener type='Apache.Ignite.Core.Events.LocalEventListener`1[[Apache.Ignite.Core.Events.CacheRebalancingEvent]]'>
-                                <eventTypes>
-                                  <int>CacheObjectPut</int>
-                                  <int>81</int>
-                                </eventTypes>
-                                <listener type='Apache.Ignite.Core.Tests.EventsTestLocalListeners+Listener`1[[Apache.Ignite.Core.Events.CacheRebalancingEvent]]' />
-                            </localEventListener>
-                              <localEventListener type='Apache.Ignite.Core.Events.LocalEventListener`1[[Apache.Ignite.Core.Events.IEvent]]'>
-                                <eventTypes>
-                                  <int>CacheObjectPut</int>
-                                  <int>81</int>
-                                </eventTypes>
-                                <listener type='Apache.Ignite.Core.Tests.IgniteConfigurationSerializerTest+MyEventListener' />
-                            </localEventListener>
-                          </localEventListeners>
-                        </igniteConfig>";
+            var xml = File.ReadAllText("Config\\full-config.xml");
 
             var cfg = IgniteConfiguration.FromXml(xml);
 
@@ -211,9 +117,12 @@ namespace Apache.Ignite.Core.Tests
             Assert.IsTrue(queryEntity.Fields.Single().IsKeyField);
             Assert.AreEqual("somefield.field", queryEntity.Aliases.Single().FullName);
             Assert.AreEqual("shortField", queryEntity.Aliases.Single().Alias);
-            Assert.AreEqual(QueryIndexType.Geospatial, queryEntity.Indexes.Single().IndexType);
-            Assert.AreEqual("indexFld", queryEntity.Indexes.Single().Fields.Single().Name);
-            Assert.AreEqual(true, queryEntity.Indexes.Single().Fields.Single().IsDescending);
+
+            var queryIndex = queryEntity.Indexes.Single();
+            Assert.AreEqual(QueryIndexType.Geospatial, queryIndex.IndexType);
+            Assert.AreEqual("indexFld", queryIndex.Fields.Single().Name);
+            Assert.AreEqual(true, queryIndex.Fields.Single().IsDescending);
+            Assert.AreEqual(123, queryIndex.InlineSize);
 
             var nearCfg = cacheCfg.NearConfiguration;
             Assert.IsNotNull(nearCfg);
@@ -695,7 +604,11 @@ namespace Apache.Ignite.Core.Tests
                                 },
                                 Indexes = new[]
                                 {
-                                    new QueryIndex("field") {IndexType = QueryIndexType.FullText}
+                                    new QueryIndex("field")
+                                    {
+                                        IndexType = QueryIndexType.FullText,
+                                        InlineSize = 32
+                                    }
                                 },
                                 Aliases = new[]
                                 {
@@ -747,7 +660,8 @@ namespace Apache.Ignite.Core.Tests
                         },
                         MemoryPolicyName = "somePolicy",
                         PartitionLossPolicy = PartitionLossPolicy.ReadOnlyAll,
-                        GroupName = "abc"
+                        GroupName = "abc",
+                        SqlIndexMaxInlineSize = 24
                     }
                 },
                 ClientMode = true,
index efa404d..3fd4772 100644 (file)
@@ -92,6 +92,7 @@ namespace Apache.Ignite.Core.Tests
             CheckDefaultValueAttributes(new ClientConnectorConfiguration());
             CheckDefaultValueAttributes(new PersistentStoreConfiguration());
             CheckDefaultValueAttributes(new IgniteClientConfiguration());
+            CheckDefaultValueAttributes(new QueryIndex());
         }
 
         /// <summary>
index 9413ed5..c6b81f0 100644 (file)
@@ -137,6 +137,9 @@ namespace Apache.Ignite.Core.Cache.Configuration
         /// <summary> Default value for <see cref="PartitionLossPolicy"/>. </summary>
         public const PartitionLossPolicy DefaultPartitionLossPolicy = PartitionLossPolicy.Ignore;
 
+        /// <summary> Default value for <see cref="SqlIndexMaxInlineSize"/>. </summary>
+        public const int DefaultSqlIndexMaxInlineSize = -1;
+
         /// <summary>
         /// Gets or sets the cache name.
         /// </summary>
@@ -184,6 +187,7 @@ namespace Apache.Ignite.Core.Cache.Configuration
             WriteBehindFlushThreadCount= DefaultWriteBehindFlushThreadCount;
             WriteBehindCoalescing = DefaultWriteBehindCoalescing;
             PartitionLossPolicy = DefaultPartitionLossPolicy;
+            SqlIndexMaxInlineSize = DefaultSqlIndexMaxInlineSize;
         }
 
         /// <summary>
@@ -286,6 +290,7 @@ namespace Apache.Ignite.Core.Cache.Configuration
             PartitionLossPolicy = (PartitionLossPolicy) reader.ReadInt();
             GroupName = reader.ReadString();
             CacheStoreFactory = reader.ReadObject<IFactory<ICacheStore>>();
+            SqlIndexMaxInlineSize = reader.ReadInt();
 
             var count = reader.ReadInt();
             QueryEntities = count == 0
@@ -365,6 +370,7 @@ namespace Apache.Ignite.Core.Cache.Configuration
             writer.WriteInt((int) PartitionLossPolicy);
             writer.WriteString(GroupName);
             writer.WriteObject(CacheStoreFactory);
+            writer.WriteInt(SqlIndexMaxInlineSize);
 
             if (QueryEntities != null)
             {
@@ -769,5 +775,12 @@ namespace Apache.Ignite.Core.Cache.Configuration
         /// Grouping caches reduces overall overhead, since internal data structures are shared.
         /// </summary>
         public string GroupName { get;set; }
+
+        /// <summary>
+        /// Gets or sets maximum inline size in bytes for sql indexes. See also <see cref="QueryIndex.InlineSize"/>.
+        /// -1 for automatic.
+        /// </summary>
+        [DefaultValue(DefaultSqlIndexMaxInlineSize)]
+        public int SqlIndexMaxInlineSize { get; set; }
     }
 }
index 1273f08..b40231c 100644 (file)
@@ -454,7 +454,10 @@ namespace Apache.Ignite.Core.Cache.Configuration
                     if (attr.IsIndexed)
                     {
                         indexes.Add(new QueryIndexEx(columnName, attr.IsDescending, QueryIndexType.Sorted,
-                            attr.IndexGroups));
+                            attr.IndexGroups)
+                        {
+                            InlineSize = attr.IndexInlineSize
+                        });
                     }
 
                     fields.Add(new QueryField(columnName, memberInfo.Value) {IsKeyField = isKey});
index 7079606..d109111 100644 (file)
@@ -20,6 +20,8 @@ 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;
 
@@ -29,9 +31,17 @@ namespace Apache.Ignite.Core.Cache.Configuration
     public class QueryIndex
     {
         /// <summary>
+        /// Default value for <see cref="InlineSize"/>.
+        /// </summary>
+        public const int DefaultInlineSize = -1;
+
+        /** Inline size. */
+        private int _inlineSize = DefaultInlineSize;
+
+        /// <summary>
         /// Initializes a new instance of the <see cref="QueryIndex"/> class.
         /// </summary>
-        public QueryIndex()
+        public QueryIndex() : this((string[]) null)
         {
             // No-op.
         }
@@ -50,9 +60,10 @@ namespace Apache.Ignite.Core.Cache.Configuration
         /// </summary>
         /// <param name="isDescending">Sort direction.</param>
         /// <param name="fieldNames">Names of the fields to index.</param>
-        public QueryIndex(bool isDescending, params string[] fieldNames)
+        public QueryIndex(bool isDescending, params string[] fieldNames) 
+            : this(isDescending, QueryIndexType.Sorted, fieldNames)
         {
-            Fields = fieldNames.Select(f => new QueryIndexField(f, isDescending)).ToArray();
+            // No-op.
         }
 
         /// <summary>
@@ -62,8 +73,12 @@ namespace Apache.Ignite.Core.Cache.Configuration
         /// <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)
         {
+            if (fieldNames != null)
+            {
+                Fields = fieldNames.Select(f => new QueryIndexField(f, isDescending)).ToArray();
+            }
+
             IndexType = indexType;
         }
 
@@ -96,7 +111,30 @@ namespace Apache.Ignite.Core.Cache.Configuration
         /// <summary>
         /// Gets or sets a collection of fields to be indexed.
         /// </summary>
-        public ICollection<QueryIndexField> Fields { get; private set; }
+        [SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
+        public ICollection<QueryIndexField> Fields { get; set; }
+
+        /// <summary>
+        /// Gets index inline size in bytes. When enabled part of indexed value will be placed directly to index pages,
+        /// thus minimizing data page accesses and increasing query performance.
+        /// <para />
+        /// Allowed values:
+        /// <ul>
+        /// <li><c>-1</c> (default) - determine inline size automatically(see below)</li>
+        /// <li><c>0</c> - index inline is disabled(not recommended)</li>
+        /// <li>positive value - fixed index inline</li >
+        /// </ul>
+        /// When set to <c>-1</c>, Ignite will try to detect inline size automatically. It will be no more than
+        /// <see cref="CacheConfiguration.SqlIndexMaxInlineSize"/>.
+        /// Index inline will be enabled for all fixed-length types,
+        ///  but <b>will not be enabled</b> for <see cref="string"/>.
+        /// </summary>
+        [DefaultValue(DefaultInlineSize)]
+        public int InlineSize
+        {
+            get { return _inlineSize; }
+            set { _inlineSize = value; }
+        }
 
         /// <summary>
         /// Initializes a new instance of the <see cref="QueryIndex"/> class.
@@ -106,6 +144,7 @@ namespace Apache.Ignite.Core.Cache.Configuration
         {
             Name = reader.ReadString();
             IndexType = (QueryIndexType) reader.ReadByte();
+            InlineSize = reader.ReadInt();
 
             var count = reader.ReadInt();
             Fields = count == 0 ? null : Enumerable.Range(0, count).Select(x =>
@@ -119,6 +158,7 @@ namespace Apache.Ignite.Core.Cache.Configuration
         {
             writer.WriteString(Name);
             writer.WriteByte((byte) IndexType);
+            writer.WriteInt(InlineSize);
 
             if (Fields != null)
             {
index a522115..b920304 100644 (file)
@@ -18,6 +18,7 @@
 namespace Apache.Ignite.Core.Cache.Configuration
 {
     using System;
+    using System.ComponentModel;
     using System.Diagnostics.CodeAnalysis;
 
     /// <summary>
@@ -29,6 +30,14 @@ namespace Apache.Ignite.Core.Cache.Configuration
     public sealed class QuerySqlFieldAttribute : Attribute
     {
         /// <summary>
+        /// Initializes a new instance of the <see cref="QuerySqlFieldAttribute"/> class.
+        /// </summary>
+        public QuerySqlFieldAttribute()
+        {
+            IndexInlineSize = QueryIndex.DefaultInlineSize;
+        }
+
+        /// <summary>
         /// Gets or sets the sql field name.
         /// If not provided, property or field name will be used.
         /// </summary>
@@ -56,5 +65,11 @@ namespace Apache.Ignite.Core.Cache.Configuration
         [SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays", 
             Justification = "Attribute initializers do not allow collections")]
         public string[] IndexGroups { get; set; }
+
+        /// <summary>
+        /// Gets or sets the index inline size, see <see cref="QueryIndex.InlineSize"/>.
+        /// </summary>
+        [DefaultValue(QueryIndex.DefaultInlineSize)]
+        public int IndexInlineSize { get; set; }
     }
 }
index 6788ef0..730cb9f 100644 (file)
                                                                                             <xs:documentation>Index type.</xs:documentation>
                                                                                         </xs:annotation>
                                                                                     </xs:attribute>
+                                                                                    <xs:attribute name="inlineSize" type="xs:int">
+                                                                                        <xs:annotation>
+                                                                                            <xs:documentation>Index inline size in bytes. When enabled part of indexed value will be placed directly to index pages, thus minimizing data page accesses and increasing query performance.</xs:documentation>
+                                                                                        </xs:annotation>
+                                                                                    </xs:attribute>
                                                                                 </xs:complexType>
                                                                             </xs:element>
                                                                         </xs:sequence>
                                             <xs:documentation>Cache group name. Caches with the same group name share single underlying 'physical' cache (partition set), but are logically isolated.</xs:documentation>
                                         </xs:annotation>
                                     </xs:attribute>
+                                    <xs:attribute name="sqlIndexMaxInlineSize" type="xs:int">
+                                        <xs:annotation>
+                                            <xs:documentation>Maximum size of SQL inline index. Part of indexed value will be placed directly to index pages, thus minimizing data page accesses and increasing query performance.</xs:documentation>
+                                        </xs:annotation>
+                                    </xs:attribute>
                                 </xs:complexType>
                             </xs:element>
                         </xs:sequence>