Search in sources :

Example 16 with InternalIndex

use of com.hazelcast.query.impl.InternalIndex in project hazelcast by hazelcast.

the class IndexRangeFilterIteratorTest method testIterator_simple_to.

@Test
public void testIterator_simple_to() {
    HazelcastInstance instance = factory.newHazelcastInstance(getConfig());
    IMap<Integer, Value> map = instance.getMap(MAP_NAME);
    map.addIndex(new IndexConfig().setName(INDEX_NAME).setType(SORTED).addAttribute("value1"));
    InternalIndex index = getIndex(instance);
    ExpressionEvalContext evalContext = createExpressionEvalContext();
    // Check missing value.
    map.put(0, new Value(10));
    checkIterator(SORTED, descendingDirection, new IndexRangeFilter(null, false, intValue(2), false).getEntries(index, descendingDirection, evalContext));
    checkIterator(SORTED, descendingDirection, new IndexRangeFilter(null, false, intValue(2), true).getEntries(index, descendingDirection, evalContext));
    // Check single value.
    map.put(1, new Value(2));
    checkIterator(SORTED, descendingDirection, new IndexRangeFilter(null, false, intValue(2), false).getEntries(index, descendingDirection, evalContext));
    checkIterator(SORTED, descendingDirection, new IndexRangeFilter(null, false, intValue(2), true).getEntries(index, descendingDirection, evalContext), 1);
    // Check multiple values.
    map.put(2, new Value(2));
    map.put(3, new Value(1));
    map.put(4, new Value(1));
    checkIterator(SORTED, descendingDirection, new IndexRangeFilter(null, false, intValue(2), false).getEntries(index, descendingDirection, evalContext), 3, 4);
    checkIterator(SORTED, descendingDirection, new IndexRangeFilter(null, false, intValue(2), true).getEntries(index, descendingDirection, evalContext), 1, 2, 3, 4);
    // Check null value.
    checkIterator(SORTED, descendingDirection, new IndexRangeFilter(null, false, intValue(null, false), false).getEntries(index, descendingDirection, evalContext));
    checkIterator(SORTED, descendingDirection, new IndexRangeFilter(null, false, intValue(null, false), true).getEntries(index, descendingDirection, evalContext));
}
Also used : ExpressionEvalContext(com.hazelcast.sql.impl.expression.ExpressionEvalContext) IndexRangeFilter(com.hazelcast.sql.impl.exec.scan.index.IndexRangeFilter) InternalIndex(com.hazelcast.query.impl.InternalIndex) HazelcastInstance(com.hazelcast.core.HazelcastInstance) IndexConfig(com.hazelcast.config.IndexConfig) ParallelJVMTest(com.hazelcast.test.annotation.ParallelJVMTest) QuickTest(com.hazelcast.test.annotation.QuickTest) Test(org.junit.Test)

Example 17 with InternalIndex

use of com.hazelcast.query.impl.InternalIndex in project hazelcast by hazelcast.

the class MapReplicationStateHolder method applyState.

