Search in sources :

Example 21 with PropertyState

use of org.apache.jackrabbit.oak.api.PropertyState in project jackrabbit-oak by apache.

the class ContentMirrorStoreStrategy method count.

long count(Filter filter, NodeState root, NodeState indexMeta, final String indexStorageNodeName, Set<String> values, int max) {
    NodeState index = indexMeta.getChildNode(indexStorageNodeName);
    long count = -1;
    if (values == null) {
        // property is not null
        PropertyState ec = indexMeta.getProperty(ENTRY_COUNT_PROPERTY_NAME);
        if (ec != null) {
            // negative value implies fall-back to counting
            count = ec.getValue(Type.LONG);
        } else {
            // negative value means that approximation isn't available
            count = ApproximateCounter.getCountSync(index);
        }
        if (count < 0) {
            CountingNodeVisitor v = new CountingNodeVisitor(max);
            v.visit(index);
            count = v.getEstimatedCount();
            if (count >= max) {
                // "is not null" queries typically read more data
                count *= 10;
            }
        }
    } else {
        // property = x, or property in (x, y, z)
        int size = values.size();
        if (size == 0) {
            return 0;
        }
        PropertyState ec = indexMeta.getProperty(ENTRY_COUNT_PROPERTY_NAME);
        if (ec != null) {
            count = ec.getValue(Type.LONG);
            if (count >= 0) {
                // assume 10*NodeCounterEditor.DEFAULT_RESOLUTION entries per key, so that this index is used
                // instead of traversal, but not instead of a regular property index
                long keyCount = count / (10 * NodeCounterEditor.DEFAULT_RESOLUTION);
                ec = indexMeta.getProperty(KEY_COUNT_PROPERTY_NAME);
                if (ec != null) {
                    keyCount = ec.getValue(Type.LONG);
                }
                // cast to double to avoid overflow 
                // (entryCount could be Long.MAX_VALUE)
                // the cost is not multiplied by the size, 
                // otherwise the traversing index might be used              
                keyCount = Math.max(1, keyCount);
                count = (long) ((double) count / keyCount) + size;
            }
        } else {
            // for this index, property "entryCount" is not set
            long approxMax = 0;
            long approxCount = ApproximateCounter.getCountSync(index);
            if (approxCount != -1) {
                // check approximate counts for each value
                for (String p : values) {
                    NodeState s = index.getChildNode(p);
                    if (s.exists()) {
                        long a = ApproximateCounter.getCountSync(s);
                        if (a != -1) {
                            approxMax += a;
                        } else if (approxMax > 0) {
                            // in absence of approx count for a key we should be conservative
                            approxMax += 10 * NodeCounterEditor.DEFAULT_RESOLUTION;
                        }
                    }
                }
                if (approxMax > 0) {
                    count = approxMax;
                }
            }
        }
        // and we don't know the count ("entryCount" = -1)
        if (count < 0) {
            count = 0;
            max = Math.max(10, max / size);
            int i = 0;
            for (String p : values) {
                if (count > max && i > 3) {
                    // the total count is extrapolated from the the number
                    // of values counted so far to the total number of values
                    count = count * size / i;
                    break;
                }
                NodeState s = index.getChildNode(p);
                if (s.exists()) {
                    CountingNodeVisitor v = new CountingNodeVisitor(max);
                    v.visit(s);
                    count += v.getEstimatedCount();
                }
                i++;
            }
        }
    }
    String filterRootPath = null;
    if (filter != null && filter.getPathRestriction().equals(Filter.PathRestriction.ALL_CHILDREN)) {
        filterRootPath = filter.getPath();
    }
    if (filterRootPath != null) {
        // scale cost according to path restriction
        long totalNodesCount = NodeCounter.getEstimatedNodeCount(root, "/", true);
        if (totalNodesCount != -1) {
            long filterPathCount = NodeCounter.getEstimatedNodeCount(root, filterRootPath, true);
            if (filterPathCount != -1) {
                // assume nodes in the index are evenly distributed in the repository (old idea)
                long countScaledDown = (long) ((double) count / totalNodesCount * filterPathCount);
                // assume 80% of the indexed nodes are in this subtree
                long mostNodesFromThisSubtree = (long) (filterPathCount * 0.8);
                // count can at most be the assumed subtree size
                count = Math.min(count, mostNodesFromThisSubtree);
                // this in theory should not have any effect, 
                // except if the above estimates are incorrect,
                // so this is just for safety feature
                count = Math.max(count, countScaledDown);
            }
        }
    }
    return count;
}
Also used : NodeState(org.apache.jackrabbit.oak.spi.state.NodeState) PropertyState(org.apache.jackrabbit.oak.api.PropertyState)

Example 22 with PropertyState

use of org.apache.jackrabbit.oak.api.PropertyState in project jackrabbit-oak by apache.

the class UniqueEntryStoreStrategy method insert.

private static void insert(NodeBuilder index, String key, String value) {
    ApproximateCounter.adjustCountSync(index, 1);
    NodeBuilder k = index.child(key);
    ArrayList<String> list = new ArrayList<String>();
    list.add(value);
    if (k.hasProperty("entry")) {
        // duplicate key (to detect duplicate entries)
        // this is just set temporarily,
        // while trying to add a duplicate entry
        PropertyState s = k.getProperty("entry");
        for (int i = 0; i < s.count(); i++) {
            String r = s.getValue(Type.STRING, i);
            if (!list.contains(r)) {
                list.add(r);
            }
        }
    }
    PropertyState s2 = MultiStringPropertyState.stringProperty("entry", list);
    k.setProperty(s2);
}
Also used : ArrayList(java.util.ArrayList) NodeBuilder(org.apache.jackrabbit.oak.spi.state.NodeBuilder) MultiStringPropertyState(org.apache.jackrabbit.oak.plugins.memory.MultiStringPropertyState) PropertyState(org.apache.jackrabbit.oak.api.PropertyState)

