Search in sources :

Example 11 with IndexStoreEntry

use of org.apache.geode.cache.query.internal.index.IndexStore.IndexStoreEntry in project geode by apache.

the class CompactRangeIndex method getSizeEstimate.

public int getSizeEstimate(Object key, int operator, int matchLevel) throws TypeMismatchException {
    // Get approx size;
    int size = 0;
    if (key == null) {
        key = IndexManager.NULL;
    }
    long start = updateIndexUseStats(false);
    try {
        switch(operator) {
            case OQLLexerTokenTypes.TOK_EQ:
                {
                    key = TypeUtils.indexKeyFor(key);
                    key = getPdxStringForIndexedPdxKeys(key);
                    size = indexStore.size(key);
                    break;
                }
            case OQLLexerTokenTypes.TOK_NE_ALT:
            case OQLLexerTokenTypes.TOK_NE:
                size = this.region.size();
                key = TypeUtils.indexKeyFor(key);
                key = getPdxStringForIndexedPdxKeys(key);
                size -= indexStore.size(key);
                break;
            case OQLLexerTokenTypes.TOK_LE:
            case OQLLexerTokenTypes.TOK_LT:
                if (matchLevel <= 0 && (key instanceof Number)) {
                    int totalSize = indexStore.size();
                    if (CompactRangeIndex.testHook != null) {
                        CompactRangeIndex.testHook.hook(1);
                    }
                    if (totalSize > 1) {
                        Number keyAsNum = (Number) key;
                        int x = 0;
                        IndexStoreEntry firstEntry = null;
                        CloseableIterator<IndexStoreEntry> iter1 = null;
                        CloseableIterator<IndexStoreEntry> iter2 = null;
                        try {
                            iter1 = indexStore.iterator(null);
                            if (iter1.hasNext()) {
                                firstEntry = iter1.next();
                                IndexStoreEntry lastEntry = null;
                                iter2 = indexStore.descendingIterator(null);
                                if (iter2.hasNext()) {
                                    lastEntry = iter2.next();
                                }
                                if (firstEntry != null && lastEntry != null) {
                                    Number first = (Number) firstEntry.getDeserializedKey();
                                    Number last = (Number) lastEntry.getDeserializedKey();
                                    if (first.doubleValue() != last.doubleValue()) {
                                        // Shobhit: Now without ReadLoack on index we can end up with 0
                                        // in denominator if the numbers are floating-point and
                                        // truncated with conversion to long, and the first and last
                                        // truncate to the same long, so safest calculation is to
                                        // convert to doubles.
                                        x = (int) (((keyAsNum.doubleValue() - first.doubleValue()) * totalSize) / (last.doubleValue() - first.doubleValue()));
                                    }
                                }
                                if (x < 0) {
                                    x = 0;
                                }
                                size = x;
                            }
                        } finally {
                            if (iter1 != null) {
                                iter1.close();
                            }
                            if (iter2 != null) {
                                iter1.close();
                            }
                        }
                    } else {
                        // not attempting to differentiate between LT & LE
                        size = indexStore.size(key) > 0 ? 1 : 0;
                    }
                } else {
                    size = Integer.MAX_VALUE;
                }
                break;
            case OQLLexerTokenTypes.TOK_GE:
            case OQLLexerTokenTypes.TOK_GT:
                if (matchLevel <= 0 && (key instanceof Number)) {
                    int totalSize = indexStore.size();
                    if (CompactRangeIndex.testHook != null) {
                        CompactRangeIndex.testHook.hook(2);
                    }
                    if (totalSize > 1) {
                        Number keyAsNum = (Number) key;
                        int x = 0;
                        IndexStoreEntry firstEntry = null;
                        CloseableIterator<IndexStoreEntry> iter1 = null;
                        CloseableIterator<IndexStoreEntry> iter2 = null;
                        try {
                            iter1 = indexStore.iterator(null);
                            if (iter1.hasNext()) {
                                firstEntry = iter1.next();
                            }
                            IndexStoreEntry lastEntry = null;
                            iter2 = indexStore.descendingIterator(null);
                            if (iter2.hasNext()) {
                                lastEntry = iter2.next();
                            }
                            if (firstEntry != null && lastEntry != null) {
                                Number first = (Number) firstEntry.getDeserializedKey();
                                Number last = (Number) lastEntry.getDeserializedKey();
                                if (first.doubleValue() != last.doubleValue()) {
                                    // Shobhit: Now without ReadLoack on index we can end up with 0
                                    // in denominator if the numbers are floating-point and
                                    // truncated with conversion to long, and the first and last
                                    // truncate to the same long, so safest calculation is to
                                    // convert to doubles.
                                    x = (int) (((last.doubleValue() - keyAsNum.doubleValue()) * totalSize) / (last.doubleValue() - first.doubleValue()));
                                }
                            }
                            if (x < 0) {
                                x = 0;
                            }
                            size = x;
                        } finally {
                            if (iter1 != null) {
                                iter1.close();
                            }
                        }
                    } else {
                        // not attempting to differentiate between GT & GE
                        size = indexStore.size(key) > 0 ? 1 : 0;
                    }
                } else {
                    size = Integer.MAX_VALUE;
                }
                break;
        }
    } catch (EntryDestroyedException ignore) {
        return Integer.MAX_VALUE;
    } finally {
        updateIndexUseEndStats(start, false);
    }
    return size;
}
Also used : EntryDestroyedException(org.apache.geode.cache.EntryDestroyedException) MemoryIndexStoreEntry(org.apache.geode.cache.query.internal.index.MemoryIndexStore.MemoryIndexStoreEntry) IndexStoreEntry(org.apache.geode.cache.query.internal.index.IndexStore.IndexStoreEntry)

