Search in sources :

Example 6 with Key

use of org.apache.jackrabbit.oak.plugins.document.UpdateOp.Key in project jackrabbit-oak by apache.

the class UpdateUtils method checkConditions.

public static boolean checkConditions(@Nonnull Document doc, @Nonnull Map<Key, Condition> conditions) {
    for (Map.Entry<Key, Condition> entry : conditions.entrySet()) {
        Condition c = entry.getValue();
        Key k = entry.getKey();
        Object value = doc.get(k.getName());
        Revision r = k.getRevision();
        if (c.type == Condition.Type.EXISTS) {
            if (r == null) {
                throw new IllegalStateException("EXISTS must not contain null revision");
            }
            if (value == null) {
                if (Boolean.TRUE.equals(c.value)) {
                    return false;
                }
            } else {
                if (value instanceof Map) {
                    Map<?, ?> map = (Map<?, ?>) value;
                    if (Boolean.TRUE.equals(c.value)) {
                        if (!map.containsKey(r)) {
                            return false;
                        }
                    } else {
                        if (map.containsKey(r)) {
                            return false;
                        }
                    }
                } else {
                    return false;
                }
            }
        } else if (c.type == Condition.Type.EQUALS || c.type == Condition.Type.NOTEQUALS) {
            if (r != null) {
                if (value instanceof Map) {
                    value = ((Map) value).get(r);
                } else {
                    value = null;
                }
            }
            boolean equal = Objects.equal(value, c.value);
            if (c.type == Condition.Type.EQUALS && !equal) {
                return false;
            } else if (c.type == Condition.Type.NOTEQUALS && equal) {
                return false;
            }
        } else {
            throw new IllegalArgumentException("Unknown condition: " + c.type);
        }
    }
    return true;
}
Also used : Condition(org.apache.jackrabbit.oak.plugins.document.UpdateOp.Condition) TreeMap(java.util.TreeMap) Map(java.util.Map) Key(org.apache.jackrabbit.oak.plugins.document.UpdateOp.Key)

Example 7 with Key

use of org.apache.jackrabbit.oak.plugins.document.UpdateOp.Key in project jackrabbit-oak by apache.

the class DocumentSplitTest method cascadingWithSplitRatio.

// OAK-1692
@Test
public void cascadingWithSplitRatio() {
    String id = Utils.getIdFromPath("/test");
    mk.commit("/", "+\"test\":{}", null, null);
    DocumentStore store = mk.getDocumentStore();
    int clusterId = mk.getNodeStore().getClusterId();
    UpdateOp op = new UpdateOp(id, false);
    // create some baggage from another cluster node
    for (int i = 0; i < 4000; i++) {
        Revision r = Revision.newRevision(2);
        op.setMapEntry("prop", r, "some long test value with many characters");
        NodeDocument.setRevision(op, r, "c");
    }
    store.findAndUpdate(NODES, op);
    NodeDocument doc = store.find(NODES, id);
    assertNotNull(doc);
    assertTrue(doc.getMemory() > DOC_SIZE_THRESHOLD);
    // some fake previous doc references to trigger UpdateOp
    // for an intermediate document
    TreeSet<Revision> prev = Sets.newTreeSet(StableRevisionComparator.INSTANCE);
    for (int i = 0; i < PREV_SPLIT_FACTOR; i++) {
        Revision low = Revision.newRevision(clusterId);
        Revision high = Revision.newRevision(clusterId);
        prev.add(high);
        NodeDocument.setPrevious(op, new Range(high, low, 0));
    }
    store.findAndUpdate(NODES, op);
    doc = store.find(NODES, id);
    assertNotNull(doc);
    List<UpdateOp> splitOps = Lists.newArrayList(doc.split(mk.getNodeStore(), mk.getNodeStore().getHeadRevision(), NO_BINARY));
    assertEquals(2, splitOps.size());
    // first update op is for the new intermediate doc
    op = splitOps.get(0);
    String newPrevId = Utils.getPreviousIdFor("/test", prev.last(), 1);
    assertEquals(newPrevId, op.getId());
    // second update op is for the main document
    op = splitOps.get(1);
    assertEquals(id, op.getId());
    for (Map.Entry<Key, Operation> entry : op.getChanges().entrySet()) {
        Revision r = entry.getKey().getRevision();
        assertNotNull(r);
        assertEquals(clusterId, r.getClusterId());
        if (entry.getKey().getName().equals("_prev")) {
            if (entry.getValue().type == REMOVE_MAP_ENTRY) {
                assertTrue(prev.contains(r));
            } else if (entry.getValue().type == SET_MAP_ENTRY) {
                assertEquals(newPrevId, Utils.getPreviousIdFor("/test", r, 1));
            } else {
                fail("unexpected update operation " + entry);
            }
        } else {
            fail("unexpected update operation " + entry);
        }
    }
}
Also used : Operation(org.apache.jackrabbit.oak.plugins.document.UpdateOp.Operation) MemoryDocumentStore(org.apache.jackrabbit.oak.plugins.document.memory.MemoryDocumentStore) Map(java.util.Map) Key(org.apache.jackrabbit.oak.plugins.document.UpdateOp.Key) Test(org.junit.Test)