@SuppressWarnings({ "checkstyle:npathcomplexity", "checkstyle:methodlength", "checkstyle:cyclomaticcomplexity", "checkstyle:nestedifdepth" })
void applyState() {
    ThreadUtil.assertRunningOnPartitionThread();
    applyIndexesState();
    if (!isNullOrEmpty(data)) {
        for (Map.Entry<String, List> dataEntry : data.entrySet()) {
            String mapName = dataEntry.getKey();
            List keyRecordExpiry = dataEntry.getValue();
            RecordStore recordStore = operation.getRecordStore(mapName);
            recordStore.beforeOperation();
            try {
                initializeRecordStore(mapName, recordStore);
                recordStore.setPreMigrationLoadedStatus(loaded.get(mapName));
                MapContainer mapContainer = recordStore.getMapContainer();
                PartitionContainer partitionContainer = recordStore.getMapContainer().getMapServiceContext().getPartitionContainer(operation.getPartitionId());
                for (Map.Entry<String, IndexConfig> indexDefinition : mapContainer.getIndexDefinitions().entrySet()) {
                    Indexes indexes = mapContainer.getIndexes(partitionContainer.getPartitionId());
                    indexes.addOrGetIndex(indexDefinition.getValue());
                }
                final Indexes indexes = mapContainer.getIndexes(partitionContainer.getPartitionId());
                final boolean populateIndexes = indexesMustBePopulated(indexes, operation);
                InternalIndex[] indexesSnapshot = null;
                if (populateIndexes) {
                    // defensively clear possible stale leftovers in non-global indexes from
                    // the previous failed promotion attempt
                    indexesSnapshot = indexes.getIndexes();
                    Indexes.beginPartitionUpdate(indexesSnapshot);
                    indexes.clearAll();
                }
                long nowInMillis = Clock.currentTimeMillis();
                forEachReplicatedRecord(keyRecordExpiry, mapContainer, recordStore, populateIndexes, nowInMillis);
                if (populateIndexes) {
                    Indexes.markPartitionAsIndexed(partitionContainer.getPartitionId(), indexesSnapshot);
                }
            } finally {
                recordStore.afterOperation();
            }
        }
    }
    for (Map.Entry<String, LocalRecordStoreStats> statsEntry : recordStoreStatsPerMapName.entrySet()) {
        String mapName = statsEntry.getKey();
        LocalRecordStoreStats stats = statsEntry.getValue();
        RecordStore recordStore = operation.getRecordStore(mapName);
        recordStore.setStats(stats);
    }
}
Also used : PartitionContainer(com.hazelcast.map.impl.PartitionContainer) Indexes(com.hazelcast.query.impl.Indexes) MapContainer(com.hazelcast.map.impl.MapContainer) LocalRecordStoreStats(com.hazelcast.internal.monitor.LocalRecordStoreStats) InternalIndex(com.hazelcast.query.impl.InternalIndex) IndexConfig(com.hazelcast.config.IndexConfig) RecordStore(com.hazelcast.map.impl.recordstore.RecordStore) ArrayList(java.util.ArrayList) List(java.util.List) HashMap(java.util.HashMap) MapUtil.createHashMap(com.hazelcast.internal.util.MapUtil.createHashMap) Map(java.util.Map) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap)

Example 18 with InternalIndex

use of com.hazelcast.query.impl.InternalIndex in project hazelcast by hazelcast.

the class CompositeIndexVisitor method visit.