Example 12 with IndexStoreEntry

use of org.apache.geode.cache.query.internal.index.IndexStore.IndexStoreEntry in project geode by apache.

the class HashIndex method queryEquijoinCondition.

/**
   * computes the resultset of an equijoin query
   */
public List queryEquijoinCondition(IndexProtocol indx, ExecutionContext context) throws TypeMismatchException, FunctionDomainException, NameResolutionException, QueryInvocationTargetException {
    // get a read lock when doing a lookup
    long start = updateIndexUseStats();
    ((AbstractIndex) indx).updateIndexUseStats();
    List data = new ArrayList();
    Iterator inner = null;
    try {
        // We will iterate over each of the valueToEntries Map to obtain the keys
        Iterator outer = entriesSet.iterator();
        if (indx instanceof CompactRangeIndex) {
            inner = ((CompactRangeIndex) indx).getIndexStorage().iterator(null);
        } else {
            inner = ((RangeIndex) indx).getValueToEntriesMap().entrySet().iterator();
        }
        Map.Entry outerEntry = null;
        Object innerEntry = null;
        Object outerKey = null;
        Object innerKey = null;
        // boolean incrementOuter = true;
        boolean incrementInner = true;
        outer: while (outer.hasNext()) {
            // if (incrementOuter) {
            outerEntry = (Map.Entry) outer.next();
            // }
            outerKey = outerEntry.getKey();
            // TODO: eliminate use of labels
            inner: while (!incrementInner || inner.hasNext()) {
                if (incrementInner) {
                    innerEntry = inner.next();
                    if (innerEntry instanceof IndexStoreEntry) {
                        innerKey = ((IndexStoreEntry) innerEntry).getDeserializedKey();
                    } else {
                        innerKey = ((Map.Entry) innerEntry).getKey();
                    }
                }
                int compare = ((Comparable) outerKey).compareTo(innerKey);
                if (compare == 0) {
                    Object innerValue = null;
                    if (innerEntry instanceof IndexStoreEntry) {
                        innerValue = ((CompactRangeIndex) indx).getIndexStorage().get(outerKey);
                    } else {
                        innerValue = ((Map.Entry) innerEntry).getValue();
                    }
                    populateListForEquiJoin(data, outerEntry.getValue(), innerValue, context, innerKey);
                    incrementInner = true;
                    continue outer;
                } else if (compare < 0) {
                    // Asif :The outer key is smaller than the inner key. That means
                    // that we need
                    // to increment the outer loop without moving inner loop.
                    // incrementOuter = true;
                    incrementInner = false;
                    continue outer;
                } else {
                    // The outer key is greater than inner key , so increment the
                    // inner loop without changing outer
                    incrementInner = true;
                }
            }
            break;
        }
        return data;
    } finally {
        ((AbstractIndex) indx).updateIndexUseEndStats(start);
        updateIndexUseEndStats(start);
        if (inner != null && indx instanceof CompactRangeIndex) {
            ((CloseableIterator<IndexStoreEntry>) inner).close();
        }
    }
}
Also used : Entry(java.util.Map.Entry) CloseableIterator(org.apache.geode.internal.cache.persistence.query.CloseableIterator) ArrayList(java.util.ArrayList) IndexStoreEntry(org.apache.geode.cache.query.internal.index.IndexStore.IndexStoreEntry) Entry(java.util.Map.Entry) CqEntry(org.apache.geode.cache.query.internal.CqEntry) RegionEntry(org.apache.geode.internal.cache.RegionEntry) IndexStoreEntry(org.apache.geode.cache.query.internal.index.IndexStore.IndexStoreEntry) RuntimeIterator(org.apache.geode.cache.query.internal.RuntimeIterator) CloseableIterator(org.apache.geode.internal.cache.persistence.query.CloseableIterator) Iterator(java.util.Iterator) List(java.util.List) ArrayList(java.util.ArrayList) StoredObject(org.apache.geode.internal.offheap.StoredObject) Object2ObjectOpenHashMap(it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap) Map(java.util.Map) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) ConcurrentMap(java.util.concurrent.ConcurrentMap)

Aggregations

IndexStoreEntry (org.apache.geode.cache.query.internal.index.IndexStore.IndexStoreEntry)12 ArrayList (java.util.ArrayList)7 List (java.util.List)6 MemoryIndexStoreEntry (org.apache.geode.cache.query.internal.index.MemoryIndexStore.MemoryIndexStoreEntry)6 Iterator (java.util.Iterator)5 RuntimeIterator (org.apache.geode.cache.query.internal.RuntimeIterator)5 CloseableIterator (org.apache.geode.internal.cache.persistence.query.CloseableIterator)5 Map (java.util.Map)4 HashSet (java.util.HashSet)3 CqEntry (org.apache.geode.cache.query.internal.CqEntry)3 RegionEntry (org.apache.geode.internal.cache.RegionEntry)3 Object2ObjectOpenHashMap (it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap)2 Collection (java.util.Collection)2 Entry (java.util.Map.Entry)2 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)2 EntryDestroyedException (org.apache.geode.cache.EntryDestroyedException)2 CompiledSortCriterion (org.apache.geode.cache.query.internal.CompiledSortCriterion)2 IndexInfo (org.apache.geode.cache.query.internal.IndexInfo)2 CompactRangeIndex (org.apache.geode.cache.query.internal.index.CompactRangeIndex)2 PrimaryKeyIndex (org.apache.geode.cache.query.internal.index.PrimaryKeyIndex)2