Example 8 with Key

use of org.apache.jackrabbit.oak.plugins.document.UpdateOp.Key in project jackrabbit-oak by apache.

the class UpdateUtils method applyChanges.

/**
     * Apply the changes to the in-memory document.
     *
     * @param doc
     *            the target document.
     * @param update
     *            the changes to apply.
     */
public static void applyChanges(@Nonnull Document doc, @Nonnull UpdateOp update) {
    doc.put(Document.ID, update.getId());
    for (Entry<Key, Operation> e : checkNotNull(update).getChanges().entrySet()) {
        Key k = e.getKey();
        Operation op = e.getValue();
        switch(op.type) {
            case SET:
                {
                    doc.put(k.toString(), op.value);
                    break;
                }
            case REMOVE:
                {
                    doc.remove(k.toString());
                    break;
                }
            case MAX:
                {
                    Comparable newValue = (Comparable) op.value;
                    Object old = doc.get(k.toString());
                    //noinspection unchecked
                    if (old == null || newValue.compareTo(old) > 0) {
                        doc.put(k.toString(), op.value);
                    }
                    break;
                }
            case INCREMENT:
                {
                    Object old = doc.get(k.toString());
                    Long x = (Long) op.value;
                    if (old == null) {
                        old = 0L;
                    }
                    doc.put(k.toString(), ((Long) old) + x);
                    break;
                }
            case SET_MAP_ENTRY:
                {
                    Object old = doc.get(k.getName());
                    @SuppressWarnings("unchecked") Map<Revision, Object> m = (Map<Revision, Object>) old;
                    if (m == null) {
                        m = new TreeMap<Revision, Object>(StableRevisionComparator.REVERSE);
                        doc.put(k.getName(), m);
                    }
                    if (k.getRevision() == null) {
                        throw new IllegalArgumentException("Cannot set map entry " + k.getName() + " with null revision");
                    }
                    m.put(k.getRevision(), op.value);
                    break;
                }
            case REMOVE_MAP_ENTRY:
                {
                    Object old = doc.get(k.getName());
                    @SuppressWarnings("unchecked") Map<Revision, Object> m = (Map<Revision, Object>) old;
                    if (m != null) {
                        m.remove(k.getRevision());
                    }
                    break;
                }
        }
    }
}
Also used : Operation(org.apache.jackrabbit.oak.plugins.document.UpdateOp.Operation) TreeMap(java.util.TreeMap) TreeMap(java.util.TreeMap) Map(java.util.Map) Key(org.apache.jackrabbit.oak.plugins.document.UpdateOp.Key)

Example 9 with Key

use of org.apache.jackrabbit.oak.plugins.document.UpdateOp.Key in project jackrabbit-oak by apache.

the class RDBDocumentSerializer method asString.

/**
     * Serializes the changes in the {@link UpdateOp} into a JSON array; each
     * entry is another JSON array holding operation, key, revision, and value.
     */
public String asString(UpdateOp update) {
    StringBuilder sb = new StringBuilder("[");
    boolean needComma = false;
    for (Map.Entry<Key, Operation> change : update.getChanges().entrySet()) {
        Operation op = change.getValue();
        Key key = change.getKey();
        // exclude properties that are serialized into special columns
        if (columnProperties.contains(key.getName()) && null == key.getRevision())
            continue;
        if (needComma) {
            sb.append(",");
        }
        sb.append("[");
        if (op.type == UpdateOp.Operation.Type.INCREMENT) {
            sb.append("\"+\",");
        } else if (op.type == UpdateOp.Operation.Type.SET || op.type == UpdateOp.Operation.Type.SET_MAP_ENTRY) {
            sb.append("\"=\",");
        } else if (op.type == UpdateOp.Operation.Type.MAX) {
            sb.append("\"M\",");
        } else if (op.type == UpdateOp.Operation.Type.REMOVE || op.type == UpdateOp.Operation.Type.REMOVE_MAP_ENTRY) {
            sb.append("\"*\",");
        } else {
            throw new DocumentStoreException("Can't serialize " + update.toString() + " for JSON append");
        }
        appendJsonString(sb, key.getName());
        sb.append(",");
        Revision rev = key.getRevision();
        if (rev != null) {
            appendJsonString(sb, rev.toString());
            sb.append(",");
        }
        appendJsonValue(sb, op.value);
        sb.append("]");
        needComma = true;
    }
    return sb.append("]").toString();
}
Also used : DocumentStoreException(org.apache.jackrabbit.oak.plugins.document.DocumentStoreException) Revision(org.apache.jackrabbit.oak.plugins.document.Revision) Operation(org.apache.jackrabbit.oak.plugins.document.UpdateOp.Operation) Map(java.util.Map) TreeMap(java.util.TreeMap) Key(org.apache.jackrabbit.oak.plugins.document.UpdateOp.Key)