@SuppressWarnings({ "checkstyle:cyclomaticcomplexity", "checkstyle:methodlength", "checkstyle:npathcomplexity" })
@Override
public Predicate visit(AndPredicate andPredicate, Indexes indexes) {
    int originalSize = andPredicate.predicates.length;
    if (originalSize < 2) {
        // can't optimize further
        return andPredicate;
    }
    InternalIndex[] compositeIndexes = indexes.getCompositeIndexes();
    if (compositeIndexes.length == 0) {
        // no composite indexes to optimize against
        return andPredicate;
    }
    // 1. Split predicates into 3 groups: (a) prefixes, that are equal
    // predicates, like a == 1; (b) comparisons, that are order comparisons
    // predicates, like a > 1; (c) output, this group contains unoptimizable
    // predicates, like a != 1; later, the group also receives optimized
    // predicates ready for output.
    Map<String, EqualPredicate> prefixes = null;
    Map<String, RangePredicate> comparisons = null;
    Output output = null;
    for (Predicate predicate : andPredicate.predicates) {
        if (predicate instanceof EqualPredicate) {
            EqualPredicate equalPredicate = (EqualPredicate) predicate;
            prefixes = obtainHashMap(prefixes, originalSize);
            EqualPredicate replaced = prefixes.put(equalPredicate.attributeName, equalPredicate);
            if (replaced != null) {
                // If we have multiple predicates for the same attribute,
                // that means RangeVisitor is failed to optimize them. In
                // turn, that means the range visitor was unable to find
                // a TypeConverter for the attribute and that means the map
                // and/or index were empty at the moment.
                // 
                // So we record duplicates in the output and produce an
                // underoptimized result in the end.
                output = obtainOutput(output, originalSize);
                output.add(replaced);
            }
            continue;
        }
        if (predicate instanceof RangePredicate) {
            RangePredicate rangePredicate = (RangePredicate) predicate;
            comparisons = obtainHashMap(comparisons, originalSize);
            RangePredicate replaced = comparisons.put(rangePredicate.getAttribute(), rangePredicate);
            if (replaced != null) {
                output = obtainOutput(output, originalSize);
                output.add(replaced);
            }
            continue;
        }
        output = obtainOutput(output, originalSize);
        output.add(predicate);
    }
    if (prefixes == null || comparisons == null && prefixes.size() == 1) {
        // no comparisons that can be matched to form a prefix of length 2.
        return andPredicate;
    }
    assert !prefixes.isEmpty();
    while (!prefixes.isEmpty()) {
        int bestPrefix = 0;
        InternalIndex bestIndex = null;
        RangePredicate bestComparison = null;
        for (InternalIndex index : compositeIndexes) {
            String[] components = index.getComponents();
            if (components.length < bestPrefix || !index.isOrdered() && prefixes.size() < components.length) {
                // fewer components to match than the index has.
                continue;
            }
            int prefix = 0;
            while (prefix < components.length && prefixes.containsKey(components[prefix])) {
                ++prefix;
            }
            if (prefix == 0) {
                // no prefix found at all
                continue;
            }
            if (index.isOrdered()) {
                RangePredicate comparison = prefix < components.length && comparisons != null ? comparisons.get(components[prefix]) : null;
                if (comparison != null) {
                    ++prefix;
                }
                if (prefix > bestPrefix) {
                    bestPrefix = prefix;
                    bestIndex = index;
                    bestComparison = comparison;
                } else if (prefix == bestPrefix) {
                    // the matched prefix is at least of length 1
                    assert bestIndex != null;
                    if (bestIndex.isOrdered() && bestIndex.getComponents().length > components.length) {
                        // prefer shorter indexes over longer ones
                        bestIndex = index;
                        bestComparison = comparison;
                    }
                }
            } else if (prefix == components.length && prefix >= bestPrefix) {
                // The unordered index components are fully matched and the
                // prefix is longer or equal to the best found prefix. The
                // later is needed to give a preference for unordered matches
                // over ordered ones.
                bestPrefix = prefix;
                bestIndex = index;
                bestComparison = null;
            }
        }
        if (bestIndex == null || bestPrefix == 1) {
            // should be handled by AttributeIndexRegistry.
            break;
        }
        // exclude the comparison from the prefix, just to make the math simpler later
        int equalPrefixLength = bestComparison == null ? bestPrefix : bestPrefix - 1;
        if (output == null) {
            // if we have no output yet, try to perform a cheaper fast exit
            Predicate generated = tryGenerateFast(prefixes, comparisons, equalPrefixLength, bestComparison, bestIndex);
            if (generated != null) {
                return generated;
            }
        }
        output = obtainOutput(output, originalSize);
        addToOutput(prefixes, comparisons, output, equalPrefixLength, bestComparison, bestIndex);
    }
    return output == null ? andPredicate : output.generate(prefixes, comparisons, andPredicate);
}
Also used : InternalIndex(com.hazelcast.query.impl.InternalIndex) Predicate(com.hazelcast.query.Predicate)

Example 19 with InternalIndex

use of com.hazelcast.query.impl.InternalIndex in project hazelcast by hazelcast.

the class AddIndexOperation method runInternal.

