[jira] [Commented] (IGNITE-640) Implement IgniteMultimap data structures
[ https://issues.apache.org/jira/browse/IGNITE-640?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=17002045#comment-17002045 ] Amir Akhmedov commented on IGNITE-640: -- [~dmagda], removed my name from assignees. > Implement IgniteMultimap data structures > > > Key: IGNITE-640 > URL: https://issues.apache.org/jira/browse/IGNITE-640 > Project: Ignite > Issue Type: Sub-task > Components: data structures >Reporter: Dmitriy Setrakyan >Priority: Major > Fix For: 2.9 > > > We need to add {{IgniteMultimap}} data structure in addition to other data > structures provided by Ignite. {{IgniteMultiMap}} should have similar API to > {{java.util.Map}} class in JDK, but support the semantics of multiple values > per key, similar to [Guava > Multimap|http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/Multimap.html]. > > However, unlike in Guava, our multi-map should work with Lists, not > Collections. Lists should make it possible to support the following methods: > {code} > // Gets value at a certain index for a key. > V get(K, index); > // Gets all values for a collection of keys at a certain index. > Map getAll(Collection, index); > // Gets values for specified indexes for a key. > List get(K, Iterable indexes); > // Gets all values for a collection of keys at specified indexes. > Map> getAll(Collection, Iterable indexes); > // Gets values for specified range of indexes, between min and max. > List get(K, int min, int max); > // Gets all values for a collection of keys for a specified index range, > between min and max. > Map> getAll(Collection, int min, int max); > // Gets all values for a specific key. > List get(K); > // Gets all values for a collection of keys. > Map> getAll(Collection); > // Iterate through all elements with a certain index. > Iterator> iterate(int idx); > // Do we need this? > Collection> get(K, IgniteBiPredicate) > {code} > Multimap should also support colocated and non-colocated modes, similar to > [IgniteQueue|https://github.com/apache/incubator-ignite/blob/master/modules/core/src/main/java/org/apache/ignite/IgniteQueue.java] > and its implementation, > [GridAtomicCacheQueueImpl|https://github.com/apache/incubator-ignite/blob/master/modules/core/src/main/java/org/apache/ignite/internal/processors/datastructures/GridAtomicCacheQueueImpl.java]. > h2. Design Details > The most natural way to implement such map, would be to store every value > under a separate key in an Ignite cache. For example, let's say that we have > a key {{K}} with multiple values: {{V0, V1, V2, ...}}. Then the cache should > end up with the following values {{K0, V0}}, {{K1, V1}}, {{K2, V2}}, etc. > This means that we need to wrap user key into our own, internal key, which > will also have {{index}} field. > Also note that we need to collocate all the values for the same key on the > same node, which means that we need to define user key K as the affinity key, > like so: > {code} > class MultiKey { > @CacheAffinityMapped > private K key; > int index; > } > {code} > Look ups of values at specific indexes becomes very simple. Just attach a > specific index to a key and do a cache lookup. Look ups for all values for a > key should work as following: > {code} > MultiKey key; > V v = null; > int index = 0; > List res = new LinkedList<>(); > do { > v = cache.get(MultiKey(K, index)); > if (v != null) > res.add(v); > index++; > } > while (v != null); > return res; > {code} > We could also use batching for performance reason. In this case the batch > size should be configurable. > {code} > int index = 0; > List res = new LinkedList<>(); > while (true) { > List batch = new ArrayList<>(batchSize); > // Populate batch. > for (; index < batchSize; index++) > batch.add(new MultiKey(K, index % batchSize); > Map batchRes = cache.getAll(batch); > // Potentially need to properly sort values, based on the key order, > // if the returning map does not do it automatically. > res.addAll(batchRes.values()); > if (res.size() < batch.size()) > break; > } > return res; > {code} > h2. Evictions > Evictions in the {{IgniteMultiMap}} should have 2 levels: maximum number of > keys, and maximum number of values for a key. The maximum number of keys > should be controlled by Ignite standard eviction policy. The maximum number > of values for a key should be controlled by the implementation of the > multi-map. Either eviction parameter should be configurable. -- This message was sent by Atlassian Jira (v8.3.4#803005)
[jira] [Assigned] (IGNITE-640) Implement IgniteMultimap data structures
[ https://issues.apache.org/jira/browse/IGNITE-640?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ] Amir Akhmedov reassigned IGNITE-640: Assignee: (was: Amir Akhmedov) > Implement IgniteMultimap data structures > > > Key: IGNITE-640 > URL: https://issues.apache.org/jira/browse/IGNITE-640 > Project: Ignite > Issue Type: Sub-task > Components: data structures >Reporter: Dmitriy Setrakyan >Priority: Major > Fix For: 2.9 > > > We need to add {{IgniteMultimap}} data structure in addition to other data > structures provided by Ignite. {{IgniteMultiMap}} should have similar API to > {{java.util.Map}} class in JDK, but support the semantics of multiple values > per key, similar to [Guava > Multimap|http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/Multimap.html]. > > However, unlike in Guava, our multi-map should work with Lists, not > Collections. Lists should make it possible to support the following methods: > {code} > // Gets value at a certain index for a key. > V get(K, index); > // Gets all values for a collection of keys at a certain index. > Map getAll(Collection, index); > // Gets values for specified indexes for a key. > List get(K, Iterable indexes); > // Gets all values for a collection of keys at specified indexes. > Map> getAll(Collection, Iterable indexes); > // Gets values for specified range of indexes, between min and max. > List get(K, int min, int max); > // Gets all values for a collection of keys for a specified index range, > between min and max. > Map> getAll(Collection, int min, int max); > // Gets all values for a specific key. > List get(K); > // Gets all values for a collection of keys. > Map> getAll(Collection); > // Iterate through all elements with a certain index. > Iterator> iterate(int idx); > // Do we need this? > Collection> get(K, IgniteBiPredicate) > {code} > Multimap should also support colocated and non-colocated modes, similar to > [IgniteQueue|https://github.com/apache/incubator-ignite/blob/master/modules/core/src/main/java/org/apache/ignite/IgniteQueue.java] > and its implementation, > [GridAtomicCacheQueueImpl|https://github.com/apache/incubator-ignite/blob/master/modules/core/src/main/java/org/apache/ignite/internal/processors/datastructures/GridAtomicCacheQueueImpl.java]. > h2. Design Details > The most natural way to implement such map, would be to store every value > under a separate key in an Ignite cache. For example, let's say that we have > a key {{K}} with multiple values: {{V0, V1, V2, ...}}. Then the cache should > end up with the following values {{K0, V0}}, {{K1, V1}}, {{K2, V2}}, etc. > This means that we need to wrap user key into our own, internal key, which > will also have {{index}} field. > Also note that we need to collocate all the values for the same key on the > same node, which means that we need to define user key K as the affinity key, > like so: > {code} > class MultiKey { > @CacheAffinityMapped > private K key; > int index; > } > {code} > Look ups of values at specific indexes becomes very simple. Just attach a > specific index to a key and do a cache lookup. Look ups for all values for a > key should work as following: > {code} > MultiKey key; > V v = null; > int index = 0; > List res = new LinkedList<>(); > do { > v = cache.get(MultiKey(K, index)); > if (v != null) > res.add(v); > index++; > } > while (v != null); > return res; > {code} > We could also use batching for performance reason. In this case the batch > size should be configurable. > {code} > int index = 0; > List res = new LinkedList<>(); > while (true) { > List batch = new ArrayList<>(batchSize); > // Populate batch. > for (; index < batchSize; index++) > batch.add(new MultiKey(K, index % batchSize); > Map batchRes = cache.getAll(batch); > // Potentially need to properly sort values, based on the key order, > // if the returning map does not do it automatically. > res.addAll(batchRes.values()); > if (res.size() < batch.size()) > break; > } > return res; > {code} > h2. Evictions > Evictions in the {{IgniteMultiMap}} should have 2 levels: maximum number of > keys, and maximum number of values for a key. The maximum number of keys > should be controlled by Ignite standard eviction policy. The maximum number > of values for a key should be controlled by the implementation of the > multi-map. Either eviction parameter should be configurable. -- This message was sent by Atlassian Jira (v8.3.4#803005)
[jira] [Updated] (IGNITE-8880) Add setIgnite() in SpringCacheManager and SpringTransactionManager
[ https://issues.apache.org/jira/browse/IGNITE-8880?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ] Amir Akhmedov updated IGNITE-8880: -- Fix Version/s: (was: 2.7) 2.8 > Add setIgnite() in SpringCacheManager and SpringTransactionManager > -- > > Key: IGNITE-8880 > URL: https://issues.apache.org/jira/browse/IGNITE-8880 > Project: Ignite > Issue Type: Improvement > Components: spring >Reporter: Amir Akhmedov >Assignee: Amir Akhmedov >Priority: Major > Labels: newbie > Fix For: 2.8 > > > Neet to add setIgnite() in SpringCacheManager and SpringTransactionManager to > make explicit injection of Ignite instance. > For more details refer: > https://issues.apache.org/jira/browse/IGNITE-8740?focusedCommentId=16520894=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-16520894 -- This message was sent by Atlassian JIRA (v7.6.3#76005)
[jira] [Updated] (IGNITE-640) Implement IgniteMultimap data structures
[ https://issues.apache.org/jira/browse/IGNITE-640?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ] Amir Akhmedov updated IGNITE-640: - Fix Version/s: (was: 2.7) 2.8 > Implement IgniteMultimap data structures > > > Key: IGNITE-640 > URL: https://issues.apache.org/jira/browse/IGNITE-640 > Project: Ignite > Issue Type: Sub-task > Components: data structures >Reporter: Dmitriy Setrakyan >Assignee: Amir Akhmedov >Priority: Major > Fix For: 2.8 > > > We need to add {{IgniteMultimap}} data structure in addition to other data > structures provided by Ignite. {{IgniteMultiMap}} should have similar API to > {{java.util.Map}} class in JDK, but support the semantics of multiple values > per key, similar to [Guava > Multimap|http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/Multimap.html]. > > However, unlike in Guava, our multi-map should work with Lists, not > Collections. Lists should make it possible to support the following methods: > {code} > // Gets value at a certain index for a key. > V get(K, index); > // Gets all values for a collection of keys at a certain index. > Map getAll(Collection, index); > // Gets values for specified indexes for a key. > List get(K, Iterable indexes); > // Gets all values for a collection of keys at specified indexes. > Map> getAll(Collection, Iterable indexes); > // Gets values for specified range of indexes, between min and max. > List get(K, int min, int max); > // Gets all values for a collection of keys for a specified index range, > between min and max. > Map> getAll(Collection, int min, int max); > // Gets all values for a specific key. > List get(K); > // Gets all values for a collection of keys. > Map> getAll(Collection); > // Iterate through all elements with a certain index. > Iterator> iterate(int idx); > // Do we need this? > Collection> get(K, IgniteBiPredicate) > {code} > Multimap should also support colocated and non-colocated modes, similar to > [IgniteQueue|https://github.com/apache/incubator-ignite/blob/master/modules/core/src/main/java/org/apache/ignite/IgniteQueue.java] > and its implementation, > [GridAtomicCacheQueueImpl|https://github.com/apache/incubator-ignite/blob/master/modules/core/src/main/java/org/apache/ignite/internal/processors/datastructures/GridAtomicCacheQueueImpl.java]. > h2. Design Details > The most natural way to implement such map, would be to store every value > under a separate key in an Ignite cache. For example, let's say that we have > a key {{K}} with multiple values: {{V0, V1, V2, ...}}. Then the cache should > end up with the following values {{K0, V0}}, {{K1, V1}}, {{K2, V2}}, etc. > This means that we need to wrap user key into our own, internal key, which > will also have {{index}} field. > Also note that we need to collocate all the values for the same key on the > same node, which means that we need to define user key K as the affinity key, > like so: > {code} > class MultiKey { > @CacheAffinityMapped > private K key; > int index; > } > {code} > Look ups of values at specific indexes becomes very simple. Just attach a > specific index to a key and do a cache lookup. Look ups for all values for a > key should work as following: > {code} > MultiKey key; > V v = null; > int index = 0; > List res = new LinkedList<>(); > do { > v = cache.get(MultiKey(K, index)); > if (v != null) > res.add(v); > index++; > } > while (v != null); > return res; > {code} > We could also use batching for performance reason. In this case the batch > size should be configurable. > {code} > int index = 0; > List res = new LinkedList<>(); > while (true) { > List batch = new ArrayList<>(batchSize); > // Populate batch. > for (; index < batchSize; index++) > batch.add(new MultiKey(K, index % batchSize); > Map batchRes = cache.getAll(batch); > // Potentially need to properly sort values, based on the key order, > // if the returning map does not do it automatically. > res.addAll(batchRes.values()); > if (res.size() < batch.size()) > break; > } > return res; > {code} > h2. Evictions > Evictions in the {{IgniteMultiMap}} should have 2 levels: maximum number of > keys, and maximum number of values for a key. The maximum number of keys > should be controlled by Ignite standard eviction policy. The maximum number > of values for a key should be controlled by the implementation of the > multi-map. Either eviction parameter should be configurable. -- This message was sent by Atlassian JIRA (v7.6.3#76005)
[jira] [Commented] (IGNITE-640) Implement IgniteMultimap data structures
[ https://issues.apache.org/jira/browse/IGNITE-640?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=16626697#comment-16626697 ] Amir Akhmedov commented on IGNITE-640: -- [~NIzhikov], I don't think it's feasible to include it into 2.7. > Implement IgniteMultimap data structures > > > Key: IGNITE-640 > URL: https://issues.apache.org/jira/browse/IGNITE-640 > Project: Ignite > Issue Type: Sub-task > Components: data structures >Reporter: Dmitriy Setrakyan >Assignee: Amir Akhmedov >Priority: Major > Fix For: 2.8 > > > We need to add {{IgniteMultimap}} data structure in addition to other data > structures provided by Ignite. {{IgniteMultiMap}} should have similar API to > {{java.util.Map}} class in JDK, but support the semantics of multiple values > per key, similar to [Guava > Multimap|http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/Multimap.html]. > > However, unlike in Guava, our multi-map should work with Lists, not > Collections. Lists should make it possible to support the following methods: > {code} > // Gets value at a certain index for a key. > V get(K, index); > // Gets all values for a collection of keys at a certain index. > Map getAll(Collection, index); > // Gets values for specified indexes for a key. > List get(K, Iterable indexes); > // Gets all values for a collection of keys at specified indexes. > Map> getAll(Collection, Iterable indexes); > // Gets values for specified range of indexes, between min and max. > List get(K, int min, int max); > // Gets all values for a collection of keys for a specified index range, > between min and max. > Map> getAll(Collection, int min, int max); > // Gets all values for a specific key. > List get(K); > // Gets all values for a collection of keys. > Map> getAll(Collection); > // Iterate through all elements with a certain index. > Iterator> iterate(int idx); > // Do we need this? > Collection> get(K, IgniteBiPredicate) > {code} > Multimap should also support colocated and non-colocated modes, similar to > [IgniteQueue|https://github.com/apache/incubator-ignite/blob/master/modules/core/src/main/java/org/apache/ignite/IgniteQueue.java] > and its implementation, > [GridAtomicCacheQueueImpl|https://github.com/apache/incubator-ignite/blob/master/modules/core/src/main/java/org/apache/ignite/internal/processors/datastructures/GridAtomicCacheQueueImpl.java]. > h2. Design Details > The most natural way to implement such map, would be to store every value > under a separate key in an Ignite cache. For example, let's say that we have > a key {{K}} with multiple values: {{V0, V1, V2, ...}}. Then the cache should > end up with the following values {{K0, V0}}, {{K1, V1}}, {{K2, V2}}, etc. > This means that we need to wrap user key into our own, internal key, which > will also have {{index}} field. > Also note that we need to collocate all the values for the same key on the > same node, which means that we need to define user key K as the affinity key, > like so: > {code} > class MultiKey { > @CacheAffinityMapped > private K key; > int index; > } > {code} > Look ups of values at specific indexes becomes very simple. Just attach a > specific index to a key and do a cache lookup. Look ups for all values for a > key should work as following: > {code} > MultiKey key; > V v = null; > int index = 0; > List res = new LinkedList<>(); > do { > v = cache.get(MultiKey(K, index)); > if (v != null) > res.add(v); > index++; > } > while (v != null); > return res; > {code} > We could also use batching for performance reason. In this case the batch > size should be configurable. > {code} > int index = 0; > List res = new LinkedList<>(); > while (true) { > List batch = new ArrayList<>(batchSize); > // Populate batch. > for (; index < batchSize; index++) > batch.add(new MultiKey(K, index % batchSize); > Map batchRes = cache.getAll(batch); > // Potentially need to properly sort values, based on the key order, > // if the returning map does not do it automatically. > res.addAll(batchRes.values()); > if (res.size() < batch.size()) > break; > } > return res; > {code} > h2. Evictions > Evictions in the {{IgniteMultiMap}} should have 2 levels: maximum number of > keys, and maximum number of values for a key. The maximum number of keys > should be controlled by Ignite standard eviction policy. The maximum number > of values for a key should be controlled by the implementation of the > multi-map. Either eviction parameter should be configurable. -- This message was sent by Atlassian JIRA (v7.6.3#76005)
[jira] [Comment Edited] (IGNITE-640) Implement IgniteMultimap data structures
[ https://issues.apache.org/jira/browse/IGNITE-640?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=16606116#comment-16606116 ] Amir Akhmedov edited comment on IGNITE-640 at 9/6/18 5:28 PM: -- [~avinogradov], In this [#comment-16520147] you mentioned to create an **AbsractMap** that IgniteSet and IgniteMultimap could inherit. But the problem is IgniteSet already extends AbstractCollection. Do you think it's still an option to have a common abstract parent class for both Set and Multimap? I can come up with solution to rename Set "header" classes to Map and reuse an existing code as much as possible but I don't see how to combine the implementation of Set and Map so far. Any thoughts? was (Author: aakhmedov): [~avinogradov], In this [#comment-16520147] you mentioned to create an **AbsractMap** that IgniteSet and IgniteMultimap could inherit. But the problem is IgniteSet already extends AbstractCollection. Do you think it's still an option to have a common abstract parent class for both Set and Multimap? > Implement IgniteMultimap data structures > > > Key: IGNITE-640 > URL: https://issues.apache.org/jira/browse/IGNITE-640 > Project: Ignite > Issue Type: Sub-task > Components: data structures >Reporter: Dmitriy Setrakyan >Assignee: Amir Akhmedov >Priority: Major > Fix For: 2.7 > > > We need to add {{IgniteMultimap}} data structure in addition to other data > structures provided by Ignite. {{IgniteMultiMap}} should have similar API to > {{java.util.Map}} class in JDK, but support the semantics of multiple values > per key, similar to [Guava > Multimap|http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/Multimap.html]. > > However, unlike in Guava, our multi-map should work with Lists, not > Collections. Lists should make it possible to support the following methods: > {code} > // Gets value at a certain index for a key. > V get(K, index); > // Gets all values for a collection of keys at a certain index. > Map getAll(Collection, index); > // Gets values for specified indexes for a key. > List get(K, Iterable indexes); > // Gets all values for a collection of keys at specified indexes. > Map> getAll(Collection, Iterable indexes); > // Gets values for specified range of indexes, between min and max. > List get(K, int min, int max); > // Gets all values for a collection of keys for a specified index range, > between min and max. > Map> getAll(Collection, int min, int max); > // Gets all values for a specific key. > List get(K); > // Gets all values for a collection of keys. > Map> getAll(Collection); > // Iterate through all elements with a certain index. > Iterator> iterate(int idx); > // Do we need this? > Collection> get(K, IgniteBiPredicate) > {code} > Multimap should also support colocated and non-colocated modes, similar to > [IgniteQueue|https://github.com/apache/incubator-ignite/blob/master/modules/core/src/main/java/org/apache/ignite/IgniteQueue.java] > and its implementation, > [GridAtomicCacheQueueImpl|https://github.com/apache/incubator-ignite/blob/master/modules/core/src/main/java/org/apache/ignite/internal/processors/datastructures/GridAtomicCacheQueueImpl.java]. > h2. Design Details > The most natural way to implement such map, would be to store every value > under a separate key in an Ignite cache. For example, let's say that we have > a key {{K}} with multiple values: {{V0, V1, V2, ...}}. Then the cache should > end up with the following values {{K0, V0}}, {{K1, V1}}, {{K2, V2}}, etc. > This means that we need to wrap user key into our own, internal key, which > will also have {{index}} field. > Also note that we need to collocate all the values for the same key on the > same node, which means that we need to define user key K as the affinity key, > like so: > {code} > class MultiKey { > @CacheAffinityMapped > private K key; > int index; > } > {code} > Look ups of values at specific indexes becomes very simple. Just attach a > specific index to a key and do a cache lookup. Look ups for all values for a > key should work as following: > {code} > MultiKey key; > V v = null; > int index = 0; > List res = new LinkedList<>(); > do { > v = cache.get(MultiKey(K, index)); > if (v != null) > res.add(v); > index++; > } > while (v != null); > return res; > {code} > We could also use batching for performance reason. In this case the batch > size should be configurable. > {code} > int index = 0; > List res = new LinkedList<>(); > while (true) { > List batch = new ArrayList<>(batchSize); > // Populate batch. > for (; index < batchSize; index++) > batch.add(new MultiKey(K, index % batchSize); > Map batchRes = cache.getAll(batch); > // Potentially
[jira] [Commented] (IGNITE-640) Implement IgniteMultimap data structures
[ https://issues.apache.org/jira/browse/IGNITE-640?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=16606116#comment-16606116 ] Amir Akhmedov commented on IGNITE-640: -- [~avinogradov], In this [#comment-16520147] you mentioned to create an **AbsractMap** that IgniteSet and IgniteMultimap could inherit. But the problem is IgniteSet already extends AbstractCollection. Do you think it's still an option to have a common abstract parent class for both Set and Multimap? > Implement IgniteMultimap data structures > > > Key: IGNITE-640 > URL: https://issues.apache.org/jira/browse/IGNITE-640 > Project: Ignite > Issue Type: Sub-task > Components: data structures >Reporter: Dmitriy Setrakyan >Assignee: Amir Akhmedov >Priority: Major > Fix For: 2.7 > > > We need to add {{IgniteMultimap}} data structure in addition to other data > structures provided by Ignite. {{IgniteMultiMap}} should have similar API to > {{java.util.Map}} class in JDK, but support the semantics of multiple values > per key, similar to [Guava > Multimap|http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/Multimap.html]. > > However, unlike in Guava, our multi-map should work with Lists, not > Collections. Lists should make it possible to support the following methods: > {code} > // Gets value at a certain index for a key. > V get(K, index); > // Gets all values for a collection of keys at a certain index. > Map getAll(Collection, index); > // Gets values for specified indexes for a key. > List get(K, Iterable indexes); > // Gets all values for a collection of keys at specified indexes. > Map> getAll(Collection, Iterable indexes); > // Gets values for specified range of indexes, between min and max. > List get(K, int min, int max); > // Gets all values for a collection of keys for a specified index range, > between min and max. > Map> getAll(Collection, int min, int max); > // Gets all values for a specific key. > List get(K); > // Gets all values for a collection of keys. > Map> getAll(Collection); > // Iterate through all elements with a certain index. > Iterator> iterate(int idx); > // Do we need this? > Collection> get(K, IgniteBiPredicate) > {code} > Multimap should also support colocated and non-colocated modes, similar to > [IgniteQueue|https://github.com/apache/incubator-ignite/blob/master/modules/core/src/main/java/org/apache/ignite/IgniteQueue.java] > and its implementation, > [GridAtomicCacheQueueImpl|https://github.com/apache/incubator-ignite/blob/master/modules/core/src/main/java/org/apache/ignite/internal/processors/datastructures/GridAtomicCacheQueueImpl.java]. > h2. Design Details > The most natural way to implement such map, would be to store every value > under a separate key in an Ignite cache. For example, let's say that we have > a key {{K}} with multiple values: {{V0, V1, V2, ...}}. Then the cache should > end up with the following values {{K0, V0}}, {{K1, V1}}, {{K2, V2}}, etc. > This means that we need to wrap user key into our own, internal key, which > will also have {{index}} field. > Also note that we need to collocate all the values for the same key on the > same node, which means that we need to define user key K as the affinity key, > like so: > {code} > class MultiKey { > @CacheAffinityMapped > private K key; > int index; > } > {code} > Look ups of values at specific indexes becomes very simple. Just attach a > specific index to a key and do a cache lookup. Look ups for all values for a > key should work as following: > {code} > MultiKey key; > V v = null; > int index = 0; > List res = new LinkedList<>(); > do { > v = cache.get(MultiKey(K, index)); > if (v != null) > res.add(v); > index++; > } > while (v != null); > return res; > {code} > We could also use batching for performance reason. In this case the batch > size should be configurable. > {code} > int index = 0; > List res = new LinkedList<>(); > while (true) { > List batch = new ArrayList<>(batchSize); > // Populate batch. > for (; index < batchSize; index++) > batch.add(new MultiKey(K, index % batchSize); > Map batchRes = cache.getAll(batch); > // Potentially need to properly sort values, based on the key order, > // if the returning map does not do it automatically. > res.addAll(batchRes.values()); > if (res.size() < batch.size()) > break; > } > return res; > {code} > h2. Evictions > Evictions in the {{IgniteMultiMap}} should have 2 levels: maximum number of > keys, and maximum number of values for a key. The maximum number of keys > should be controlled by Ignite standard eviction policy. The maximum number > of values for a key should be controlled by the implementation of the > multi-map. Either eviction
[jira] [Commented] (IGNITE-640) Implement IgniteMultimap data structures
[ https://issues.apache.org/jira/browse/IGNITE-640?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=16595159#comment-16595159 ] Amir Akhmedov commented on IGNITE-640: -- [~avinogradov], Work in progress, will have something to share by next week > Implement IgniteMultimap data structures > > > Key: IGNITE-640 > URL: https://issues.apache.org/jira/browse/IGNITE-640 > Project: Ignite > Issue Type: Sub-task > Components: data structures >Reporter: Dmitriy Setrakyan >Assignee: Amir Akhmedov >Priority: Major > Fix For: 2.7 > > > We need to add {{IgniteMultimap}} data structure in addition to other data > structures provided by Ignite. {{IgniteMultiMap}} should have similar API to > {{java.util.Map}} class in JDK, but support the semantics of multiple values > per key, similar to [Guava > Multimap|http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/Multimap.html]. > > However, unlike in Guava, our multi-map should work with Lists, not > Collections. Lists should make it possible to support the following methods: > {code} > // Gets value at a certain index for a key. > V get(K, index); > // Gets all values for a collection of keys at a certain index. > Map getAll(Collection, index); > // Gets values for specified indexes for a key. > List get(K, Iterable indexes); > // Gets all values for a collection of keys at specified indexes. > Map> getAll(Collection, Iterable indexes); > // Gets values for specified range of indexes, between min and max. > List get(K, int min, int max); > // Gets all values for a collection of keys for a specified index range, > between min and max. > Map> getAll(Collection, int min, int max); > // Gets all values for a specific key. > List get(K); > // Gets all values for a collection of keys. > Map> getAll(Collection); > // Iterate through all elements with a certain index. > Iterator> iterate(int idx); > // Do we need this? > Collection> get(K, IgniteBiPredicate) > {code} > Multimap should also support colocated and non-colocated modes, similar to > [IgniteQueue|https://github.com/apache/incubator-ignite/blob/master/modules/core/src/main/java/org/apache/ignite/IgniteQueue.java] > and its implementation, > [GridAtomicCacheQueueImpl|https://github.com/apache/incubator-ignite/blob/master/modules/core/src/main/java/org/apache/ignite/internal/processors/datastructures/GridAtomicCacheQueueImpl.java]. > h2. Design Details > The most natural way to implement such map, would be to store every value > under a separate key in an Ignite cache. For example, let's say that we have > a key {{K}} with multiple values: {{V0, V1, V2, ...}}. Then the cache should > end up with the following values {{K0, V0}}, {{K1, V1}}, {{K2, V2}}, etc. > This means that we need to wrap user key into our own, internal key, which > will also have {{index}} field. > Also note that we need to collocate all the values for the same key on the > same node, which means that we need to define user key K as the affinity key, > like so: > {code} > class MultiKey { > @CacheAffinityMapped > private K key; > int index; > } > {code} > Look ups of values at specific indexes becomes very simple. Just attach a > specific index to a key and do a cache lookup. Look ups for all values for a > key should work as following: > {code} > MultiKey key; > V v = null; > int index = 0; > List res = new LinkedList<>(); > do { > v = cache.get(MultiKey(K, index)); > if (v != null) > res.add(v); > index++; > } > while (v != null); > return res; > {code} > We could also use batching for performance reason. In this case the batch > size should be configurable. > {code} > int index = 0; > List res = new LinkedList<>(); > while (true) { > List batch = new ArrayList<>(batchSize); > // Populate batch. > for (; index < batchSize; index++) > batch.add(new MultiKey(K, index % batchSize); > Map batchRes = cache.getAll(batch); > // Potentially need to properly sort values, based on the key order, > // if the returning map does not do it automatically. > res.addAll(batchRes.values()); > if (res.size() < batch.size()) > break; > } > return res; > {code} > h2. Evictions > Evictions in the {{IgniteMultiMap}} should have 2 levels: maximum number of > keys, and maximum number of values for a key. The maximum number of keys > should be controlled by Ignite standard eviction policy. The maximum number > of values for a key should be controlled by the implementation of the > multi-map. Either eviction parameter should be configurable. -- This message was sent by Atlassian JIRA (v7.6.3#76005)
[jira] [Commented] (IGNITE-9031) SpringCacheManager throws AssertionError during Spring initialization
[ https://issues.apache.org/jira/browse/IGNITE-9031?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=16580194#comment-16580194 ] Amir Akhmedov commented on IGNITE-9031: --- [~vkulichenko], I don't think it's possible since {{ContextRefreshEvent}} is published once (when all initialization is done) and from application thread [https://github.com/spring-projects/spring-framework/blob/master/spring-context/src/main/java/org/springframework/context/support/AbstractApplicationContext.java#L873] Besides, I looked at documentation and found nothing about multi-threading. > SpringCacheManager throws AssertionError during Spring initialization > - > > Key: IGNITE-9031 > URL: https://issues.apache.org/jira/browse/IGNITE-9031 > Project: Ignite > Issue Type: Bug > Components: spring >Affects Versions: 2.6 >Reporter: Joel Lang >Assignee: Amir Akhmedov >Priority: Major > > When initializing Ignite using an IgniteSpringBean and also having a > SpringCacheManager defined, the SpringCacheManager throws an AssertionError > in the onApplicationEvent() method due to it being called more than once. > There is an "assert ignite == null" that fails after the first call. > This is related to the changes in IGNITE-8740. This happened immediately when > I first tried to start Ignite after upgrading from 2.5 to 2.6. -- This message was sent by Atlassian JIRA (v7.6.3#76005)
[jira] [Commented] (IGNITE-9031) SpringCacheManager throws AssertionError during Spring initialization
[ https://issues.apache.org/jira/browse/IGNITE-9031?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=16577656#comment-16577656 ] Amir Akhmedov commented on IGNITE-9031: --- [~vkulichenko], can you please review my changes? > SpringCacheManager throws AssertionError during Spring initialization > - > > Key: IGNITE-9031 > URL: https://issues.apache.org/jira/browse/IGNITE-9031 > Project: Ignite > Issue Type: Bug > Components: spring >Affects Versions: 2.6 >Reporter: Joel Lang >Assignee: Amir Akhmedov >Priority: Major > > When initializing Ignite using an IgniteSpringBean and also having a > SpringCacheManager defined, the SpringCacheManager throws an AssertionError > in the onApplicationEvent() method due to it being called more than once. > There is an "assert ignite == null" that fails after the first call. > This is related to the changes in IGNITE-8740. This happened immediately when > I first tried to start Ignite after upgrading from 2.5 to 2.6. -- This message was sent by Atlassian JIRA (v7.6.3#76005)
[jira] [Commented] (IGNITE-9031) SpringCacheManager throws AssertionError during Spring initialization
[ https://issues.apache.org/jira/browse/IGNITE-9031?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=16548720#comment-16548720 ] Amir Akhmedov commented on IGNITE-9031: --- [~vkulichenko], the only case it can happen, as I see so far, when {{ApplicationContext}} which creates {{IgniteSpringBean}} is used as a parent for another {{ApplicationContext}}. In this case {{ContextRefreshedEvent}} from child will be propagated to the parent. This might be a case of Spring MVC application. [~langj], can you please share your spring configuration, it will help to understand the root cause. > SpringCacheManager throws AssertionError during Spring initialization > - > > Key: IGNITE-9031 > URL: https://issues.apache.org/jira/browse/IGNITE-9031 > Project: Ignite > Issue Type: Bug > Components: spring >Affects Versions: 2.6 >Reporter: Joel Lang >Priority: Major > > When initializing Ignite using an IgniteSpringBean and also having a > SpringCacheManager defined, the SpringCacheManager throws an AssertionError > in the onApplicationEvent() method due to it being called more than once. > There is an "assert ignite == null" that fails after the first call. > This is related to the changes in IGNITE-8740. This happened immediately when > I first tried to start Ignite after upgrading from 2.5 to 2.6. -- This message was sent by Atlassian JIRA (v7.6.3#76005)
[jira] [Assigned] (IGNITE-9031) SpringCacheManager throws AssertionError during Spring initialization
[ https://issues.apache.org/jira/browse/IGNITE-9031?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ] Amir Akhmedov reassigned IGNITE-9031: - Assignee: Amir Akhmedov > SpringCacheManager throws AssertionError during Spring initialization > - > > Key: IGNITE-9031 > URL: https://issues.apache.org/jira/browse/IGNITE-9031 > Project: Ignite > Issue Type: Bug > Components: spring >Affects Versions: 2.6 >Reporter: Joel Lang >Assignee: Amir Akhmedov >Priority: Major > > When initializing Ignite using an IgniteSpringBean and also having a > SpringCacheManager defined, the SpringCacheManager throws an AssertionError > in the onApplicationEvent() method due to it being called more than once. > There is an "assert ignite == null" that fails after the first call. > This is related to the changes in IGNITE-8740. This happened immediately when > I first tried to start Ignite after upgrading from 2.5 to 2.6. -- This message was sent by Atlassian JIRA (v7.6.3#76005)
[jira] [Commented] (IGNITE-640) Implement IgniteMultimap data structures
[ https://issues.apache.org/jira/browse/IGNITE-640?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=16538061#comment-16538061 ] Amir Akhmedov commented on IGNITE-640: -- [~avinogradov], 1) I need size field in {{GridCacheMapHeader}} to make {{size()}} faster otherwise for the collocated map we have to iterate over all maps to count the size of target map. 2) I made {{multimap0}} similar to to {{queue0}} because its implementation more natural and clean than {{set0}}. At the moment of my initial implementation there was no talk about removal of {{setDataMap}} in {{IgniteSet}} and I wanted to avoid such design flaw. I think once we start work on IGNITE-5553 {{set0}} will be much similar to {{multimap0}} and it will be good time to converge {{set0()}} and {{multimap0()}} into one method e.g. {{map0()}} and thus avoid a code dupe. >> compatibleCacheForMultimap is a 99% copy of compatibleCache. Agree, will fix it soon >> I see no reason to have special GridCacheMapItemKey it 100% equals to >>GridCacheSetItemKey. I do not see two classes, as you suggested I renamed GridCacheSetItemKey to GridCacheMapItemKey. >> I see no reason to use any code from queue In general, all {{queue()}}, {{set()}}, {{multimap()}} are similar in {{CacheDataStructuresManager}} and {{DataStructuresProcessor}} except daastructure removal in queue/multimap handled through continuous query and in set through infamous {{setDataMap}} >> You should use and refactor set implementation to support multimap as well. >>Avoid code duplication. Agree but IMHO first one of the implementations should go first either IGNITE-640 or IGNITE-5553. Today, multimap and set are two different implementations. >> What odd do you see? e.g. in {{GridCacheMultimapImpl::getAll}} I need to make casting like this {{(Map>) getAll0(keys)}} Please let me know your thoughts. P.S. do you mind to have a chat/call through gitter/Skype to discuss the details? Sometimes 5 minutes of chat can be more productive than long running email chains. Please, do not hesitate to directly email me if you mind to have a chat/call. > Implement IgniteMultimap data structures > > > Key: IGNITE-640 > URL: https://issues.apache.org/jira/browse/IGNITE-640 > Project: Ignite > Issue Type: Sub-task > Components: data structures >Reporter: Dmitriy Setrakyan >Assignee: Amir Akhmedov >Priority: Major > Fix For: 2.7 > > > We need to add {{IgniteMultimap}} data structure in addition to other data > structures provided by Ignite. {{IgniteMultiMap}} should have similar API to > {{java.util.Map}} class in JDK, but support the semantics of multiple values > per key, similar to [Guava > Multimap|http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/Multimap.html]. > > However, unlike in Guava, our multi-map should work with Lists, not > Collections. Lists should make it possible to support the following methods: > {code} > // Gets value at a certain index for a key. > V get(K, index); > // Gets all values for a collection of keys at a certain index. > Map getAll(Collection, index); > // Gets values for specified indexes for a key. > List get(K, Iterable indexes); > // Gets all values for a collection of keys at specified indexes. > Map> getAll(Collection, Iterable indexes); > // Gets values for specified range of indexes, between min and max. > List get(K, int min, int max); > // Gets all values for a collection of keys for a specified index range, > between min and max. > Map> getAll(Collection, int min, int max); > // Gets all values for a specific key. > List get(K); > // Gets all values for a collection of keys. > Map> getAll(Collection); > // Iterate through all elements with a certain index. > Iterator> iterate(int idx); > // Do we need this? > Collection> get(K, IgniteBiPredicate) > {code} > Multimap should also support colocated and non-colocated modes, similar to > [IgniteQueue|https://github.com/apache/incubator-ignite/blob/master/modules/core/src/main/java/org/apache/ignite/IgniteQueue.java] > and its implementation, > [GridAtomicCacheQueueImpl|https://github.com/apache/incubator-ignite/blob/master/modules/core/src/main/java/org/apache/ignite/internal/processors/datastructures/GridAtomicCacheQueueImpl.java]. > h2. Design Details > The most natural way to implement such map, would be to store every value > under a separate key in an Ignite cache. For example, let's say that we have > a key {{K}} with multiple values: {{V0, V1, V2, ...}}. Then the cache should > end up with the following values {{K0, V0}}, {{K1, V1}}, {{K2, V2}}, etc. > This means that we need to wrap user key into our own, internal key, which > will also have {{index}} field. > Also note that we need to collocate all the values for the
[jira] [Assigned] (IGNITE-8880) Add setIgnite() in SpringCacheManager and SpringTransactionManager
[ https://issues.apache.org/jira/browse/IGNITE-8880?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ] Amir Akhmedov reassigned IGNITE-8880: - Assignee: Amir Akhmedov > Add setIgnite() in SpringCacheManager and SpringTransactionManager > -- > > Key: IGNITE-8880 > URL: https://issues.apache.org/jira/browse/IGNITE-8880 > Project: Ignite > Issue Type: Improvement > Components: spring >Reporter: Amir Akhmedov >Assignee: Amir Akhmedov >Priority: Major > Labels: newbie > Fix For: 2.7 > > > Neet to add setIgnite() in SpringCacheManager and SpringTransactionManager to > make explicit injection of Ignite instance. > For more details refer: > https://issues.apache.org/jira/browse/IGNITE-8740?focusedCommentId=16520894=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-16520894 -- This message was sent by Atlassian JIRA (v7.6.3#76005)
[jira] [Comment Edited] (IGNITE-640) Implement IgniteMultimap data structures
[ https://issues.apache.org/jira/browse/IGNITE-640?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=16534428#comment-16534428 ] Amir Akhmedov edited comment on IGNITE-640 at 7/6/18 5:11 AM: -- Hi [~avinogradov], I made a changes discussed above, please check them. I think it worth to add generic type for key into MapItemKey, without it code in MultimapImpl looks a little odd. PR: [https://github.com/apache/ignite/pull/4207] was (Author: aakhmedov): Hi [~avinogradov], I made a changes discussed above, please check them. I think it worth to add generic type for key into MapItemKey, without it code in MultimapImpl looks a little odd. > Implement IgniteMultimap data structures > > > Key: IGNITE-640 > URL: https://issues.apache.org/jira/browse/IGNITE-640 > Project: Ignite > Issue Type: Sub-task > Components: data structures >Reporter: Dmitriy Setrakyan >Assignee: Amir Akhmedov >Priority: Major > Fix For: 2.7 > > > We need to add {{IgniteMultimap}} data structure in addition to other data > structures provided by Ignite. {{IgniteMultiMap}} should have similar API to > {{java.util.Map}} class in JDK, but support the semantics of multiple values > per key, similar to [Guava > Multimap|http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/Multimap.html]. > > However, unlike in Guava, our multi-map should work with Lists, not > Collections. Lists should make it possible to support the following methods: > {code} > // Gets value at a certain index for a key. > V get(K, index); > // Gets all values for a collection of keys at a certain index. > Map getAll(Collection, index); > // Gets values for specified indexes for a key. > List get(K, Iterable indexes); > // Gets all values for a collection of keys at specified indexes. > Map> getAll(Collection, Iterable indexes); > // Gets values for specified range of indexes, between min and max. > List get(K, int min, int max); > // Gets all values for a collection of keys for a specified index range, > between min and max. > Map> getAll(Collection, int min, int max); > // Gets all values for a specific key. > List get(K); > // Gets all values for a collection of keys. > Map> getAll(Collection); > // Iterate through all elements with a certain index. > Iterator> iterate(int idx); > // Do we need this? > Collection> get(K, IgniteBiPredicate) > {code} > Multimap should also support colocated and non-colocated modes, similar to > [IgniteQueue|https://github.com/apache/incubator-ignite/blob/master/modules/core/src/main/java/org/apache/ignite/IgniteQueue.java] > and its implementation, > [GridAtomicCacheQueueImpl|https://github.com/apache/incubator-ignite/blob/master/modules/core/src/main/java/org/apache/ignite/internal/processors/datastructures/GridAtomicCacheQueueImpl.java]. > h2. Design Details > The most natural way to implement such map, would be to store every value > under a separate key in an Ignite cache. For example, let's say that we have > a key {{K}} with multiple values: {{V0, V1, V2, ...}}. Then the cache should > end up with the following values {{K0, V0}}, {{K1, V1}}, {{K2, V2}}, etc. > This means that we need to wrap user key into our own, internal key, which > will also have {{index}} field. > Also note that we need to collocate all the values for the same key on the > same node, which means that we need to define user key K as the affinity key, > like so: > {code} > class MultiKey { > @CacheAffinityMapped > private K key; > int index; > } > {code} > Look ups of values at specific indexes becomes very simple. Just attach a > specific index to a key and do a cache lookup. Look ups for all values for a > key should work as following: > {code} > MultiKey key; > V v = null; > int index = 0; > List res = new LinkedList<>(); > do { > v = cache.get(MultiKey(K, index)); > if (v != null) > res.add(v); > index++; > } > while (v != null); > return res; > {code} > We could also use batching for performance reason. In this case the batch > size should be configurable. > {code} > int index = 0; > List res = new LinkedList<>(); > while (true) { > List batch = new ArrayList<>(batchSize); > // Populate batch. > for (; index < batchSize; index++) > batch.add(new MultiKey(K, index % batchSize); > Map batchRes = cache.getAll(batch); > // Potentially need to properly sort values, based on the key order, > // if the returning map does not do it automatically. > res.addAll(batchRes.values()); > if (res.size() < batch.size()) > break; > } > return res; > {code} > h2. Evictions > Evictions in the {{IgniteMultiMap}} should have 2 levels: maximum number of > keys, and maximum number of values for a key. The
[jira] [Commented] (IGNITE-640) Implement IgniteMultimap data structures
[ https://issues.apache.org/jira/browse/IGNITE-640?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=16534428#comment-16534428 ] Amir Akhmedov commented on IGNITE-640: -- Hi [~avinogradov], I made a changes discussed above, please check them. I think it worth to add generic type for key into MapItemKey, without it code in MultimapImpl looks a little odd. > Implement IgniteMultimap data structures > > > Key: IGNITE-640 > URL: https://issues.apache.org/jira/browse/IGNITE-640 > Project: Ignite > Issue Type: Sub-task > Components: data structures >Reporter: Dmitriy Setrakyan >Assignee: Amir Akhmedov >Priority: Major > Fix For: 2.7 > > > We need to add {{IgniteMultimap}} data structure in addition to other data > structures provided by Ignite. {{IgniteMultiMap}} should have similar API to > {{java.util.Map}} class in JDK, but support the semantics of multiple values > per key, similar to [Guava > Multimap|http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/Multimap.html]. > > However, unlike in Guava, our multi-map should work with Lists, not > Collections. Lists should make it possible to support the following methods: > {code} > // Gets value at a certain index for a key. > V get(K, index); > // Gets all values for a collection of keys at a certain index. > Map getAll(Collection, index); > // Gets values for specified indexes for a key. > List get(K, Iterable indexes); > // Gets all values for a collection of keys at specified indexes. > Map> getAll(Collection, Iterable indexes); > // Gets values for specified range of indexes, between min and max. > List get(K, int min, int max); > // Gets all values for a collection of keys for a specified index range, > between min and max. > Map> getAll(Collection, int min, int max); > // Gets all values for a specific key. > List get(K); > // Gets all values for a collection of keys. > Map> getAll(Collection); > // Iterate through all elements with a certain index. > Iterator> iterate(int idx); > // Do we need this? > Collection> get(K, IgniteBiPredicate) > {code} > Multimap should also support colocated and non-colocated modes, similar to > [IgniteQueue|https://github.com/apache/incubator-ignite/blob/master/modules/core/src/main/java/org/apache/ignite/IgniteQueue.java] > and its implementation, > [GridAtomicCacheQueueImpl|https://github.com/apache/incubator-ignite/blob/master/modules/core/src/main/java/org/apache/ignite/internal/processors/datastructures/GridAtomicCacheQueueImpl.java]. > h2. Design Details > The most natural way to implement such map, would be to store every value > under a separate key in an Ignite cache. For example, let's say that we have > a key {{K}} with multiple values: {{V0, V1, V2, ...}}. Then the cache should > end up with the following values {{K0, V0}}, {{K1, V1}}, {{K2, V2}}, etc. > This means that we need to wrap user key into our own, internal key, which > will also have {{index}} field. > Also note that we need to collocate all the values for the same key on the > same node, which means that we need to define user key K as the affinity key, > like so: > {code} > class MultiKey { > @CacheAffinityMapped > private K key; > int index; > } > {code} > Look ups of values at specific indexes becomes very simple. Just attach a > specific index to a key and do a cache lookup. Look ups for all values for a > key should work as following: > {code} > MultiKey key; > V v = null; > int index = 0; > List res = new LinkedList<>(); > do { > v = cache.get(MultiKey(K, index)); > if (v != null) > res.add(v); > index++; > } > while (v != null); > return res; > {code} > We could also use batching for performance reason. In this case the batch > size should be configurable. > {code} > int index = 0; > List res = new LinkedList<>(); > while (true) { > List batch = new ArrayList<>(batchSize); > // Populate batch. > for (; index < batchSize; index++) > batch.add(new MultiKey(K, index % batchSize); > Map batchRes = cache.getAll(batch); > // Potentially need to properly sort values, based on the key order, > // if the returning map does not do it automatically. > res.addAll(batchRes.values()); > if (res.size() < batch.size()) > break; > } > return res; > {code} > h2. Evictions > Evictions in the {{IgniteMultiMap}} should have 2 levels: maximum number of > keys, and maximum number of values for a key. The maximum number of keys > should be controlled by Ignite standard eviction policy. The maximum number > of values for a key should be controlled by the implementation of the > multi-map. Either eviction parameter should be configurable. -- This message was sent by Atlassian JIRA (v7.6.3#76005)
[jira] [Commented] (IGNITE-8740) Support reuse of already initialized Ignite in IgniteSpringBean
[ https://issues.apache.org/jira/browse/IGNITE-8740?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=16524062#comment-16524062 ] Amir Akhmedov commented on IGNITE-8740: --- Done https://issues.apache.org/jira/browse/IGNITE-8880 > Support reuse of already initialized Ignite in IgniteSpringBean > --- > > Key: IGNITE-8740 > URL: https://issues.apache.org/jira/browse/IGNITE-8740 > Project: Ignite > Issue Type: Improvement > Components: spring >Affects Versions: 2.4 >Reporter: Ilya Kasnacheev >Assignee: Amir Akhmedov >Priority: Blocker > Fix For: 2.6 > > > See > http://apache-ignite-users.70518.x6.nabble.com/IgniteSpringBean-amp-Ignite-SpringTransactionManager-broken-with-2-4-td21667.html#a21724 > (there's patch available) > The idea is to introduce a workaround for users hit by IGNITE-6555, which > unfortunately broke some scenarios. -- This message was sent by Atlassian JIRA (v7.6.3#76005)
[jira] [Created] (IGNITE-8880) Add setIgnite() in SpringCacheManager and SpringTransactionManager
Amir Akhmedov created IGNITE-8880: - Summary: Add setIgnite() in SpringCacheManager and SpringTransactionManager Key: IGNITE-8880 URL: https://issues.apache.org/jira/browse/IGNITE-8880 Project: Ignite Issue Type: Improvement Components: spring Reporter: Amir Akhmedov Fix For: 2.7 Neet to add setIgnite() in SpringCacheManager and SpringTransactionManager to make explicit injection of Ignite instance. For more details refer: https://issues.apache.org/jira/browse/IGNITE-8740?focusedCommentId=16520894=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-16520894 -- This message was sent by Atlassian JIRA (v7.6.3#76005)
[jira] [Commented] (IGNITE-640) Implement IgniteMultimap data structures
[ https://issues.apache.org/jira/browse/IGNITE-640?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=16523955#comment-16523955 ] Amir Akhmedov commented on IGNITE-640: -- [~avinogradov], Yes, I followed the ideas from {{IgniteQueue}} since I found its implementation more clean and natural. {{IgniteSet}}'s implementation really polluted with the maintenance of {{setDataMap}} # Regarding the size, in general I followed how it's working today in IgniteQueue. I understand that at some point of time you will see inconsistent data between actual map's size and {{size()}} but I think {{gate.enter()}} call in {{GridCacheMultimapProxy}} should help at least not to see a big deference in values of actual vs {{size()}}. Or am I wrong on capabilities of {{gate.enter()}}? # Right, and I think you are right, I will rename {{CollocatedMultimapItemKey}} and others to **Map** so we could reuse them latter when re-implement {{IgniteSet}}. I don't think it's a good idea to make changes for two tickets in one pull request # Absolutely agree with you. There was no intention to change {{IgniteSet}} when I started to work on this ticket that's why I separated the logic into {{DataStructuresProcessor#getMultimap}} but right now I can extract them out into a base class so they could be reused in both {{IgniteMultimap}} and {{IgniteSet}} Please let me know your thoughts. If you are fine then I'll start working on changes discussed above. > Implement IgniteMultimap data structures > > > Key: IGNITE-640 > URL: https://issues.apache.org/jira/browse/IGNITE-640 > Project: Ignite > Issue Type: Sub-task > Components: data structures >Reporter: Dmitriy Setrakyan >Assignee: Amir Akhmedov >Priority: Major > Fix For: 2.7 > > > We need to add {{IgniteMultimap}} data structure in addition to other data > structures provided by Ignite. {{IgniteMultiMap}} should have similar API to > {{java.util.Map}} class in JDK, but support the semantics of multiple values > per key, similar to [Guava > Multimap|http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/Multimap.html]. > > However, unlike in Guava, our multi-map should work with Lists, not > Collections. Lists should make it possible to support the following methods: > {code} > // Gets value at a certain index for a key. > V get(K, index); > // Gets all values for a collection of keys at a certain index. > Map getAll(Collection, index); > // Gets values for specified indexes for a key. > List get(K, Iterable indexes); > // Gets all values for a collection of keys at specified indexes. > Map> getAll(Collection, Iterable indexes); > // Gets values for specified range of indexes, between min and max. > List get(K, int min, int max); > // Gets all values for a collection of keys for a specified index range, > between min and max. > Map> getAll(Collection, int min, int max); > // Gets all values for a specific key. > List get(K); > // Gets all values for a collection of keys. > Map> getAll(Collection); > // Iterate through all elements with a certain index. > Iterator> iterate(int idx); > // Do we need this? > Collection> get(K, IgniteBiPredicate) > {code} > Multimap should also support colocated and non-colocated modes, similar to > [IgniteQueue|https://github.com/apache/incubator-ignite/blob/master/modules/core/src/main/java/org/apache/ignite/IgniteQueue.java] > and its implementation, > [GridAtomicCacheQueueImpl|https://github.com/apache/incubator-ignite/blob/master/modules/core/src/main/java/org/apache/ignite/internal/processors/datastructures/GridAtomicCacheQueueImpl.java]. > h2. Design Details > The most natural way to implement such map, would be to store every value > under a separate key in an Ignite cache. For example, let's say that we have > a key {{K}} with multiple values: {{V0, V1, V2, ...}}. Then the cache should > end up with the following values {{K0, V0}}, {{K1, V1}}, {{K2, V2}}, etc. > This means that we need to wrap user key into our own, internal key, which > will also have {{index}} field. > Also note that we need to collocate all the values for the same key on the > same node, which means that we need to define user key K as the affinity key, > like so: > {code} > class MultiKey { > @CacheAffinityMapped > private K key; > int index; > } > {code} > Look ups of values at specific indexes becomes very simple. Just attach a > specific index to a key and do a cache lookup. Look ups for all values for a > key should work as following: > {code} > MultiKey key; > V v = null; > int index = 0; > List res = new LinkedList<>(); > do { > v = cache.get(MultiKey(K, index)); > if (v != null) > res.add(v); > index++; > } > while (v != null); > return res; > {code} > We could also
[jira] [Commented] (IGNITE-8740) Support reuse of already initialized Ignite in IgniteSpringBean
[ https://issues.apache.org/jira/browse/IGNITE-8740?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=16520887#comment-16520887 ] Amir Akhmedov commented on IGNITE-8740: --- [~vkulichenko], yes, if SCM/STM initialized after {{IgniteSpringBean}} (which was the case before -IGNITE-6555- implementation) then everything will work as expected. {{ContextRefreshedEvent}} is a guarantee which says every bean is setup and ready and after that I'm setting Ignite references in SCM/STM > Support reuse of already initialized Ignite in IgniteSpringBean > --- > > Key: IGNITE-8740 > URL: https://issues.apache.org/jira/browse/IGNITE-8740 > Project: Ignite > Issue Type: Improvement > Components: spring >Affects Versions: 2.4 >Reporter: Ilya Kasnacheev >Assignee: Amir Akhmedov >Priority: Blocker > Fix For: 2.6 > > > See > http://apache-ignite-users.70518.x6.nabble.com/IgniteSpringBean-amp-Ignite-SpringTransactionManager-broken-with-2-4-td21667.html#a21724 > (there's patch available) > The idea is to introduce a workaround for users hit by IGNITE-6555, which > unfortunately broke some scenarios. -- This message was sent by Atlassian JIRA (v7.6.3#76005)
[jira] [Commented] (IGNITE-8740) Support reuse of already initialized Ignite in IgniteSpringBean
[ https://issues.apache.org/jira/browse/IGNITE-8740?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=16520861#comment-16520861 ] Amir Akhmedov commented on IGNITE-8740: --- [~vkulichenko], In general, we can add {{setIgnite(Ignite ignite)}} to make dependency injection explicit but today you can pass instance of {{IgniteConfiguration}} or set a path to {{IgniteConfiguration}} in {{SpringCacheManager/}}{{SpringTransactionManager}} (SCM/STM) and it brings up an Ignite instance (it's done in {{afterPropertiesSet()}}) But the issue occurs only if you want to use {{IgniteSpringBean}}. What's happening today, since {{IgniteSpringBean}} implements {{SmartInitializingSingleton}} it will start it's initialization right after all singleton scope beans are initialized (which SCM and STM are) and since in SCM/STM referring to Ignite instance in afterPropertiesSet() it can't find and failing (ignite will be instantiated later in {{IgniteSpringBean}}). So, what ApplicationListener does, it's listening to {{ContextRefreshedEvent}} which is published when all Spring beans are initialized (including {{IgniteSpringBean}}). And what I'm doing is waiting to this event to happen and finalizing SCM/STM initialization in onApplicationEvent(ContextRefreshedEvent event) method. > Support reuse of already initialized Ignite in IgniteSpringBean > --- > > Key: IGNITE-8740 > URL: https://issues.apache.org/jira/browse/IGNITE-8740 > Project: Ignite > Issue Type: Improvement > Components: spring >Affects Versions: 2.4 >Reporter: Ilya Kasnacheev >Assignee: Amir Akhmedov >Priority: Blocker > Fix For: 2.6 > > > See > http://apache-ignite-users.70518.x6.nabble.com/IgniteSpringBean-amp-Ignite-SpringTransactionManager-broken-with-2-4-td21667.html#a21724 > (there's patch available) > The idea is to introduce a workaround for users hit by IGNITE-6555, which > unfortunately broke some scenarios. -- This message was sent by Atlassian JIRA (v7.6.3#76005)
[jira] [Assigned] (IGNITE-8740) Support reuse of already initialized Ignite in IgniteSpringBean
[ https://issues.apache.org/jira/browse/IGNITE-8740?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ] Amir Akhmedov reassigned IGNITE-8740: - Assignee: Amir Akhmedov > Support reuse of already initialized Ignite in IgniteSpringBean > --- > > Key: IGNITE-8740 > URL: https://issues.apache.org/jira/browse/IGNITE-8740 > Project: Ignite > Issue Type: Improvement > Components: spring >Affects Versions: 2.4 >Reporter: Ilya Kasnacheev >Assignee: Amir Akhmedov >Priority: Blocker > Fix For: 2.6 > > > See > http://apache-ignite-users.70518.x6.nabble.com/IgniteSpringBean-amp-Ignite-SpringTransactionManager-broken-with-2-4-td21667.html#a21724 > (there's patch available) > The idea is to introduce a workaround for users hit by IGNITE-6555, which > unfortunately broke some scenarios. -- This message was sent by Atlassian JIRA (v7.6.3#76005)
[jira] [Commented] (IGNITE-640) Implement IgniteMultimap data structures
[ https://issues.apache.org/jira/browse/IGNITE-640?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=16514979#comment-16514979 ] Amir Akhmedov commented on IGNITE-640: -- New pull request created [https://github.com/apache/ignite/pull/4207] > Implement IgniteMultimap data structures > > > Key: IGNITE-640 > URL: https://issues.apache.org/jira/browse/IGNITE-640 > Project: Ignite > Issue Type: Sub-task > Components: data structures >Reporter: Dmitriy Setrakyan >Assignee: Amir Akhmedov >Priority: Major > Fix For: 2.6 > > > We need to add {{IgniteMultimap}} data structure in addition to other data > structures provided by Ignite. {{IgniteMultiMap}} should have similar API to > {{java.util.Map}} class in JDK, but support the semantics of multiple values > per key, similar to [Guava > Multimap|http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/Multimap.html]. > > However, unlike in Guava, our multi-map should work with Lists, not > Collections. Lists should make it possible to support the following methods: > {code} > // Gets value at a certain index for a key. > V get(K, index); > // Gets all values for a collection of keys at a certain index. > Map getAll(Collection, index); > // Gets values for specified indexes for a key. > List get(K, Iterable indexes); > // Gets all values for a collection of keys at specified indexes. > Map> getAll(Collection, Iterable indexes); > // Gets values for specified range of indexes, between min and max. > List get(K, int min, int max); > // Gets all values for a collection of keys for a specified index range, > between min and max. > Map> getAll(Collection, int min, int max); > // Gets all values for a specific key. > List get(K); > // Gets all values for a collection of keys. > Map> getAll(Collection); > // Iterate through all elements with a certain index. > Iterator> iterate(int idx); > // Do we need this? > Collection> get(K, IgniteBiPredicate) > {code} > Multimap should also support colocated and non-colocated modes, similar to > [IgniteQueue|https://github.com/apache/incubator-ignite/blob/master/modules/core/src/main/java/org/apache/ignite/IgniteQueue.java] > and its implementation, > [GridAtomicCacheQueueImpl|https://github.com/apache/incubator-ignite/blob/master/modules/core/src/main/java/org/apache/ignite/internal/processors/datastructures/GridAtomicCacheQueueImpl.java]. > h2. Design Details > The most natural way to implement such map, would be to store every value > under a separate key in an Ignite cache. For example, let's say that we have > a key {{K}} with multiple values: {{V0, V1, V2, ...}}. Then the cache should > end up with the following values {{K0, V0}}, {{K1, V1}}, {{K2, V2}}, etc. > This means that we need to wrap user key into our own, internal key, which > will also have {{index}} field. > Also note that we need to collocate all the values for the same key on the > same node, which means that we need to define user key K as the affinity key, > like so: > {code} > class MultiKey { > @CacheAffinityMapped > private K key; > int index; > } > {code} > Look ups of values at specific indexes becomes very simple. Just attach a > specific index to a key and do a cache lookup. Look ups for all values for a > key should work as following: > {code} > MultiKey key; > V v = null; > int index = 0; > List res = new LinkedList<>(); > do { > v = cache.get(MultiKey(K, index)); > if (v != null) > res.add(v); > index++; > } > while (v != null); > return res; > {code} > We could also use batching for performance reason. In this case the batch > size should be configurable. > {code} > int index = 0; > List res = new LinkedList<>(); > while (true) { > List batch = new ArrayList<>(batchSize); > // Populate batch. > for (; index < batchSize; index++) > batch.add(new MultiKey(K, index % batchSize); > Map batchRes = cache.getAll(batch); > // Potentially need to properly sort values, based on the key order, > // if the returning map does not do it automatically. > res.addAll(batchRes.values()); > if (res.size() < batch.size()) > break; > } > return res; > {code} > h2. Evictions > Evictions in the {{IgniteMultiMap}} should have 2 levels: maximum number of > keys, and maximum number of values for a key. The maximum number of keys > should be controlled by Ignite standard eviction policy. The maximum number > of values for a key should be controlled by the implementation of the > multi-map. Either eviction parameter should be configurable. -- This message was sent by Atlassian JIRA (v7.6.3#76005)
[jira] [Commented] (IGNITE-640) Implement IgniteMultimap data structures
[ https://issues.apache.org/jira/browse/IGNITE-640?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=16501233#comment-16501233 ] Amir Akhmedov commented on IGNITE-640: -- Hi [~avinogradov], Thanks for your time to review and comment my changes. Please find below my comments: # I think Map and Set look similar at first glance but in general they implement two different interfaces which has nothing in common. In terms of Ignite we can build similar infrastructure on CacheDataStructuresManager and DataStructuresProcessor levels but I doubt we can come up with generic easy maintainable design for both of them. # Agree. I could say the methods queue0 and multimap0 in CacheDataStructuresManager are identical and would be nice to merge them into one but I can't make my mind how to do this cause despite having the similar flow those methods operate with different object types, arguments, predicates etc. If you have an idea how to converge them would be happy to listen to it. # Fixed. # Fixed in most places. Will look more carefully in next days. # Fixed. # Sorry, I'm not following. Can you please put more details how GridCacheMultimapApiSelfAbstractTest could be shortened? # Fixed. # Fixed. # I tried my best and did something wrong, now my PR looks ugly :) I don't know can it be reverted back or not. Please let me know if you have any other inquiries or concerns. > Implement IgniteMultimap data structures > > > Key: IGNITE-640 > URL: https://issues.apache.org/jira/browse/IGNITE-640 > Project: Ignite > Issue Type: Sub-task > Components: data structures >Reporter: Dmitriy Setrakyan >Assignee: Amir Akhmedov >Priority: Major > Fix For: 2.6 > > > We need to add {{IgniteMultimap}} data structure in addition to other data > structures provided by Ignite. {{IgniteMultiMap}} should have similar API to > {{java.util.Map}} class in JDK, but support the semantics of multiple values > per key, similar to [Guava > Multimap|http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/Multimap.html]. > > However, unlike in Guava, our multi-map should work with Lists, not > Collections. Lists should make it possible to support the following methods: > {code} > // Gets value at a certain index for a key. > V get(K, index); > // Gets all values for a collection of keys at a certain index. > Map getAll(Collection, index); > // Gets values for specified indexes for a key. > List get(K, Iterable indexes); > // Gets all values for a collection of keys at specified indexes. > Map> getAll(Collection, Iterable indexes); > // Gets values for specified range of indexes, between min and max. > List get(K, int min, int max); > // Gets all values for a collection of keys for a specified index range, > between min and max. > Map> getAll(Collection, int min, int max); > // Gets all values for a specific key. > List get(K); > // Gets all values for a collection of keys. > Map> getAll(Collection); > // Iterate through all elements with a certain index. > Iterator> iterate(int idx); > // Do we need this? > Collection> get(K, IgniteBiPredicate) > {code} > Multimap should also support colocated and non-colocated modes, similar to > [IgniteQueue|https://github.com/apache/incubator-ignite/blob/master/modules/core/src/main/java/org/apache/ignite/IgniteQueue.java] > and its implementation, > [GridAtomicCacheQueueImpl|https://github.com/apache/incubator-ignite/blob/master/modules/core/src/main/java/org/apache/ignite/internal/processors/datastructures/GridAtomicCacheQueueImpl.java]. > h2. Design Details > The most natural way to implement such map, would be to store every value > under a separate key in an Ignite cache. For example, let's say that we have > a key {{K}} with multiple values: {{V0, V1, V2, ...}}. Then the cache should > end up with the following values {{K0, V0}}, {{K1, V1}}, {{K2, V2}}, etc. > This means that we need to wrap user key into our own, internal key, which > will also have {{index}} field. > Also note that we need to collocate all the values for the same key on the > same node, which means that we need to define user key K as the affinity key, > like so: > {code} > class MultiKey { > @CacheAffinityMapped > private K key; > int index; > } > {code} > Look ups of values at specific indexes becomes very simple. Just attach a > specific index to a key and do a cache lookup. Look ups for all values for a > key should work as following: > {code} > MultiKey key; > V v = null; > int index = 0; > List res = new LinkedList<>(); > do { > v = cache.get(MultiKey(K, index)); > if (v != null) > res.add(v); > index++; > } > while (v != null); > return res; > {code} > We could also use batching for performance reason. In this case the
[jira] [Commented] (IGNITE-3999) Support case insensitive search in SQL
[ https://issues.apache.org/jira/browse/IGNITE-3999?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=16472897#comment-16472897 ] Amir Akhmedov commented on IGNITE-3999: --- [~dpavlov], [~vozerov], [~vkulichenko] I would be more than happy to contribute a function indexes but I will need some guidance on it. > Support case insensitive search in SQL > -- > > Key: IGNITE-3999 > URL: https://issues.apache.org/jira/browse/IGNITE-3999 > Project: Ignite > Issue Type: Improvement > Components: sql >Affects Versions: 1.7 >Reporter: Valentin Kulichenko >Assignee: Amir Akhmedov >Priority: Critical > Labels: sql-engine > Fix For: 2.6 > > > Currently case insensitive search is possible only with the help of > {{lower()}} function: > {code} > select name from MyValue where lower(name) = 'abc_5' > {code} > But this will always be a full scan, even if {{name}} field is indexed. > We need to correctly support {{VARCHAR_IGNORECASE}} H2 type in Ignite and add > a respective property to {{@QuerySqlField}} annotation. -- This message was sent by Atlassian JIRA (v7.6.3#76005)
[jira] [Commented] (IGNITE-3999) Support case insensitive search in SQL
[ https://issues.apache.org/jira/browse/IGNITE-3999?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=16468282#comment-16468282 ] Amir Akhmedov commented on IGNITE-3999: --- Hi [~vozerov], thank you for your time to review it and your comments are highly appreciated. I agree with you on the approaches to support case sensitivity and as per me functional index is a better choice. Do you think I need to close the ticket with "Won't fix" status? > Support case insensitive search in SQL > -- > > Key: IGNITE-3999 > URL: https://issues.apache.org/jira/browse/IGNITE-3999 > Project: Ignite > Issue Type: Improvement > Components: sql >Affects Versions: 1.7 >Reporter: Valentin Kulichenko >Assignee: Amir Akhmedov >Priority: Critical > Labels: sql-engine > Fix For: 2.6 > > > Currently case insensitive search is possible only with the help of > {{lower()}} function: > {code} > select name from MyValue where lower(name) = 'abc_5' > {code} > But this will always be a full scan, even if {{name}} field is indexed. > We need to correctly support {{VARCHAR_IGNORECASE}} H2 type in Ignite and add > a respective property to {{@QuerySqlField}} annotation. -- This message was sent by Atlassian JIRA (v7.6.3#76005)
[jira] [Commented] (IGNITE-640) Implement IgniteMultimap data structures
[ https://issues.apache.org/jira/browse/IGNITE-640?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=16459702#comment-16459702 ] Amir Akhmedov commented on IGNITE-640: -- Hi All, Could someone please check my pull request? PR: [https://github.com/apache/ignite/pull/3926] TC Run: [https://ci.ignite.apache.org/viewLog.html?buildId=1255210=buildResultsDiv=IgniteTests24Java8_RunAll] > Implement IgniteMultimap data structures > > > Key: IGNITE-640 > URL: https://issues.apache.org/jira/browse/IGNITE-640 > Project: Ignite > Issue Type: Sub-task > Components: data structures >Reporter: Dmitriy Setrakyan >Assignee: Amir Akhmedov >Priority: Major > Fix For: 2.6 > > > We need to add {{IgniteMultimap}} data structure in addition to other data > structures provided by Ignite. {{IgniteMultiMap}} should have similar API to > {{java.util.Map}} class in JDK, but support the semantics of multiple values > per key, similar to [Guava > Multimap|http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/Multimap.html]. > > However, unlike in Guava, our multi-map should work with Lists, not > Collections. Lists should make it possible to support the following methods: > {code} > // Gets value at a certain index for a key. > V get(K, index); > // Gets all values for a collection of keys at a certain index. > MapgetAll(Collection, index); > // Gets values for specified indexes for a key. > List get(K, Iterable indexes); > // Gets all values for a collection of keys at specified indexes. > Map getAll(Collection, Iterable indexes); > // Gets values for specified range of indexes, between min and max. > List get(K, int min, int max); > // Gets all values for a collection of keys for a specified index range, > between min and max. > Map getAll(Collection, int min, int max); > // Gets all values for a specific key. > List get(K); > // Gets all values for a collection of keys. > Map getAll(Collection); > // Iterate through all elements with a certain index. > Iterator > iterate(int idx); > // Do we need this? > Collection get(K, IgniteBiPredicate ) > {code} > Multimap should also support colocated and non-colocated modes, similar to > [IgniteQueue|https://github.com/apache/incubator-ignite/blob/master/modules/core/src/main/java/org/apache/ignite/IgniteQueue.java] > and its implementation, > [GridAtomicCacheQueueImpl|https://github.com/apache/incubator-ignite/blob/master/modules/core/src/main/java/org/apache/ignite/internal/processors/datastructures/GridAtomicCacheQueueImpl.java]. > h2. Design Details > The most natural way to implement such map, would be to store every value > under a separate key in an Ignite cache. For example, let's say that we have > a key {{K}} with multiple values: {{V0, V1, V2, ...}}. Then the cache should > end up with the following values {{K0, V0}}, {{K1, V1}}, {{K2, V2}}, etc. > This means that we need to wrap user key into our own, internal key, which > will also have {{index}} field. > Also note that we need to collocate all the values for the same key on the > same node, which means that we need to define user key K as the affinity key, > like so: > {code} > class MultiKey { > @CacheAffinityMapped > private K key; > int index; > } > {code} > Look ups of values at specific indexes becomes very simple. Just attach a > specific index to a key and do a cache lookup. Look ups for all values for a > key should work as following: > {code} > MultiKey key; > V v = null; > int index = 0; > List res = new LinkedList<>(); > do { > v = cache.get(MultiKey(K, index)); > if (v != null) > res.add(v); > index++; > } > while (v != null); > return res; > {code} > We could also use batching for performance reason. In this case the batch > size should be configurable. > {code} > int index = 0; > List res = new LinkedList<>(); > while (true) { > List batch = new ArrayList<>(batchSize); > // Populate batch. > for (; index < batchSize; index++) > batch.add(new MultiKey(K, index % batchSize); > Map batchRes = cache.getAll(batch); > // Potentially need to properly sort values, based on the key order, > // if the returning map does not do it automatically. > res.addAll(batchRes.values()); > if (res.size() < batch.size()) > break; > } > return res; > {code} > h2. Evictions > Evictions in the {{IgniteMultiMap}} should have 2 levels: maximum number of > keys, and maximum number of values for a key. The maximum number of keys > should be controlled by Ignite standard eviction policy. The maximum number > of values for a key should be controlled by the implementation of the > multi-map. Either eviction
[jira] [Commented] (IGNITE-3999) Support case insensitive search in SQL
[ https://issues.apache.org/jira/browse/IGNITE-3999?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=16454752#comment-16454752 ] Amir Akhmedov commented on IGNITE-3999: --- [~dpavlov], conflicts resolved. > Support case insensitive search in SQL > -- > > Key: IGNITE-3999 > URL: https://issues.apache.org/jira/browse/IGNITE-3999 > Project: Ignite > Issue Type: Improvement > Components: sql >Affects Versions: 1.7 >Reporter: Valentin Kulichenko >Assignee: Amir Akhmedov >Priority: Critical > Labels: sql-engine > Fix For: 2.6 > > > Currently case insensitive search is possible only with the help of > {{lower()}} function: > {code} > select name from MyValue where lower(name) = 'abc_5' > {code} > But this will always be a full scan, even if {{name}} field is indexed. > We need to correctly support {{VARCHAR_IGNORECASE}} H2 type in Ignite and add > a respective property to {{@QuerySqlField}} annotation. -- This message was sent by Atlassian JIRA (v7.6.3#76005)
[jira] [Updated] (IGNITE-640) Implement IgniteMultimap data structures
[ https://issues.apache.org/jira/browse/IGNITE-640?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ] Amir Akhmedov updated IGNITE-640: - Fix Version/s: 2.6 > Implement IgniteMultimap data structures > > > Key: IGNITE-640 > URL: https://issues.apache.org/jira/browse/IGNITE-640 > Project: Ignite > Issue Type: Sub-task > Components: data structures >Reporter: Dmitriy Setrakyan >Assignee: Amir Akhmedov >Priority: Major > Fix For: 2.6 > > > We need to add {{IgniteMultimap}} data structure in addition to other data > structures provided by Ignite. {{IgniteMultiMap}} should have similar API to > {{java.util.Map}} class in JDK, but support the semantics of multiple values > per key, similar to [Guava > Multimap|http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/Multimap.html]. > > However, unlike in Guava, our multi-map should work with Lists, not > Collections. Lists should make it possible to support the following methods: > {code} > // Gets value at a certain index for a key. > V get(K, index); > // Gets all values for a collection of keys at a certain index. > MapgetAll(Collection, index); > // Gets values for specified indexes for a key. > List get(K, Iterable indexes); > // Gets all values for a collection of keys at specified indexes. > Map getAll(Collection, Iterable indexes); > // Gets values for specified range of indexes, between min and max. > List get(K, int min, int max); > // Gets all values for a collection of keys for a specified index range, > between min and max. > Map getAll(Collection, int min, int max); > // Gets all values for a specific key. > List get(K); > // Gets all values for a collection of keys. > Map getAll(Collection); > // Iterate through all elements with a certain index. > Iterator > iterate(int idx); > // Do we need this? > Collection get(K, IgniteBiPredicate ) > {code} > Multimap should also support colocated and non-colocated modes, similar to > [IgniteQueue|https://github.com/apache/incubator-ignite/blob/master/modules/core/src/main/java/org/apache/ignite/IgniteQueue.java] > and its implementation, > [GridAtomicCacheQueueImpl|https://github.com/apache/incubator-ignite/blob/master/modules/core/src/main/java/org/apache/ignite/internal/processors/datastructures/GridAtomicCacheQueueImpl.java]. > h2. Design Details > The most natural way to implement such map, would be to store every value > under a separate key in an Ignite cache. For example, let's say that we have > a key {{K}} with multiple values: {{V0, V1, V2, ...}}. Then the cache should > end up with the following values {{K0, V0}}, {{K1, V1}}, {{K2, V2}}, etc. > This means that we need to wrap user key into our own, internal key, which > will also have {{index}} field. > Also note that we need to collocate all the values for the same key on the > same node, which means that we need to define user key K as the affinity key, > like so: > {code} > class MultiKey { > @CacheAffinityMapped > private K key; > int index; > } > {code} > Look ups of values at specific indexes becomes very simple. Just attach a > specific index to a key and do a cache lookup. Look ups for all values for a > key should work as following: > {code} > MultiKey key; > V v = null; > int index = 0; > List res = new LinkedList<>(); > do { > v = cache.get(MultiKey(K, index)); > if (v != null) > res.add(v); > index++; > } > while (v != null); > return res; > {code} > We could also use batching for performance reason. In this case the batch > size should be configurable. > {code} > int index = 0; > List res = new LinkedList<>(); > while (true) { > List batch = new ArrayList<>(batchSize); > // Populate batch. > for (; index < batchSize; index++) > batch.add(new MultiKey(K, index % batchSize); > Map batchRes = cache.getAll(batch); > // Potentially need to properly sort values, based on the key order, > // if the returning map does not do it automatically. > res.addAll(batchRes.values()); > if (res.size() < batch.size()) > break; > } > return res; > {code} > h2. Evictions > Evictions in the {{IgniteMultiMap}} should have 2 levels: maximum number of > keys, and maximum number of values for a key. The maximum number of keys > should be controlled by Ignite standard eviction policy. The maximum number > of values for a key should be controlled by the implementation of the > multi-map. Either eviction parameter should be configurable. -- This message was sent by Atlassian JIRA (v7.6.3#76005)
[jira] [Commented] (IGNITE-3999) Support case insensitive search in SQL
[ https://issues.apache.org/jira/browse/IGNITE-3999?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=16429255#comment-16429255 ] Amir Akhmedov commented on IGNITE-3999: --- [~NIzhikov], I fixed the comments except one, left a response in Upsource. Can you please check my changes and let me know? Thanks! > Support case insensitive search in SQL > -- > > Key: IGNITE-3999 > URL: https://issues.apache.org/jira/browse/IGNITE-3999 > Project: Ignite > Issue Type: Improvement > Components: sql >Affects Versions: 1.7 >Reporter: Valentin Kulichenko >Assignee: Amir Akhmedov >Priority: Critical > Labels: sql-engine > Fix For: 2.5 > > > Currently case insensitive search is possible only with the help of > {{lower()}} function: > {code} > select name from MyValue where lower(name) = 'abc_5' > {code} > But this will always be a full scan, even if {{name}} field is indexed. > We need to correctly support {{VARCHAR_IGNORECASE}} H2 type in Ignite and add > a respective property to {{@QuerySqlField}} annotation. -- This message was sent by Atlassian JIRA (v7.6.3#76005)
[jira] [Assigned] (IGNITE-640) Implement IgniteMultimap data structures
[ https://issues.apache.org/jira/browse/IGNITE-640?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ] Amir Akhmedov reassigned IGNITE-640: Assignee: Amir Akhmedov > Implement IgniteMultimap data structures > > > Key: IGNITE-640 > URL: https://issues.apache.org/jira/browse/IGNITE-640 > Project: Ignite > Issue Type: Sub-task > Components: data structures >Reporter: Dmitriy Setrakyan >Assignee: Amir Akhmedov >Priority: Major > > We need to add {{IgniteMultimap}} data structure in addition to other data > structures provided by Ignite. {{IgniteMultiMap}} should have similar API to > {{java.util.Map}} class in JDK, but support the semantics of multiple values > per key, similar to [Guava > Multimap|http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/Multimap.html]. > > However, unlike in Guava, our multi-map should work with Lists, not > Collections. Lists should make it possible to support the following methods: > {code} > // Gets value at a certain index for a key. > V get(K, index); > // Gets all values for a collection of keys at a certain index. > MapgetAll(Collection, index); > // Gets values for specified indexes for a key. > List get(K, Iterable indexes); > // Gets all values for a collection of keys at specified indexes. > Map getAll(Collection, Iterable indexes); > // Gets values for specified range of indexes, between min and max. > List get(K, int min, int max); > // Gets all values for a collection of keys for a specified index range, > between min and max. > Map getAll(Collection, int min, int max); > // Gets all values for a specific key. > List get(K); > // Gets all values for a collection of keys. > Map getAll(Collection); > // Iterate through all elements with a certain index. > Iterator > iterate(int idx); > // Do we need this? > Collection get(K, IgniteBiPredicate ) > {code} > Multimap should also support colocated and non-colocated modes, similar to > [IgniteQueue|https://github.com/apache/incubator-ignite/blob/master/modules/core/src/main/java/org/apache/ignite/IgniteQueue.java] > and its implementation, > [GridAtomicCacheQueueImpl|https://github.com/apache/incubator-ignite/blob/master/modules/core/src/main/java/org/apache/ignite/internal/processors/datastructures/GridAtomicCacheQueueImpl.java]. > h2. Design Details > The most natural way to implement such map, would be to store every value > under a separate key in an Ignite cache. For example, let's say that we have > a key {{K}} with multiple values: {{V0, V1, V2, ...}}. Then the cache should > end up with the following values {{K0, V0}}, {{K1, V1}}, {{K2, V2}}, etc. > This means that we need to wrap user key into our own, internal key, which > will also have {{index}} field. > Also note that we need to collocate all the values for the same key on the > same node, which means that we need to define user key K as the affinity key, > like so: > {code} > class MultiKey { > @CacheAffinityMapped > private K key; > int index; > } > {code} > Look ups of values at specific indexes becomes very simple. Just attach a > specific index to a key and do a cache lookup. Look ups for all values for a > key should work as following: > {code} > MultiKey key; > V v = null; > int index = 0; > List res = new LinkedList<>(); > do { > v = cache.get(MultiKey(K, index)); > if (v != null) > res.add(v); > index++; > } > while (v != null); > return res; > {code} > We could also use batching for performance reason. In this case the batch > size should be configurable. > {code} > int index = 0; > List res = new LinkedList<>(); > while (true) { > List batch = new ArrayList<>(batchSize); > // Populate batch. > for (; index < batchSize; index++) > batch.add(new MultiKey(K, index % batchSize); > Map batchRes = cache.getAll(batch); > // Potentially need to properly sort values, based on the key order, > // if the returning map does not do it automatically. > res.addAll(batchRes.values()); > if (res.size() < batch.size()) > break; > } > return res; > {code} > h2. Evictions > Evictions in the {{IgniteMultiMap}} should have 2 levels: maximum number of > keys, and maximum number of values for a key. The maximum number of keys > should be controlled by Ignite standard eviction policy. The maximum number > of values for a key should be controlled by the implementation of the > multi-map. Either eviction parameter should be configurable. -- This message was sent by Atlassian JIRA (v7.6.3#76005)
[jira] [Commented] (IGNITE-3999) Support case insensitive search in SQL
[ https://issues.apache.org/jira/browse/IGNITE-3999?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=16348079#comment-16348079 ] Amir Akhmedov commented on IGNITE-3999: --- [~al.psc], javadoc and style has been fixed and committed. > Support case insensitive search in SQL > -- > > Key: IGNITE-3999 > URL: https://issues.apache.org/jira/browse/IGNITE-3999 > Project: Ignite > Issue Type: Improvement > Components: sql >Affects Versions: 1.7 >Reporter: Valentin Kulichenko >Assignee: Amir Akhmedov >Priority: Critical > Fix For: 2.5 > > > Currently case insensitive search is possible only with the help of > {{lower()}} function: > {code} > select name from MyValue where lower(name) = 'abc_5' > {code} > But this will always be a full scan, even if {{name}} field is indexed. > We need to correctly support {{VARCHAR_IGNORECASE}} H2 type in Ignite and add > a respective property to {{@QuerySqlField}} annotation. -- This message was sent by Atlassian JIRA (v7.6.3#76005)
[jira] [Commented] (IGNITE-3999) Support case insensitive search in SQL
[ https://issues.apache.org/jira/browse/IGNITE-3999?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=16343609#comment-16343609 ] Amir Akhmedov commented on IGNITE-3999: --- [~vkulichenko], [~sergi.vladykin], can you please review my PR. > Support case insensitive search in SQL > -- > > Key: IGNITE-3999 > URL: https://issues.apache.org/jira/browse/IGNITE-3999 > Project: Ignite > Issue Type: Improvement > Components: sql >Affects Versions: 1.7 >Reporter: Valentin Kulichenko >Assignee: Amir Akhmedov >Priority: Critical > Fix For: 2.4 > > > Currently case insensitive search is possible only with the help of > {{lower()}} function: > {code} > select name from MyValue where lower(name) = 'abc_5' > {code} > But this will always be a full scan, even if {{name}} field is indexed. > We need to correctly support {{VARCHAR_IGNORECASE}} H2 type in Ignite and add > a respective property to {{@QuerySqlField}} annotation. -- This message was sent by Atlassian JIRA (v7.6.3#76005)
[jira] [Assigned] (IGNITE-3999) Support case insensitive search in SQL
[ https://issues.apache.org/jira/browse/IGNITE-3999?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ] Amir Akhmedov reassigned IGNITE-3999: - Assignee: Amir Akhmedov > Support case insensitive search in SQL > -- > > Key: IGNITE-3999 > URL: https://issues.apache.org/jira/browse/IGNITE-3999 > Project: Ignite > Issue Type: Improvement > Components: sql >Affects Versions: 1.7 >Reporter: Valentin Kulichenko >Assignee: Amir Akhmedov >Priority: Critical > > Currently case insensitive search is possible only with the help of > {{lower()}} function: > {code} > select name from MyValue where lower(name) = 'abc_5' > {code} > But this will always be a full scan, even if {{name}} field is indexed. > We need to correctly support {{VARCHAR_IGNORECASE}} H2 type in Ignite and add > a respective property to {{@QuerySqlField}} annotation. -- This message was sent by Atlassian JIRA (v7.6.3#76005)
[jira] [Assigned] (IGNITE-3999) Support case insensitive search in SQL
[ https://issues.apache.org/jira/browse/IGNITE-3999?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ] Amir Akhmedov reassigned IGNITE-3999: - Assignee: (was: Amir Akhmedov) > Support case insensitive search in SQL > -- > > Key: IGNITE-3999 > URL: https://issues.apache.org/jira/browse/IGNITE-3999 > Project: Ignite > Issue Type: Improvement > Components: cache >Affects Versions: 1.7 >Reporter: Valentin Kulichenko >Priority: Critical > Fix For: 2.1 > > > Currently case insensitive search is possible only with the help of > {{lower()}} function: > {code} > select name from MyValue where lower(name) = 'abc_5' > {code} > But this will always be a full scan, even if {{name}} field is indexed. > We need to correctly support {{VARCHAR_IGNORECASE}} H2 type in Ignite and add > a respective property to {{@QuerySqlField}} annotation. -- This message was sent by Atlassian JIRA (v6.3.15#6346)
[jira] [Comment Edited] (IGNITE-3699) CreatedExpiryPolicy doesn't work if entry is loaded from store
[ https://issues.apache.org/jira/browse/IGNITE-3699?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=15703061#comment-15703061 ] Amir Akhmedov edited comment on IGNITE-3699 at 11/28/16 8:42 PM: - Hi Semen, I updated PR with corresponding changes: 1. Switched JDK to version 7 and ran TeamCity tests. Some of them are failing but from test's history I see that they are also failing on master 2. Now {{getAllAsync0}} calculates the ttl and passes it to {{versionedValue}} 3. The change in GridDhtTxPrepareFuture was done to fix IGNITE-821. But I realized that it's not correct fix and reverted back the changes. Please let me know if you have any comments Thanks. was (Author: aakhmedov): Hi Semen, I updated PR with corresponding changes: 1. Switched JDK to version 7 and ran TeamCity tests. Some of them are failing but from test's history I see that they also failing on master 2. Now {{getAllAsync0}} calculates the ttl and passes it to {{versionedValue}} 3. The change in GridDhtTxPrepareFuture was done to fix IGNITE-821. But I realized that it's not correct fix and I reverted back the changes. Please let me know if you any comments Thanks. > CreatedExpiryPolicy doesn't work if entry is loaded from store > -- > > Key: IGNITE-3699 > URL: https://issues.apache.org/jira/browse/IGNITE-3699 > Project: Ignite > Issue Type: Bug > Components: cache >Affects Versions: 1.7 >Reporter: Valentin Kulichenko >Assignee: Amir Akhmedov >Priority: Critical > Fix For: 2.0 > > Attachments: LoadWithExpiryTest.java > > > According to JCache spec, {{ExpiryPolicy.getExpiryForCreation()}} must be > triggered on {{get()}} operation if the entry is loaded from the store. > Currently this is not happening. > Test reproducing the issue is attached. -- This message was sent by Atlassian JIRA (v6.3.4#6332)
[jira] [Comment Edited] (IGNITE-3699) CreatedExpiryPolicy doesn't work if entry is loaded from store
[ https://issues.apache.org/jira/browse/IGNITE-3699?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=15703061#comment-15703061 ] Amir Akhmedov edited comment on IGNITE-3699 at 11/28/16 8:41 PM: - Hi Semen, I updated PR with corresponding changes: 1. Switched JDK to version 7 and ran TeamCity tests. Some of them are failing but from test's history I see that they also failing on master 2. Now {{getAllAsync0}} calculates the ttl and passes it to {{versionedValue}} 3. The change in GridDhtTxPrepareFuture was done to fix IGNITE-821. But I realized that it's not correct fix and I reverted back the changes. Please let me know if you any comments Thanks. was (Author: aakhmedov): Hi Semen, I update PR with corresponding changes: 1. Switched JDK to version 7 and ran TeamCity tests. Some of them are failing but from test's history I see that they also failing on master 2. Now {{getAllAsync0}} calculates the ttl and passes it to {{versionedValue}} 3. The change in GridDhtTxPrepareFuture was done to fix IGNITE-821. But I realized that it's not correct fix and I reverted back the changes. Please let me know if you any comments Thanks. > CreatedExpiryPolicy doesn't work if entry is loaded from store > -- > > Key: IGNITE-3699 > URL: https://issues.apache.org/jira/browse/IGNITE-3699 > Project: Ignite > Issue Type: Bug > Components: cache >Affects Versions: 1.7 >Reporter: Valentin Kulichenko >Assignee: Amir Akhmedov >Priority: Critical > Fix For: 2.0 > > Attachments: LoadWithExpiryTest.java > > > According to JCache spec, {{ExpiryPolicy.getExpiryForCreation()}} must be > triggered on {{get()}} operation if the entry is loaded from the store. > Currently this is not happening. > Test reproducing the issue is attached. -- This message was sent by Atlassian JIRA (v6.3.4#6332)
[jira] [Commented] (IGNITE-3699) CreatedExpiryPolicy doesn't work if entry is loaded from store
[ https://issues.apache.org/jira/browse/IGNITE-3699?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=15703061#comment-15703061 ] Amir Akhmedov commented on IGNITE-3699: --- Hi Semen, I update PR with corresponding changes: 1. Switched JDK to version 7 and ran TeamCity tests. Some of them are failing but from test's history I see that they also failing on master 2. Now {{getAllAsync0}} calculates the ttl and passes it to {{versionedValue}} 3. The change in GridDhtTxPrepareFuture was done to fix IGNITE-821. But I realized that it's not correct fix and I reverted back the changes. Please let me know if you any comments Thanks. > CreatedExpiryPolicy doesn't work if entry is loaded from store > -- > > Key: IGNITE-3699 > URL: https://issues.apache.org/jira/browse/IGNITE-3699 > Project: Ignite > Issue Type: Bug > Components: cache >Affects Versions: 1.7 >Reporter: Valentin Kulichenko >Assignee: Amir Akhmedov >Priority: Critical > Fix For: 2.0 > > Attachments: LoadWithExpiryTest.java > > > According to JCache spec, {{ExpiryPolicy.getExpiryForCreation()}} must be > triggered on {{get()}} operation if the entry is loaded from the store. > Currently this is not happening. > Test reproducing the issue is attached. -- This message was sent by Atlassian JIRA (v6.3.4#6332)
[jira] [Assigned] (IGNITE-4176) IgniteQueue not functioning as expected after remove().
[ https://issues.apache.org/jira/browse/IGNITE-4176?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ] Amir Akhmedov reassigned IGNITE-4176: - Assignee: Amir Akhmedov > IgniteQueue not functioning as expected after remove(). > --- > > Key: IGNITE-4176 > URL: https://issues.apache.org/jira/browse/IGNITE-4176 > Project: Ignite > Issue Type: Bug > Components: data structures >Affects Versions: 1.7 >Reporter: C Saternos >Assignee: Amir Akhmedov > Fix For: 1.8 > > Attachments: WhereDidItGo.java, pom.xml > > > After removing an item from an IgniteQueue, the next item on the queue can be > viewed using peek(). However, poll() or take() does not retrieve the item. > When iterating through the remaining items in the queue, it appears that 1/2 > of them are missing. -- This message was sent by Atlassian JIRA (v6.3.4#6332)
[jira] [Updated] (IGNITE-4176) IgniteQueue not functioning as expected after remove().
[ https://issues.apache.org/jira/browse/IGNITE-4176?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ] Amir Akhmedov updated IGNITE-4176: -- Fix Version/s: 1.8 > IgniteQueue not functioning as expected after remove(). > --- > > Key: IGNITE-4176 > URL: https://issues.apache.org/jira/browse/IGNITE-4176 > Project: Ignite > Issue Type: Bug > Components: data structures >Affects Versions: 1.7 >Reporter: C Saternos >Assignee: Amir Akhmedov > Fix For: 1.8 > > Attachments: WhereDidItGo.java, pom.xml > > > After removing an item from an IgniteQueue, the next item on the queue can be > viewed using peek(). However, poll() or take() does not retrieve the item. > When iterating through the remaining items in the queue, it appears that 1/2 > of them are missing. -- This message was sent by Atlassian JIRA (v6.3.4#6332)
[jira] [Commented] (IGNITE-3999) Support case insensitive search in SQL
[ https://issues.apache.org/jira/browse/IGNITE-3999?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=15632998#comment-15632998 ] Amir Akhmedov commented on IGNITE-3999: --- [~vkulichenko], I have a concern on this ticket, can you please advise what will be the correct way to solve it. As of today, fields are defined as {{setFields(LinkedHashMapfields)}}, with introduction of case insensitive property need to create a new POJO e.g. {{QueryField(String type, boolean caseInsensitive)}}. So, to keep backward compatibility we can introduce a new method e.g. {{setQueryFields(LinkedHashMap fields)}}, in my opinion it looks like counter-intuitive with existing {{setFields}} method. Another possible way, this change can be done with changing the generic type of {{setFields}} (which will not be backward competible) and released in Ignite 2.0. Please advise on this, or maybe you have an alternative solutions? Thanks! > Support case insensitive search in SQL > -- > > Key: IGNITE-3999 > URL: https://issues.apache.org/jira/browse/IGNITE-3999 > Project: Ignite > Issue Type: Improvement > Components: cache >Affects Versions: 1.7 >Reporter: Valentin Kulichenko >Assignee: Amir Akhmedov >Priority: Critical > Fix For: 1.8 > > > Currently case insensitive search is possible only with the help of > {{lower()}} function: > {code} > select name from MyValue where lower(name) = 'abc_5' > {code} > But this will always be a full scan, even if {{name}} field is indexed. > We need to correctly support {{VARCHAR_IGNORECASE}} H2 type in Ignite and add > a respective property to {{@QuerySqlField}} annotation. -- This message was sent by Atlassian JIRA (v6.3.4#6332)
[jira] [Commented] (IGNITE-640) Implement IgniteMultimap data structures
[ https://issues.apache.org/jira/browse/IGNITE-640?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=15560441#comment-15560441 ] Amir Akhmedov commented on IGNITE-640: -- I had a question about implementation details of this ticket. In details it's said "The most natural way to implement such map, would be to store every value under a separate key in an Ignite cache" 1. How about memory footprint in this approach? We need to create a separate cache key for every value in multimap rather backing all the value for key under some data structure? 2. Retrieving the data by index for key will be much difficult in case of value removal e.g. {{multimap.put(key, "one"); multimap.put(key, "two"); multimap.put(key, "three"); multimap.remove(key, "two");}} In this case value "three" will have index 1 by Multimap API but internally (Ignite side) it has index 2 and need to take extra steps to handle such cases which hurt performance For me, backing structure for values in ArrayList will be optimal way to go. Please, advise? > Implement IgniteMultimap data structures > > > Key: IGNITE-640 > URL: https://issues.apache.org/jira/browse/IGNITE-640 > Project: Ignite > Issue Type: Sub-task > Components: data structures >Reporter: Dmitriy Setrakyan >Assignee: Amir Akhmedov > > We need to add {{IgniteMultimap}} data structure in addition to other data > structures provided by Ignite. {{IgniteMultiMap}} should have similar API to > {{java.util.Map}} class in JDK, but support the semantics of multiple values > per key, similar to [Guava > Multimap|http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/Multimap.html]. > > However, unlike in Guava, our multi-map should work with Lists, not > Collections. Lists should make it possible to support the following methods: > {code} > // Gets value at a certain index for a key. > V get(K, index); > // Gets all values for a collection of keys at a certain index. > MapgetAll(Collection, index); > // Gets values for specified indexes for a key. > List get(K, Iterable indexes); > // Gets all values for a collection of keys at specified indexes. > Map getAll(Collection, Iterable indexes); > // Gets values for specified range of indexes, between min and max. > List get(K, int min, int max); > // Gets all values for a collection of keys for a specified index range, > between min and max. > Map getAll(Collection, int min, int max); > // Gets all values for a specific key. > List get(K); > // Gets all values for a collection of keys. > Map getAll(Collection); > // Iterate through all elements with a certain index. > Iterator > iterate(int idx); > // Do we need this? > Collection get(K, IgniteBiPredicate ) > {code} > Multimap should also support colocated and non-colocated modes, similar to > [IgniteQueue|https://github.com/apache/incubator-ignite/blob/master/modules/core/src/main/java/org/apache/ignite/IgniteQueue.java] > and its implementation, > [GridAtomicCacheQueueImpl|https://github.com/apache/incubator-ignite/blob/master/modules/core/src/main/java/org/apache/ignite/internal/processors/datastructures/GridAtomicCacheQueueImpl.java]. > h2. Design Details > The most natural way to implement such map, would be to store every value > under a separate key in an Ignite cache. For example, let's say that we have > a key {{K}} with multiple values: {{V0, V1, V2, ...}}. Then the cache should > end up with the following values {{K0, V0}}, {{K1, V1}}, {{K2, V2}}, etc. > This means that we need to wrap user key into our own, internal key, which > will also have {{index}} field. > Also note that we need to collocate all the values for the same key on the > same node, which means that we need to define user key K as the affinity key, > like so: > {code} > class MultiKey { > @CacheAffinityMapped > private K key; > int index; > } > {code} > Look ups of values at specific indexes becomes very simple. Just attach a > specific index to a key and do a cache lookup. Look ups for all values for a > key should work as following: > {code} > MultiKey key; > V v = null; > int index = 0; > List res = new LinkedList<>(); > do { > v = cache.get(MultiKey(K, index)); > if (v != null) > res.add(v); > index++; > } > while (v != null); > return res; > {code} > We could also use batching for performance reason. In this case the batch > size should be configurable. > {code} > int index = 0; > List res = new LinkedList<>(); > while (true) { > List batch = new ArrayList<>(batchSize); > // Populate batch. > for (; index < batchSize; index++) > batch.add(new MultiKey(K, index % batchSize); > Map batchRes = cache.getAll(batch); > //
[jira] [Commented] (IGNITE-3699) CreatedExpiryPolicy doesn't work if entry is loaded from store
[ https://issues.apache.org/jira/browse/IGNITE-3699?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=15466316#comment-15466316 ] Amir Akhmedov commented on IGNITE-3699: --- [~vkulichenko], I updated PR. Reverted back tests for {{invoke}} and fixed ttl calculation for {{Transactional}} cache. Can you please review it and let me know. Thanks. > CreatedExpiryPolicy doesn't work if entry is loaded from store > -- > > Key: IGNITE-3699 > URL: https://issues.apache.org/jira/browse/IGNITE-3699 > Project: Ignite > Issue Type: Bug > Components: cache >Affects Versions: 1.7 >Reporter: Valentin Kulichenko >Assignee: Amir Akhmedov > Fix For: 1.8 > > Attachments: LoadWithExpiryTest.java > > > According to JCache spec, {{ExpiryPolicy.getExpiryForCreation()}} must be > triggered on {{get()}} operation if the entry is loaded from the store. > Currently this is not happening. > Test reproducing the issue is attached. -- This message was sent by Atlassian JIRA (v6.3.4#6332)
[jira] [Comment Edited] (IGNITE-3699) CreatedExpiryPolicy doesn't work if entry is loaded from store
[ https://issues.apache.org/jira/browse/IGNITE-3699?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=15457320#comment-15457320 ] Amir Akhmedov edited comment on IGNITE-3699 at 9/2/16 2:58 AM: --- [~vkulichenko], thank you for your comments. 1. Totally agree with you, will update the PR for this case. 2. In case of Atomic cache {{GridCacheAdapter.getAllAsync0}} is called. In this method if cache does not have a specified key it loads the value from store and creates a cache entry for the key-value pair. At this place I'm setting the TTL for this cache entry. was (Author: aakhmedov): [~vkulichenko], thank you for your comments. 1. Totally agree with you, will update the PR for this case. 2. In case of Atomic cache {noformat}GridCacheAdapter.getAllAsync0{noformat} is called. In this method if cache does not have a specified key it loads the value from store and creates a cache entry for the key-value pair. At this place I'm setting the TTL for this cache entry. > CreatedExpiryPolicy doesn't work if entry is loaded from store > -- > > Key: IGNITE-3699 > URL: https://issues.apache.org/jira/browse/IGNITE-3699 > Project: Ignite > Issue Type: Bug > Components: cache >Affects Versions: 1.7 >Reporter: Valentin Kulichenko >Assignee: Amir Akhmedov > Fix For: 1.8 > > Attachments: LoadWithExpiryTest.java > > > According to JCache spec, {{ExpiryPolicy.getExpiryForCreation()}} must be > triggered on {{get()}} operation if the entry is loaded from the store. > Currently this is not happening. > Test reproducing the issue is attached. -- This message was sent by Atlassian JIRA (v6.3.4#6332)
[jira] [Comment Edited] (IGNITE-3699) CreatedExpiryPolicy doesn't work if entry is loaded from store
[ https://issues.apache.org/jira/browse/IGNITE-3699?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=15457320#comment-15457320 ] Amir Akhmedov edited comment on IGNITE-3699 at 9/2/16 2:55 AM: --- [~vkulichenko], thank you for your comments. 1. Totally agree with you, will update the PR for this case. 2. In case of Atomic cache {noformat}GridCacheAdapter.getAllAsync0{noformat} is called. In this method if cache does not have a specified key it loads the value from store and creates a cache entry for the key-value pair. At this place I'm setting the TTL for this cache entry. was (Author: aakhmedov): [~vkulichenko], thank you for your comments. 1. Totally agree with you, will update the PR for this case. 2. In case of Atomic cache {code}GridCacheAdapter.getAllAsync0{code} is called. In this method if cache does not have a specified key it loads the value from store and creates a cache entry for the key-value pair. At this place I'm setting the TTL for this cache entry. > CreatedExpiryPolicy doesn't work if entry is loaded from store > -- > > Key: IGNITE-3699 > URL: https://issues.apache.org/jira/browse/IGNITE-3699 > Project: Ignite > Issue Type: Bug > Components: cache >Affects Versions: 1.7 >Reporter: Valentin Kulichenko >Assignee: Amir Akhmedov > Fix For: 1.8 > > Attachments: LoadWithExpiryTest.java > > > According to JCache spec, {{ExpiryPolicy.getExpiryForCreation()}} must be > triggered on {{get()}} operation if the entry is loaded from the store. > Currently this is not happening. > Test reproducing the issue is attached. -- This message was sent by Atlassian JIRA (v6.3.4#6332)
[jira] [Commented] (IGNITE-3699) CreatedExpiryPolicy doesn't work if entry is loaded from store
[ https://issues.apache.org/jira/browse/IGNITE-3699?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=15457320#comment-15457320 ] Amir Akhmedov commented on IGNITE-3699: --- [~vkulichenko], thank you for your comments. 1. Totally agree with you, will update the PR for this case. 2. In case of Atomic cache {code}GridCacheAdapter.getAllAsync0{code} is called. In this method if cache does not have a specified key it loads the value from store and creates a cache entry for the key-value pair. At this place I'm setting the TTL for this cache entry. > CreatedExpiryPolicy doesn't work if entry is loaded from store > -- > > Key: IGNITE-3699 > URL: https://issues.apache.org/jira/browse/IGNITE-3699 > Project: Ignite > Issue Type: Bug > Components: cache >Affects Versions: 1.7 >Reporter: Valentin Kulichenko >Assignee: Amir Akhmedov > Fix For: 1.8 > > Attachments: LoadWithExpiryTest.java > > > According to JCache spec, {{ExpiryPolicy.getExpiryForCreation()}} must be > triggered on {{get()}} operation if the entry is loaded from the store. > Currently this is not happening. > Test reproducing the issue is attached. -- This message was sent by Atlassian JIRA (v6.3.4#6332)
[jira] [Assigned] (IGNITE-3699) CreatedExpiryPolicy doesn't work if entry is loaded from store
[ https://issues.apache.org/jira/browse/IGNITE-3699?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ] Amir Akhmedov reassigned IGNITE-3699: - Assignee: Valentin Kulichenko (was: Amir Akhmedov) > CreatedExpiryPolicy doesn't work if entry is loaded from store > -- > > Key: IGNITE-3699 > URL: https://issues.apache.org/jira/browse/IGNITE-3699 > Project: Ignite > Issue Type: Bug > Components: cache >Affects Versions: 1.7 >Reporter: Valentin Kulichenko >Assignee: Valentin Kulichenko > Fix For: 1.8 > > Attachments: LoadWithExpiryTest.java > > > According to JCache spec, {{ExpiryPolicy.getExpiryForCreation()}} must be > triggered on {{get()}} operation if the entry is loaded from the store. > Currently this is not happening. > Test reproducing the issue is attached. -- This message was sent by Atlassian JIRA (v6.3.4#6332)
[jira] [Assigned] (IGNITE-3699) CreatedExpiryPolicy doesn't work if entry is loaded from store
[ https://issues.apache.org/jira/browse/IGNITE-3699?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ] Amir Akhmedov reassigned IGNITE-3699: - Assignee: Amir Akhmedov > CreatedExpiryPolicy doesn't work if entry is loaded from store > -- > > Key: IGNITE-3699 > URL: https://issues.apache.org/jira/browse/IGNITE-3699 > Project: Ignite > Issue Type: Bug > Components: cache >Affects Versions: 1.7 >Reporter: Valentin Kulichenko >Assignee: Amir Akhmedov > Fix For: 1.8 > > Attachments: LoadWithExpiryTest.java > > > According to JCache spec, {{ExpiryPolicy.getExpiryForCreation()}} must be > triggered on {{get()}} operation if the entry is loaded from the store. > Currently this is not happening. > Test reproducing the issue is attached. -- This message was sent by Atlassian JIRA (v6.3.4#6332)
[jira] [Commented] (IGNITE-640) Implement IgniteMultimap data structures
[ https://issues.apache.org/jira/browse/IGNITE-640?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=15420877#comment-15420877 ] Amir Akhmedov commented on IGNITE-640: -- Dmitriy, one interface is used as a base interface. Besides list-based I also provided interfaces for set-based for constant check, fetch operations and sortedset-based to keep the keys and values in order > Implement IgniteMultimap data structures > > > Key: IGNITE-640 > URL: https://issues.apache.org/jira/browse/IGNITE-640 > Project: Ignite > Issue Type: Sub-task > Components: data structures >Reporter: Dmitriy Setrakyan >Assignee: Amir Akhmedov > > We need to add {{IgniteMultimap}} data structure in addition to other data > structures provided by Ignite. {{IgniteMultiMap}} should have similar API to > {{java.util.Map}} class in JDK, but support the semantics of multiple values > per key, similar to [Guava > Multimap|http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/Multimap.html]. > > However, unlike in Guava, our multi-map should work with Lists, not > Collections. Lists should make it possible to support the following methods: > {code} > // Gets value at a certain index for a key. > V get(K, index); > // Gets all values for a collection of keys at a certain index. > MapgetAll(Collection, index); > // Gets values for specified indexes for a key. > List get(K, Iterable indexes); > // Gets all values for a collection of keys at specified indexes. > Map getAll(Collection, Iterable indexes); > // Gets values for specified range of indexes, between min and max. > List get(K, int min, int max); > // Gets all values for a collection of keys for a specified index range, > between min and max. > Map getAll(Collection, int min, int max); > // Gets all values for a specific key. > List get(K); > // Gets all values for a collection of keys. > Map getAll(Collection); > // Iterate through all elements with a certain index. > Iterator > iterate(int idx); > // Do we need this? > Collection get(K, IgniteBiPredicate ) > {code} > Multimap should also support colocated and non-colocated modes, similar to > [IgniteQueue|https://github.com/apache/incubator-ignite/blob/master/modules/core/src/main/java/org/apache/ignite/IgniteQueue.java] > and its implementation, > [GridAtomicCacheQueueImpl|https://github.com/apache/incubator-ignite/blob/master/modules/core/src/main/java/org/apache/ignite/internal/processors/datastructures/GridAtomicCacheQueueImpl.java]. > h2. Design Details > The most natural way to implement such map, would be to store every value > under a separate key in an Ignite cache. For example, let's say that we have > a key {{K}} with multiple values: {{V0, V1, V2, ...}}. Then the cache should > end up with the following values {{K0, V0}}, {{K1, V1}}, {{K2, V2}}, etc. > This means that we need to wrap user key into our own, internal key, which > will also have {{index}} field. > Also note that we need to collocate all the values for the same key on the > same node, which means that we need to define user key K as the affinity key, > like so: > {code} > class MultiKey { > @CacheAffinityMapped > private K key; > int index; > } > {code} > Look ups of values at specific indexes becomes very simple. Just attach a > specific index to a key and do a cache lookup. Look ups for all values for a > key should work as following: > {code} > MultiKey key; > V v = null; > int index = 0; > List res = new LinkedList<>(); > do { > v = cache.get(MultiKey(K, index)); > if (v != null) > res.add(v); > index++; > } > while (v != null); > return res; > {code} > We could also use batching for performance reason. In this case the batch > size should be configurable. > {code} > int index = 0; > List res = new LinkedList<>(); > while (true) { > List batch = new ArrayList<>(batchSize); > // Populate batch. > for (; index < batchSize; index++) > batch.add(new MultiKey(K, index % batchSize); > Map batchRes = cache.getAll(batch); > // Potentially need to properly sort values, based on the key order, > // if the returning map does not do it automatically. > res.addAll(batchRes.values()); > if (res.size() < batch.size()) > break; > } > return res; > {code} > h2. Evictions > Evictions in the {{IgniteMultiMap}} should have 2 levels: maximum number of > keys, and maximum number of values for a key. The maximum number of keys > should be controlled by Ignite standard eviction policy. The maximum number > of values for a key should be controlled by the implementation of the > multi-map. Either eviction parameter should be configurable. -- This message was sent
[jira] [Comment Edited] (IGNITE-640) Implement IgniteMultimap data structures
[ https://issues.apache.org/jira/browse/IGNITE-640?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=15420437#comment-15420437 ] Amir Akhmedov edited comment on IGNITE-640 at 8/14/16 6:46 PM: --- I'm proposing IgniteMultimap interface to be as Guava has: IgniteMultimap is a base interface and also there will be 3 derived interfaces: IgniteListMultimap, IgniteSetMultimap, IgniteSortedSetMultimap. All 3 subinterfaces will have Atomic and Transactional implementations. Please review it, any comments and concerns will be highly appreciated. {code:title=IgniteMultimap.java|borderStyle=solid} public interface IgniteMultimapextends Closeable { /** * Returns collection of values to which the specified key is mapped, * or empty collection if this multimap contains no mapping for the key. * * @param key the key whose associated values are to be returned * @return the list of values to which the specified key is mapped, * or empty collection if this multimap contains no mapping for the key. * @throws ClassCastException if the key is of an inappropriate type for this multimap */ public Collection get(K key); /** * Returns the list of values for a collection of keys to which the keys are mapped. * Empty collection will be added to resulting list if this multimap contains no mapping for the key. * @param keys collection of keys * @return the list of values for a collection of keys to which the keys are mapped. * Empty collection will be added to resulting list if this multimap contains no mapping for the key. * @throws ClassCastException if the key is of an inappropriate type for this multimap */ public Map getAll(Collection keys); /** * Clears the multimap. Removes all key-value pairs. */ public void clear(); /** * Returns {@code true} if this multimap contains a mapping for the specified key. * * @param key key whose presence in this multimap is to be tested * @return {@code true} if this multimap contains a mapping for the specified key * @throws ClassCastException if the key is of an inappropriate type for this multimap */ public boolean containsKey(K key); /** * Returns {@code true} if this multimap contains at least one key-value pair * with the value {@code value}. * * @param value value whose presence in this multimap is to be tested * @return {@code true} if this multimap contains at least one key-value pair * with the value {@code value}. * @throws ClassCastException if the key is of an inappropriate type for this multimap */ public boolean containsValue(V value); /** * Returns whether the multimap contains the given key-value pair. * * @param key key whose presence in this multimap is to be tested * @param value value whose presence in this multimap is to be tested * * @return {@code true} if the multimap contains the key-value pair, {@code false} otherwise * @throws ClassCastException if the key is of an inappropriate type for this multimap */ public boolean containsEntry(K key, V value); /** * Returns a {@link Collection} view of the mappings contained in this multimap. * * @return a {@link Collection} view of the mappings contained in this multimap. */ public Collection > entries(); /** * Returns the locally owned set of keys. * * @return the locally owned set of keys. */ public Set localKeySet(); /** * Returns a {@link Set} view of the keys contained in this multimap. * * @return a {@link Set} view of the keys contained in this multimap. */ public Set keySet(); /** * Associates the specified value with the specified key in this multimap * * @param key key with which the specified value is to be associated * @param value value to be associated with the specified key * @return {@code true} if the method increased the size of the multimap, or * {@code false} if the multimap already contained the key-value pair and * doesn't allow duplicates * @throws ClassCastException if the class of the specified key or value * prevents it from being stored in this multimap */ public boolean put(K key, V value); /** * Stores a key-value pair in this multimap for each of {@code values}, all * using the same key, {@code key}. Equivalent to (but expected to be more * efficient than):{@code * * for (V value : values) { * put(key, value); * }} * * In particular, this is a no-op if {@code values} is empty. * * @return {@code true} if the multimap changed * @throws ClassCastException if the class of the specified key or
[jira] [Commented] (IGNITE-640) Implement IgniteMultimap data structures
[ https://issues.apache.org/jira/browse/IGNITE-640?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=15420437#comment-15420437 ] Amir Akhmedov commented on IGNITE-640: -- I'm proposing IgniteMultimap interface to be as Guava has: IgniteMultimap is a base interface and also there will be 3 derived interfaces: IgniteListMultimap, IgniteSetMultimap, IgniteSortedSetMultimap. All 3 subinterfaces will have Atomic and Transactional implementations. Please review it, any comments and concerns will be highly appreciated. {code:title=IgniteMultimap.java|borderStyle=solid} public interface IgniteMultimapextends Closeable { /** * Returns collection of values to which the specified key is mapped, * or empty collection if this multimap contains no mapping for the key. * * @param key the key whose associated values are to be returned * @return the list of values to which the specified key is mapped, * or empty collection if this multimap contains no mapping for the key. * @throws ClassCastException if the key is of an inappropriate type for this multimap */ public Collection get(K key); /** * Returns the list of values for a collection of keys to which the keys are mapped. * Empty collection will be added to resulting list if this multimap contains no mapping for the key. * @param keys collection of keys * @return the list of values for a collection of keys to which the keys are mapped. * Empty collection will be added to resulting list if this multimap contains no mapping for the key. * @throws ClassCastException if the key is of an inappropriate type for this multimap */ public Map getAll(Collection keys); /** * Clears the multimap. Removes all key-value pairs. */ public void clear(); /** * Returns {@code true} if this multimap contains a mapping for the specified key. * * @param key key whose presence in this multimap is to be tested * @return {@code true} if this multimap contains a mapping for the specified key * @throws ClassCastException if the key is of an inappropriate type for this multimap */ public boolean containsKey(K key); /** * Returns {@code true} if this multimap contains at least one key-value pair * with the value {@code value}. * * @param value value whose presence in this multimap is to be tested * @return {@code true} if this multimap contains at least one key-value pair * with the value {@code value}. * @throws ClassCastException if the key is of an inappropriate type for this multimap */ public boolean containsValue(V value); /** * Returns whether the multimap contains the given key-value pair. * * @param key key whose presence in this multimap is to be tested * @param value value whose presence in this multimap is to be tested * * @return {@code true} if the multimap contains the key-value pair, {@code false} otherwise * @throws ClassCastException if the key is of an inappropriate type for this multimap */ public boolean containsEntry(K key, V value); /** * Returns a {@link Collection} view of the mappings contained in this multimap. * * @return a {@link Collection} view of the mappings contained in this multimap. */ public Collection > entries(); /** * Returns the locally owned set of keys. * * @return the locally owned set of keys. */ public Set localKeySet(); /** * Returns a {@link Set} view of the keys contained in this multimap. * * @return a {@link Set} view of the keys contained in this multimap. */ public Set keySet(); /** * Associates the specified value with the specified key in this multimap * * @param key key with which the specified value is to be associated * @param value value to be associated with the specified key * @return {@code true} if the method increased the size of the multimap, or * {@code false} if the multimap already contained the key-value pair and * doesn't allow duplicates * @throws ClassCastException if the class of the specified key or value * prevents it from being stored in this multimap */ public boolean put(K key, V value); /** * Stores a key-value pair in this multimap for each of {@code values}, all * using the same key, {@code key}. Equivalent to (but expected to be more * efficient than):{@code * * for (V value : values) { * put(key, value); * }} * * In particular, this is a no-op if {@code values} is empty. * * @return {@code true} if the multimap changed * @throws ClassCastException if the class of the specified key or value * prevents it from being stored in
[jira] [Commented] (IGNITE-640) Implement IgniteMultimap data structures
[ https://issues.apache.org/jira/browse/IGNITE-640?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=15420426#comment-15420426 ] Amir Akhmedov commented on IGNITE-640: -- Discussion thread: http://apache-ignite-developers.2346864.n4.nabble.com/IGNITE-640-IgniteMultimap-interface-draft-version-td10659.html > Implement IgniteMultimap data structures > > > Key: IGNITE-640 > URL: https://issues.apache.org/jira/browse/IGNITE-640 > Project: Ignite > Issue Type: Sub-task > Components: data structures >Reporter: Dmitriy Setrakyan >Assignee: Amir Akhmedov > > We need to add {{IgniteMultimap}} data structure in addition to other data > structures provided by Ignite. {{IgniteMultiMap}} should have similar API to > {{java.util.Map}} class in JDK, but support the semantics of multiple values > per key, similar to [Guava > Multimap|http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/Multimap.html]. > > However, unlike in Guava, our multi-map should work with Lists, not > Collections. Lists should make it possible to support the following methods: > {code} > // Gets value at a certain index for a key. > V get(K, index); > // Gets all values for a collection of keys at a certain index. > MapgetAll(Collection, index); > // Gets values for specified indexes for a key. > List get(K, Iterable indexes); > // Gets all values for a collection of keys at specified indexes. > Map getAll(Collection, Iterable indexes); > // Gets values for specified range of indexes, between min and max. > List get(K, int min, int max); > // Gets all values for a collection of keys for a specified index range, > between min and max. > Map getAll(Collection, int min, int max); > // Gets all values for a specific key. > List get(K); > // Gets all values for a collection of keys. > Map getAll(Collection); > // Iterate through all elements with a certain index. > Iterator > iterate(int idx); > // Do we need this? > Collection get(K, IgniteBiPredicate ) > {code} > Multimap should also support colocated and non-colocated modes, similar to > [IgniteQueue|https://github.com/apache/incubator-ignite/blob/master/modules/core/src/main/java/org/apache/ignite/IgniteQueue.java] > and its implementation, > [GridAtomicCacheQueueImpl|https://github.com/apache/incubator-ignite/blob/master/modules/core/src/main/java/org/apache/ignite/internal/processors/datastructures/GridAtomicCacheQueueImpl.java]. > h2. Design Details > The most natural way to implement such map, would be to store every value > under a separate key in an Ignite cache. For example, let's say that we have > a key {{K}} with multiple values: {{V0, V1, V2, ...}}. Then the cache should > end up with the following values {{K0, V0}}, {{K1, V1}}, {{K2, V2}}, etc. > This means that we need to wrap user key into our own, internal key, which > will also have {{index}} field. > Also note that we need to collocate all the values for the same key on the > same node, which means that we need to define user key K as the affinity key, > like so: > {code} > class MultiKey { > @CacheAffinityMapped > private K key; > int index; > } > {code} > Look ups of values at specific indexes becomes very simple. Just attach a > specific index to a key and do a cache lookup. Look ups for all values for a > key should work as following: > {code} > MultiKey key; > V v = null; > int index = 0; > List res = new LinkedList<>(); > do { > v = cache.get(MultiKey(K, index)); > if (v != null) > res.add(v); > index++; > } > while (v != null); > return res; > {code} > We could also use batching for performance reason. In this case the batch > size should be configurable. > {code} > int index = 0; > List res = new LinkedList<>(); > while (true) { > List batch = new ArrayList<>(batchSize); > // Populate batch. > for (; index < batchSize; index++) > batch.add(new MultiKey(K, index % batchSize); > Map batchRes = cache.getAll(batch); > // Potentially need to properly sort values, based on the key order, > // if the returning map does not do it automatically. > res.addAll(batchRes.values()); > if (res.size() < batch.size()) > break; > } > return res; > {code} > h2. Evictions > Evictions in the {{IgniteMultiMap}} should have 2 levels: maximum number of > keys, and maximum number of values for a key. The maximum number of keys > should be controlled by Ignite standard eviction policy. The maximum number > of values for a key should be controlled by the implementation of the > multi-map. Either eviction parameter should be configurable. -- This message was sent by Atlassian JIRA (v6.3.4#6332)
[jira] [Assigned] (IGNITE-640) Implement IgniteMultimap data structures
[ https://issues.apache.org/jira/browse/IGNITE-640?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ] Amir Akhmedov reassigned IGNITE-640: Assignee: Amir Akhmedov > Implement IgniteMultimap data structures > > > Key: IGNITE-640 > URL: https://issues.apache.org/jira/browse/IGNITE-640 > Project: Ignite > Issue Type: Sub-task > Components: data structures >Reporter: Dmitriy Setrakyan >Assignee: Amir Akhmedov > > We need to add {{IgniteMultimap}} data structure in addition to other data > structures provided by Ignite. {{IgniteMultiMap}} should have similar API to > {{java.util.Map}} class in JDK, but support the semantics of multiple values > per key, similar to [Guava > Multimap|http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/Multimap.html]. > > However, unlike in Guava, our multi-map should work with Lists, not > Collections. Lists should make it possible to support the following methods: > {code} > // Gets value at a certain index for a key. > V get(K, index); > // Gets all values for a collection of keys at a certain index. > MapgetAll(Collection, index); > // Gets values for specified indexes for a key. > List get(K, Iterable indexes); > // Gets all values for a collection of keys at specified indexes. > Map getAll(Collection, Iterable indexes); > // Gets values for specified range of indexes, between min and max. > List get(K, int min, int max); > // Gets all values for a collection of keys for a specified index range, > between min and max. > Map getAll(Collection, int min, int max); > // Gets all values for a specific key. > List get(K); > // Gets all values for a collection of keys. > Map getAll(Collection); > // Iterate through all elements with a certain index. > Iterator > iterate(int idx); > // Do we need this? > Collection get(K, IgniteBiPredicate ) > {code} > Multimap should also support colocated and non-colocated modes, similar to > [IgniteQueue|https://github.com/apache/incubator-ignite/blob/master/modules/core/src/main/java/org/apache/ignite/IgniteQueue.java] > and its implementation, > [GridAtomicCacheQueueImpl|https://github.com/apache/incubator-ignite/blob/master/modules/core/src/main/java/org/apache/ignite/internal/processors/datastructures/GridAtomicCacheQueueImpl.java]. > h2. Design Details > The most natural way to implement such map, would be to store every value > under a separate key in an Ignite cache. For example, let's say that we have > a key {{K}} with multiple values: {{V0, V1, V2, ...}}. Then the cache should > end up with the following values {{K0, V0}}, {{K1, V1}}, {{K2, V2}}, etc. > This means that we need to wrap user key into our own, internal key, which > will also have {{index}} field. > Also note that we need to collocate all the values for the same key on the > same node, which means that we need to define user key K as the affinity key, > like so: > {code} > class MultiKey { > @CacheAffinityMapped > private K key; > int index; > } > {code} > Look ups of values at specific indexes becomes very simple. Just attach a > specific index to a key and do a cache lookup. Look ups for all values for a > key should work as following: > {code} > MultiKey key; > V v = null; > int index = 0; > List res = new LinkedList<>(); > do { > v = cache.get(MultiKey(K, index)); > if (v != null) > res.add(v); > index++; > } > while (v != null); > return res; > {code} > We could also use batching for performance reason. In this case the batch > size should be configurable. > {code} > int index = 0; > List res = new LinkedList<>(); > while (true) { > List batch = new ArrayList<>(batchSize); > // Populate batch. > for (; index < batchSize; index++) > batch.add(new MultiKey(K, index % batchSize); > Map batchRes = cache.getAll(batch); > // Potentially need to properly sort values, based on the key order, > // if the returning map does not do it automatically. > res.addAll(batchRes.values()); > if (res.size() < batch.size()) > break; > } > return res; > {code} > h2. Evictions > Evictions in the {{IgniteMultiMap}} should have 2 levels: maximum number of > keys, and maximum number of values for a key. The maximum number of keys > should be controlled by Ignite standard eviction policy. The maximum number > of values for a key should be controlled by the implementation of the > multi-map. Either eviction parameter should be configurable. -- This message was sent by Atlassian JIRA (v6.3.4#6332)
[jira] [Assigned] (IGNITE-640) Implement IgniteMultimap data structures
[ https://issues.apache.org/jira/browse/IGNITE-640?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ] Amir Akhmedov reassigned IGNITE-640: Assignee: (was: Amir Akhmedov) > Implement IgniteMultimap data structures > > > Key: IGNITE-640 > URL: https://issues.apache.org/jira/browse/IGNITE-640 > Project: Ignite > Issue Type: Sub-task > Components: data structures >Reporter: Dmitriy Setrakyan > > We need to add {{IgniteMultimap}} data structure in addition to other data > structures provided by Ignite. {{IgniteMultiMap}} should have similar API to > {{java.util.Map}} class in JDK, but support the semantics of multiple values > per key, similar to [Guava > Multimap|http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/Multimap.html]. > > However, unlike in Guava, our multi-map should work with Lists, not > Collections. Lists should make it possible to support the following methods: > {code} > // Gets value at a certain index for a key. > V get(K, index); > // Gets all values for a collection of keys at a certain index. > MapgetAll(Collection, index); > // Gets values for specified indexes for a key. > Collection get(K, Iterable indexes); > // Gets all values for a collection of keys at specified indexes. > Map getAll(Collection, Iterable indexes); > // Gets values for specified range of indexes, between min and max. > Collection get(K, int min, int max); > // Gets all values for a collection of keys for a specified index range, > between min and max. > Map getAll(Collection, int min, int max); > // Gets all values for a specific key. > Collection get(K); > // Gets all values for a collection of keys. > Map getAll(Collection); > Collection get(K, IgniteBiPredicate ) > {code} > Multimap should also support colocated and non-colocated modes, similar to > [IgniteQueue|https://github.com/apache/incubator-ignite/blob/master/modules/core/src/main/java/org/apache/ignite/IgniteQueue.java] > and its implementation, > [GridAtomicCacheQueueImpl|https://github.com/apache/incubator-ignite/blob/master/modules/core/src/main/java/org/apache/ignite/internal/processors/datastructures/GridAtomicCacheQueueImpl.java]. > h2. Design Details > The most natural way to implement such map, would be to store every value > under a separate key in an Ignite cache. For example, let's say that we have > a key {{K}} with multiple values: {{V0, V1, V2, ...}}. Then the cache should > end up with the following values {{K0, V0}}, {{K1, V1}}, {{K2, V2}}, etc. > This means that we need to wrap user key into our own, internal key, which > will also have {{index}} field. > Also note that we need to collocate all the values for the same key on the > same node, which means that we need to define user key K as the affinity key, > like so: > {code} > class MultiKey { > @CacheAffinityMapped > private K key; > int index; > } > {code} > Look ups of values at specific indexes becomes very simple. Just attach a > specific index to a key and do a cache lookup. Look ups for all values for a > key should work as following: > {code} > MultiKey key; > V v = null; > int index = 0; > List res = new LinkedList<>(); > do { > v = cache.get(MultiKey(K, index)); > if (v != null) > res.add(v); > index++; > } > while (v != null); > return res; > {code} > We could also use batching for performance reason. In this case the batch > size should be configurable. > {code} > int index = 0; > List res = new LinkedList<>(); > while (true) { > List batch = new ArrayList<>(batchSize); > // Populate batch. > for (; index < batchSize; index++) > batch.add(new MultiKey(K, index % batchSize); > Map batchRes = cache.getAll(batch); > // Potentially need to properly sort values, based on the key order, > // if the returning map does not do it automatically. > res.addAll(batchRes.values()); > if (res.size() < batch.size()) > break; > } > return res; > {code} > h2. Evictions > Evictions in the {{IgniteMultiMap}} should have 2 levels: maximum number of > keys, and maximum number of values for a key. The maximum number of keys > should be controlled by Ignite standard eviction policy. The maximum number > of values for a key should be controlled by the implementation of the > multi-map. Either eviction parameter should be configurable. -- This message was sent by Atlassian JIRA (v6.3.4#6332)
[jira] [Assigned] (IGNITE-1227) Need to implement Ignite-based Spring transaction manager
[ https://issues.apache.org/jira/browse/IGNITE-1227?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ] Amir Akhmedov reassigned IGNITE-1227: - Assignee: Valentin Kulichenko (was: Amir Akhmedov) > Need to implement Ignite-based Spring transaction manager > - > > Key: IGNITE-1227 > URL: https://issues.apache.org/jira/browse/IGNITE-1227 > Project: Ignite > Issue Type: Improvement > Components: cache >Affects Versions: 1.1.4 >Reporter: Valentin Kulichenko >Assignee: Valentin Kulichenko > Labels: newbie > Attachments: IGNITE-1227.patch > > > This will allow to use Spring transaction interceptor for wrapping cache > operations into Ignite transaction. > Essentially, we need to implement Spring's {{PlatformTransactionManager}} > interface using {{IgniteTransactions}} API. > Corresponding user list thread: > http://apache-ignite-users.70518.x6.nabble.com/Transactions-td885.html -- This message was sent by Atlassian JIRA (v6.3.4#6332)
[jira] [Assigned] (IGNITE-640) Implement IgniteMultimap data structures
[ https://issues.apache.org/jira/browse/IGNITE-640?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ] Amir Akhmedov reassigned IGNITE-640: Assignee: Amir Akhmedov > Implement IgniteMultimap data structures > > > Key: IGNITE-640 > URL: https://issues.apache.org/jira/browse/IGNITE-640 > Project: Ignite > Issue Type: Sub-task > Components: data structures >Reporter: Dmitriy Setrakyan >Assignee: Amir Akhmedov > > We need to add {{IgniteMultimap}} data structure in addition to other data > structures provided by Ignite. {{IgniteMultiMap}} should have similar API to > {{java.util.Map}} class in JDK, but support the semantics of multiple values > per key, similar to [Guava > Multimap|http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/Multimap.html]. > > However, unlike in Guava, our multi-map should work with Lists, not > Collections. Lists should make it possible to support the following methods: > {code} > // Gets value at a certain index for a key. > V get(K, index); > // Gets all values for a collection of keys at a certain index. > MapgetAll(Collection, index); > // Gets values for specified indexes for a key. > Collection get(K, Iterable indexes); > // Gets all values for a collection of keys at specified indexes. > Map getAll(Collection, Iterable indexes); > // Gets values for specified range of indexes, between min and max. > Collection get(K, int min, int max); > // Gets all values for a collection of keys for a specified index range, > between min and max. > Map getAll(Collection, int min, int max); > // Gets all values for a specific key. > Collection get(K); > // Gets all values for a collection of keys. > Map getAll(Collection); > Collection get(K, IgniteBiPredicate ) > {code} > Multimap should also support colocated and non-colocated modes, similar to > [IgniteQueue|https://github.com/apache/incubator-ignite/blob/master/modules/core/src/main/java/org/apache/ignite/IgniteQueue.java] > and its implementation, > [GridAtomicCacheQueueImpl|https://github.com/apache/incubator-ignite/blob/master/modules/core/src/main/java/org/apache/ignite/internal/processors/datastructures/GridAtomicCacheQueueImpl.java]. > h2. Design Details > The most natural way to implement such map, would be to store every value > under a separate key in an Ignite cache. For example, let's say that we have > a key {{K}} with multiple values: {{V0, V1, V2, ...}}. Then the cache should > end up with the following values {{K0, V0}}, {{K1, V1}}, {{K2, V2}}, etc. > This means that we need to wrap user key into our own, internal key, which > will also have {{index}} field. > Also note that we need to collocate all the values for the same key on the > same node, which means that we need to define user key K as the affinity key, > like so: > {code} > class MultiKey { > @CacheAffinityMapped > private K key; > int index; > } > {code} > Look ups of values at specific indexes becomes very simple. Just attach a > specific index to a key and do a cache lookup. Look ups for all values for a > key should work as following: > {code} > MultiKey key; > V v = null; > int index = 0; > List res = new LinkedList<>(); > do { > v = cache.get(MultiKey(K, index)); > if (v != null) > res.add(v); > index++; > } > while (v != null); > return res; > {code} > We could also use batching for performance reason. In this case the batch > size should be configurable. > {code} > int index = 0; > List res = new LinkedList<>(); > while (true) { > List batch = new ArrayList<>(batchSize); > // Populate batch. > for (; index < batchSize; index++) > batch.add(new MultiKey(K, index % batchSize); > Map batchRes = cache.getAll(batch); > // Potentially need to properly sort values, based on the key order, > // if the returning map does not do it automatically. > res.addAll(batchRes.values()); > if (res.size() < batch.size()) > break; > } > return res; > {code} > h2. Evictions > Evictions in the {{IgniteMultiMap}} should have 2 levels: maximum number of > keys, and maximum number of values for a key. The maximum number of keys > should be controlled by Ignite standard eviction policy. The maximum number > of values for a key should be controlled by the implementation of the > multi-map. Either eviction parameter should be configurable. -- This message was sent by Atlassian JIRA (v6.3.4#6332)
[jira] [Updated] (IGNITE-1227) Need to implement Ignite-based Spring transaction manager
[ https://issues.apache.org/jira/browse/IGNITE-1227?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ] Amir Akhmedov updated IGNITE-1227: -- Attachment: IGNITE-1227.patch > Need to implement Ignite-based Spring transaction manager > - > > Key: IGNITE-1227 > URL: https://issues.apache.org/jira/browse/IGNITE-1227 > Project: Ignite > Issue Type: Improvement > Components: cache >Affects Versions: 1.1.4 >Reporter: Valentin Kulichenko >Assignee: Amir Akhmedov > Labels: newbie > Attachments: IGNITE-1227.patch > > > This will allow to use Spring transaction interceptor for wrapping cache > operations into Ignite transaction. > Essentially, we need to implement Spring's {{PlatformTransactionManager}} > interface using {{IgniteTransactions}} API. > Corresponding user list thread: > http://apache-ignite-users.70518.x6.nabble.com/Transactions-td885.html -- This message was sent by Atlassian JIRA (v6.3.4#6332)
[jira] [Assigned] (IGNITE-1227) Need to implement Ignite-based Spring transaction manager
[ https://issues.apache.org/jira/browse/IGNITE-1227?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ] Amir Akhmedov reassigned IGNITE-1227: - Assignee: Amir Akhmedov > Need to implement Ignite-based Spring transaction manager > - > > Key: IGNITE-1227 > URL: https://issues.apache.org/jira/browse/IGNITE-1227 > Project: Ignite > Issue Type: Improvement > Components: cache >Affects Versions: 1.1.4 >Reporter: Valentin Kulichenko >Assignee: Amir Akhmedov > Labels: newbie > > This will allow to use Spring transaction interceptor for wrapping cache > operations into Ignite transaction. > Essentially, we need to implement Spring's {{PlatformTransactionManager}} > interface using {{IgniteTransactions}} API. > Corresponding user list thread: > http://apache-ignite-users.70518.x6.nabble.com/Transactions-td885.html -- This message was sent by Atlassian JIRA (v6.3.4#6332)