Example 10 with Key

use of org.apache.jackrabbit.oak.plugins.document.UpdateOp.Key in project jackrabbit-oak by apache.

the class MongoDocumentStore method createUpdate.

/**
     * Creates a MongoDB update object from the given UpdateOp.
     *
     * @param updateOp the update op.
     * @param includeId whether to include the SET id operation
     * @return the DBObject.
     */
@Nonnull
private static DBObject createUpdate(UpdateOp updateOp, boolean includeId) {
    BasicDBObject setUpdates = new BasicDBObject();
    BasicDBObject maxUpdates = new BasicDBObject();
    BasicDBObject incUpdates = new BasicDBObject();
    BasicDBObject unsetUpdates = new BasicDBObject();
    // always increment modCount
    updateOp.increment(Document.MOD_COUNT, 1);
    if (includeId) {
        setUpdates.append(Document.ID, updateOp.getId());
    }
    // other updates
    for (Entry<Key, Operation> entry : updateOp.getChanges().entrySet()) {
        Key k = entry.getKey();
        Operation op = entry.getValue();
        switch(op.type) {
            case SET:
            case SET_MAP_ENTRY:
                {
                    setUpdates.append(k.toString(), op.value);
                    break;
                }
            case MAX:
                {
                    maxUpdates.append(k.toString(), op.value);
                    break;
                }
            case INCREMENT:
                {
                    incUpdates.append(k.toString(), op.value);
                    break;
                }
            case REMOVE:
            case REMOVE_MAP_ENTRY:
                {
                    unsetUpdates.append(k.toString(), "1");
                    break;
                }
        }
    }
    BasicDBObject update = new BasicDBObject();
    if (!setUpdates.isEmpty()) {
        update.append("$set", setUpdates);
    }
    if (!maxUpdates.isEmpty()) {
        update.append("$max", maxUpdates);
    }
    if (!incUpdates.isEmpty()) {
        update.append("$inc", incUpdates);
    }
    if (!unsetUpdates.isEmpty()) {
        update.append("$unset", unsetUpdates);
    }
    return update;
}
Also used : BasicDBObject(com.mongodb.BasicDBObject) BulkWriteOperation(com.mongodb.BulkWriteOperation) Operation(org.apache.jackrabbit.oak.plugins.document.UpdateOp.Operation) Key(org.apache.jackrabbit.oak.plugins.document.UpdateOp.Key) Nonnull(javax.annotation.Nonnull)

Aggregations

Key (org.apache.jackrabbit.oak.plugins.document.UpdateOp.Key)19 Map (java.util.Map)12 Operation (org.apache.jackrabbit.oak.plugins.document.UpdateOp.Operation)12 Test (org.junit.Test)8 TreeMap (java.util.TreeMap)6 Condition (org.apache.jackrabbit.oak.plugins.document.UpdateOp.Condition)6 MemoryDocumentStore (org.apache.jackrabbit.oak.plugins.document.memory.MemoryDocumentStore)5 NodeBuilder (org.apache.jackrabbit.oak.spi.state.NodeBuilder)5 HashMap (java.util.HashMap)4 DocumentStoreException (org.apache.jackrabbit.oak.plugins.document.DocumentStoreException)4 Stopwatch (com.google.common.base.Stopwatch)3 BasicDBObject (com.mongodb.BasicDBObject)3 Nonnull (javax.annotation.Nonnull)3 CommitFailedException (org.apache.jackrabbit.oak.api.CommitFailedException)3 ImmutableMap (com.google.common.collect.ImmutableMap)2 BulkWriteOperation (com.mongodb.BulkWriteOperation)2 DBCollection (com.mongodb.DBCollection)2 DBObject (com.mongodb.DBObject)2 MongoException (com.mongodb.MongoException)2 QueryBuilder (com.mongodb.QueryBuilder)2