Example 23 with PropertyState

use of org.apache.jackrabbit.oak.api.PropertyState in project jackrabbit-oak by apache.

the class UniqueEntryStoreStrategy method remove.

private static void remove(NodeBuilder index, String key, String value) {
    ApproximateCounter.adjustCountSync(index, -1);
    NodeBuilder builder = index.getChildNode(key);
    if (builder.exists()) {
        // there could be (temporarily) multiple entries
        // we need to remove the right one
        PropertyState s = builder.getProperty("entry");
        if (s.count() == 1) {
            builder.remove();
        } else {
            ArrayList<String> list = new ArrayList<String>();
            for (int i = 0; i < s.count(); i++) {
                String r = s.getValue(Type.STRING, i);
                if (!r.equals(value)) {
                    list.add(r);
                }
            }
            PropertyState s2 = MultiStringPropertyState.stringProperty("entry", list);
            builder.setProperty(s2);
        }
    }
}
Also used : ArrayList(java.util.ArrayList) NodeBuilder(org.apache.jackrabbit.oak.spi.state.NodeBuilder) MultiStringPropertyState(org.apache.jackrabbit.oak.plugins.memory.MultiStringPropertyState) PropertyState(org.apache.jackrabbit.oak.api.PropertyState)

Example 24 with PropertyState

use of org.apache.jackrabbit.oak.api.PropertyState in project jackrabbit-oak by apache.

the class UniqueEntryStoreStrategy method query.

@Override
public Iterable<String> query(final Filter filter, final String indexName, final NodeState indexMeta, final Iterable<String> values) {
    final NodeState index = indexMeta.getChildNode(getIndexNodeName());
    return new Iterable<String>() {

        @Override
        public Iterator<String> iterator() {
            if (values == null) {
                return new Iterator<String>() {

                    Iterator<? extends ChildNodeEntry> it = index.getChildNodeEntries().iterator();

                    @Override
                    public boolean hasNext() {
                        return it.hasNext();
                    }

                    @Override
                    public String next() {
                        PropertyState s = it.next().getNodeState().getProperty("entry");
                        return s.getValue(Type.STRING, 0);
                    }

                    @Override
                    public void remove() {
                        it.remove();
                    }
                };
            }
            ArrayList<String> list = new ArrayList<String>();
            for (String p : values) {
                NodeState key = index.getChildNode(p);
                if (key.exists()) {
                    // we have an entry for this value, so use it
                    PropertyState s = key.getProperty("entry");
                    String v = s.getValue(Type.STRING, 0);
                    list.add(v);
                }
            }
            return list.iterator();
        }
    };
}
Also used : NodeState(org.apache.jackrabbit.oak.spi.state.NodeState) ChildNodeEntry(org.apache.jackrabbit.oak.spi.state.ChildNodeEntry) Iterator(java.util.Iterator) ArrayList(java.util.ArrayList) MultiStringPropertyState(org.apache.jackrabbit.oak.plugins.memory.MultiStringPropertyState) PropertyState(org.apache.jackrabbit.oak.api.PropertyState)

Example 25 with PropertyState

use of org.apache.jackrabbit.oak.api.PropertyState in project jackrabbit-oak by apache.

the class AbstractTypeDefinition method getValues.

private String[] getValues(String oakName, Type<String> type) {
    String[] values = null;
    PropertyState property = definition.getProperty(checkNotNull(oakName));
    if (property != null) {
        int n = property.count();
        if (n > 0) {
            values = new String[n];
            for (int i = 0; i < n; i++) {
                values[i] = property.getValue(type, i);
            }
        } else {
            values = NO_STRINGS;
        }
    }
    return values;
}
Also used : PropertyState(org.apache.jackrabbit.oak.api.PropertyState)

Aggregations

PropertyState (org.apache.jackrabbit.oak.api.PropertyState)404 Test (org.junit.Test)189 Tree (org.apache.jackrabbit.oak.api.Tree)138 NodeBuilder (org.apache.jackrabbit.oak.spi.state.NodeBuilder)49 NodeState (org.apache.jackrabbit.oak.spi.state.NodeState)45 Nonnull (javax.annotation.Nonnull)31 AbstractSecurityTest (org.apache.jackrabbit.oak.AbstractSecurityTest)29 RemoteTree (org.apache.jackrabbit.oak.remote.RemoteTree)28 RemoteValue (org.apache.jackrabbit.oak.remote.RemoteValue)28 Blob (org.apache.jackrabbit.oak.api.Blob)21 ArrayList (java.util.ArrayList)20 LongPropertyState (org.apache.jackrabbit.oak.plugins.memory.LongPropertyState)17 ChildNodeEntry (org.apache.jackrabbit.oak.spi.state.ChildNodeEntry)16 EmptyNodeState (org.apache.jackrabbit.oak.plugins.memory.EmptyNodeState)14 CommitFailedException (org.apache.jackrabbit.oak.api.CommitFailedException)13 CheckForNull (javax.annotation.CheckForNull)12 RepositoryException (javax.jcr.RepositoryException)10 NodeStore (org.apache.jackrabbit.oak.spi.state.NodeStore)10 Map (java.util.Map)9 Value (javax.jcr.Value)9