@Override
public void runInternal() {
    int partitionId = getPartitionId();
    Indexes indexes = mapContainer.getIndexes(partitionId);
    InternalIndex index = indexes.addOrGetIndex(config);
    if (index.hasPartitionIndexed(partitionId)) {
        return;
    }
    SerializationService serializationService = getNodeEngine().getSerializationService();
    index.beginPartitionUpdate();
    CacheDeserializedValues cacheDeserializedValues = mapContainer.getMapConfig().getCacheDeserializedValues();
    CachedQueryEntry<?, ?> cachedEntry = cacheDeserializedValues == NEVER ? new CachedQueryEntry<>(serializationService, mapContainer.getExtractors()) : null;
    recordStore.forEach((dataKey, record) -> {
        Object value = Records.getValueOrCachedValue(record, serializationService);
        QueryableEntry<?, ?> queryEntry = mapContainer.newQueryEntry(dataKey, value);
        queryEntry.setRecord(record);
        CachedQueryEntry<?, ?> newEntry = cachedEntry == null ? (CachedQueryEntry<?, ?>) queryEntry : cachedEntry.init(dataKey, value);
        index.putEntry(newEntry, null, queryEntry, Index.OperationSource.USER);
    }, false);
    index.markPartitionAsIndexed(partitionId);
}
Also used : InternalIndex(com.hazelcast.query.impl.InternalIndex) CacheDeserializedValues(com.hazelcast.config.CacheDeserializedValues) SerializationService(com.hazelcast.internal.serialization.SerializationService) Indexes(com.hazelcast.query.impl.Indexes)

Example 20 with InternalIndex

use of com.hazelcast.query.impl.InternalIndex in project hazelcast by hazelcast.

the class CompositeIndexVisitorTest method before.

@Before
public void before() {
    indexes = mock(Indexes.class);
    o123 = mock(InternalIndex.class);
    when(o123.isOrdered()).thenReturn(true);
    when(o123.getComponents()).thenReturn(components("a1", "a2", "a3"));
    u321 = mock(InternalIndex.class);
    when(u321.isOrdered()).thenReturn(false);
    when(u321.getComponents()).thenReturn(components("a3", "a2", "a1"));
    o567 = mock(InternalIndex.class);
    when(o567.isOrdered()).thenReturn(true);
    when(o567.getComponents()).thenReturn(components("a5", "a6", "a7"));
    // needed to test the preference of shorter indexes over longer ones
    InternalIndex o1234 = mock(InternalIndex.class);
    when(o1234.isOrdered()).thenReturn(true);
    when(o1234.getComponents()).thenReturn(components("a1", "a2", "a3", "a4"));
    when(indexes.getCompositeIndexes()).thenReturn(new InternalIndex[] { o1234, o123, u321, o567 });
    visitor = new CompositeIndexVisitor();
}
Also used : InternalIndex(com.hazelcast.query.impl.InternalIndex) Indexes(com.hazelcast.query.impl.Indexes) Before(org.junit.Before)

Aggregations

InternalIndex (com.hazelcast.query.impl.InternalIndex)22 IndexConfig (com.hazelcast.config.IndexConfig)11 HazelcastInstance (com.hazelcast.core.HazelcastInstance)9 Indexes (com.hazelcast.query.impl.Indexes)9 ExpressionEvalContext (com.hazelcast.sql.impl.expression.ExpressionEvalContext)7 ParallelJVMTest (com.hazelcast.test.annotation.ParallelJVMTest)5 QuickTest (com.hazelcast.test.annotation.QuickTest)5 Test (org.junit.Test)5 IndexRangeFilter (com.hazelcast.sql.impl.exec.scan.index.IndexRangeFilter)4 ArrayList (java.util.ArrayList)3 Before (org.junit.Before)3 CacheDeserializedValues (com.hazelcast.config.CacheDeserializedValues)2 MapContainer (com.hazelcast.map.impl.MapContainer)2 Record (com.hazelcast.map.impl.record.Record)2 Predicate (com.hazelcast.query.Predicate)2 QueryableEntry (com.hazelcast.query.impl.QueryableEntry)2 IndexEqualsFilter (com.hazelcast.sql.impl.exec.scan.index.IndexEqualsFilter)2 HazelcastInstanceProxy (com.hazelcast.instance.impl.HazelcastInstanceProxy)1 LocalRecordStoreStats (com.hazelcast.internal.monitor.LocalRecordStoreStats)1 OnDemandIndexStats (com.hazelcast.internal.monitor.impl.OnDemandIndexStats)1