Search in sources :

Example 31 with CheckForNull

use of javax.annotation.CheckForNull in project jackrabbit-oak by apache.

the class RDBDocumentStore method internalCreate.

@CheckForNull
private <T extends Document> boolean internalCreate(Collection<T> collection, List<UpdateOp> updates) {
    final Stopwatch watch = startWatch();
    List<String> ids = new ArrayList<String>(updates.size());
    boolean success = true;
    try {
        // try up to CHUNKSIZE ops in one transaction
        for (List<UpdateOp> chunks : Lists.partition(updates, CHUNKSIZE)) {
            List<T> docs = new ArrayList<T>();
            for (UpdateOp update : chunks) {
                ids.add(update.getId());
                maintainUpdateStats(collection, update.getId());
                UpdateUtils.assertUnconditional(update);
                T doc = collection.newDocument(this);
                addUpdateCounters(update);
                UpdateUtils.applyChanges(doc, update);
                if (!update.getId().equals(doc.getId())) {
                    throw new DocumentStoreException("ID mismatch - UpdateOp: " + update.getId() + ", ID property: " + doc.getId());
                }
                docs.add(doc);
            }
            boolean done = insertDocuments(collection, docs);
            if (done) {
                if (collection == Collection.NODES) {
                    for (T doc : docs) {
                        nodesCache.putIfAbsent((NodeDocument) doc);
                    }
                }
            } else {
                success = false;
            }
        }
        return success;
    } catch (DocumentStoreException ex) {
        return false;
    } finally {
        stats.doneCreate(watch.elapsed(TimeUnit.NANOSECONDS), collection, ids, success);
    }
}
Also used : DocumentStoreException(org.apache.jackrabbit.oak.plugins.document.DocumentStoreException) UpdateOp(org.apache.jackrabbit.oak.plugins.document.UpdateOp) Stopwatch(com.google.common.base.Stopwatch) Lists.newArrayList(com.google.common.collect.Lists.newArrayList) ArrayList(java.util.ArrayList) CheckForNull(javax.annotation.CheckForNull)

Example 32 with CheckForNull

use of javax.annotation.CheckForNull in project jackrabbit-oak by apache.

the class RDBDocumentStore method readDocumentUncached.

@CheckForNull
private <T extends Document> T readDocumentUncached(Collection<T> collection, String id, NodeDocument cachedDoc) {
    Connection connection = null;
    RDBTableMetaData tmd = getTable(collection);
    final Stopwatch watch = startWatch();
    boolean docFound = true;
    try {
        long lastmodcount = -1, lastmodified = -1;
        if (cachedDoc != null) {
            lastmodcount = modcountOf(cachedDoc);
            lastmodified = modifiedOf(cachedDoc);
        }
        connection = this.ch.getROConnection();
        RDBRow row = db.read(connection, tmd, id, lastmodcount, lastmodified);
        connection.commit();
        if (row == null) {
            docFound = false;
            return null;
        } else {
            if (lastmodcount == row.getModcount() && lastmodified == row.getModified() && lastmodified >= 1) {
                // we can re-use the cached document
                cachedDoc.markUpToDate(System.currentTimeMillis());
                return castAsT(cachedDoc);
            } else {
                return convertFromDBObject(collection, row);
            }
        }
    } catch (Exception ex) {
        throw new DocumentStoreException(ex);
    } finally {
        this.ch.closeConnection(connection);
        stats.doneFindUncached(watch.elapsed(TimeUnit.NANOSECONDS), collection, id, docFound, false);
    }
}
Also used : DocumentStoreException(org.apache.jackrabbit.oak.plugins.document.DocumentStoreException) Connection(java.sql.Connection) Stopwatch(com.google.common.base.Stopwatch) UnsupportedEncodingException(java.io.UnsupportedEncodingException) DocumentStoreException(org.apache.jackrabbit.oak.plugins.document.DocumentStoreException) SQLException(java.sql.SQLException) IOException(java.io.IOException) ExecutionException(java.util.concurrent.ExecutionException) CheckForNull(javax.annotation.CheckForNull)

Example 33 with CheckForNull

use of javax.annotation.CheckForNull in project jackrabbit-oak by apache.

the class RDBDocumentStoreJDBC method read.

@CheckForNull
public RDBRow read(Connection connection, RDBTableMetaData tmd, String id, long lastmodcount, long lastmodified) throws SQLException {
    boolean useCaseStatement = lastmodcount != -1 && lastmodified >= 1;
    StringBuffer sql = new StringBuffer();
    sql.append("select MODIFIED, MODCOUNT, CMODCOUNT, HASBINARY, DELETEDONCE, ");
    if (useCaseStatement) {
        // the case statement causes the actual row data not to be
        // sent in case we already have it
        sql.append("case when (MODCOUNT = ? and MODIFIED = ?) then null else DATA end as DATA, ");
        sql.append("case when (MODCOUNT = ? and MODIFIED = ?) then null else BDATA end as BDATA ");
    } else {
        // either we don't have a previous version of the document
        // or the database does not support CASE in SELECT
        sql.append("DATA, BDATA ");
    }
    sql.append("from " + tmd.getName() + " where ID = ?");
    PreparedStatement stmt = connection.prepareStatement(sql.toString());
    ResultSet rs = null;
    try {
        int si = 1;
        if (useCaseStatement) {
            stmt.setLong(si++, lastmodcount);
            stmt.setLong(si++, lastmodified);
            stmt.setLong(si++, lastmodcount);
            stmt.setLong(si++, lastmodified);
        }
        setIdInStatement(tmd, stmt, si, id);
        rs = stmt.executeQuery();
        if (rs.next()) {
            long modified = readLongFromResultSet(rs, 1);
            long modcount = readLongFromResultSet(rs, 2);
            long cmodcount = readLongFromResultSet(rs, 3);
            Long hasBinary = readLongOrNullFromResultSet(rs, 4);
            Boolean deletedOnce = readBooleanOrNullFromResultSet(rs, 5);
            String data = rs.getString(6);
            byte[] bdata = rs.getBytes(7);
            return new RDBRow(id, hasBinary, deletedOnce, modified, modcount, cmodcount, data, bdata);
        } else {
            return null;
        }
    } catch (SQLException ex) {
        LOG.debug("attempting to read " + id + " (id length is " + id.length() + ")", ex);
        // gracefully
        if ("22001".equals(ex.getSQLState())) {
            try {
                connection.rollback();
            } catch (SQLException ex2) {
                LOG.debug("failed to rollback", ex2);
            }
            return null;
        } else {
            throw (ex);
        }
    } finally {
        closeResultSet(rs);
        closeStatement(stmt);
    }
}
Also used : SQLException(java.sql.SQLException) RDBJDBCTools.closeResultSet(org.apache.jackrabbit.oak.plugins.document.rdb.RDBJDBCTools.closeResultSet) ResultSet(java.sql.ResultSet) PreparedStatement(java.sql.PreparedStatement) CheckForNull(javax.annotation.CheckForNull)

Example 34 with CheckForNull

use of javax.annotation.CheckForNull in project jackrabbit-oak by apache.

the class MongoDocumentStore method createOrUpdate.

/**
     * Try to apply all the {@link UpdateOp}s with at least MongoDB requests as
     * possible. The return value is the list of the old documents (before
     * applying changes). The mechanism is as follows:
     *
     * <ol>
     * <li>For each UpdateOp try to read the assigned document from the cache.
     *     Add them to {@code oldDocs}.</li>
     * <li>Prepare a list of all UpdateOps that doesn't have their documents and
     *     read them in one find() call. Add results to {@code oldDocs}.</li>
     * <li>Prepare a bulk update. For each remaining UpdateOp add following
     *     operation:
     *   <ul>
     *   <li>Find document with the same id and the same mod_count as in the
     *       {@code oldDocs}.</li>
     *   <li>Apply changes from the UpdateOps.</li>
     *   </ul>
     * </li>
     * <li>Execute the bulk update.</li>
     * </ol>
     *
     * If some other process modifies the target documents between points 2 and
     * 3, the mod_count will be increased as well and the bulk update will fail
     * for the concurrently modified docs. The method will then remove the
     * failed documents from the {@code oldDocs} and restart the process from
     * point 2. It will stop after 3rd iteration.
     */
@SuppressWarnings("unchecked")
@CheckForNull
@Override
public <T extends Document> List<T> createOrUpdate(Collection<T> collection, List<UpdateOp> updateOps) {
    log("createOrUpdate", updateOps);
    Map<String, UpdateOp> operationsToCover = new LinkedHashMap<String, UpdateOp>();
    List<UpdateOp> duplicates = new ArrayList<UpdateOp>();
    Map<UpdateOp, T> results = new LinkedHashMap<UpdateOp, T>();
    final Stopwatch watch = startWatch();
    try {
        for (UpdateOp updateOp : updateOps) {
            UpdateUtils.assertUnconditional(updateOp);
            UpdateOp clone = updateOp.copy();
            if (operationsToCover.containsKey(updateOp.getId())) {
                duplicates.add(clone);
            } else {
                operationsToCover.put(updateOp.getId(), clone);
            }
            results.put(clone, null);
        }
        Map<String, T> oldDocs = new HashMap<String, T>();
        if (collection == Collection.NODES) {
            oldDocs.putAll((Map<String, T>) getCachedNodes(operationsToCover.keySet()));
        }
        for (int i = 0; i <= bulkRetries; i++) {
            if (operationsToCover.size() <= 2) {
                // in bulk mode wouldn't result in any performance gain
                break;
            }
            for (List<UpdateOp> partition : Lists.partition(Lists.newArrayList(operationsToCover.values()), bulkSize)) {
                Map<UpdateOp, T> successfulUpdates = bulkUpdate(collection, partition, oldDocs);
                results.putAll(successfulUpdates);
                operationsToCover.values().removeAll(successfulUpdates.keySet());
            }
        }
        // if there are some changes left, we'll apply them one after another
        Iterator<UpdateOp> it = Iterators.concat(operationsToCover.values().iterator(), duplicates.iterator());
        while (it.hasNext()) {
            UpdateOp op = it.next();
            it.remove();
            T oldDoc = createOrUpdate(collection, op);
            if (oldDoc != null) {
                results.put(op, oldDoc);
            }
        }
    } catch (MongoException e) {
        throw handleException(e, collection, Iterables.transform(updateOps, new Function<UpdateOp, String>() {

            @Override
            public String apply(UpdateOp input) {
                return input.getId();
            }
        }));
    } finally {
        stats.doneCreateOrUpdate(watch.elapsed(TimeUnit.NANOSECONDS), collection, Lists.transform(updateOps, new Function<UpdateOp, String>() {

            @Override
            public String apply(UpdateOp input) {
                return input.getId();
            }
        }));
    }
    List<T> resultList = new ArrayList<T>(results.values());
    log("createOrUpdate returns", resultList);
    return resultList;
}
Also used : MongoException(com.mongodb.MongoException) UpdateOp(org.apache.jackrabbit.oak.plugins.document.UpdateOp) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) ArrayList(java.util.ArrayList) Stopwatch(com.google.common.base.Stopwatch) LinkedHashMap(java.util.LinkedHashMap) Function(com.google.common.base.Function) CheckForNull(javax.annotation.CheckForNull)

Example 35 with CheckForNull

use of javax.annotation.CheckForNull in project jackrabbit-oak by apache.

the class RDBDocumentStore method internalUpdate.

@CheckForNull
private <T extends Document> void internalUpdate(Collection<T> collection, List<String> ids, UpdateOp update) {
    if (isAppendableUpdate(update, true) && !requiresPreviousState(update)) {
        Operation modOperation = update.getChanges().get(MODIFIEDKEY);
        long modified = getModifiedFromOperation(modOperation);
        boolean modifiedIsConditional = modOperation == null || modOperation.type != UpdateOp.Operation.Type.SET;
        String appendData = ser.asString(update);
        for (List<String> chunkedIds : Lists.partition(ids, CHUNKSIZE)) {
            if (collection == Collection.NODES) {
                for (String key : chunkedIds) {
                    nodesCache.invalidate(key);
                }
            }
            Connection connection = null;
            RDBTableMetaData tmd = getTable(collection);
            boolean success = false;
            try {
                Stopwatch watch = startWatch();
                connection = this.ch.getRWConnection();
                success = db.batchedAppendingUpdate(connection, tmd, chunkedIds, modified, modifiedIsConditional, appendData);
                connection.commit();
                //Internally 'db' would make multiple calls and number of those
                //remote calls would not be captured
                stats.doneUpdate(watch.elapsed(TimeUnit.NANOSECONDS), collection, chunkedIds.size());
            } catch (SQLException ex) {
                success = false;
                this.ch.rollbackConnection(connection);
            } finally {
                this.ch.closeConnection(connection);
            }
            if (success) {
                if (collection == Collection.NODES) {
                    for (String id : chunkedIds) {
                        nodesCache.invalidate(id);
                    }
                }
            } else {
                for (String id : chunkedIds) {
                    UpdateOp up = update.copy();
                    up = up.shallowCopy(id);
                    internalCreateOrUpdate(collection, up, false, true);
                }
            }
        }
    } else {
        Stopwatch watch = startWatch();
        for (String id : ids) {
            UpdateOp up = update.copy();
            up = up.shallowCopy(id);
            internalCreateOrUpdate(collection, up, false, true);
        }
        stats.doneUpdate(watch.elapsed(TimeUnit.NANOSECONDS), collection, ids.size());
    }
}
Also used : SQLException(java.sql.SQLException) UpdateOp(org.apache.jackrabbit.oak.plugins.document.UpdateOp) Connection(java.sql.Connection) Stopwatch(com.google.common.base.Stopwatch) Operation(org.apache.jackrabbit.oak.plugins.document.UpdateOp.Operation) CheckForNull(javax.annotation.CheckForNull)

Aggregations

CheckForNull (javax.annotation.CheckForNull)149 IOException (java.io.IOException)18 Tree (org.apache.jackrabbit.oak.api.Tree)16 PropertyState (org.apache.jackrabbit.oak.api.PropertyState)12 ArrayList (java.util.ArrayList)9 NodeState (org.apache.jackrabbit.oak.spi.state.NodeState)9 Stopwatch (com.google.common.base.Stopwatch)8 UnsupportedCallbackException (javax.security.auth.callback.UnsupportedCallbackException)8 Date (java.util.Date)7 SnapshotDto (org.sonar.db.component.SnapshotDto)7 Period (org.sonar.server.computation.task.projectanalysis.period.Period)7 File (java.io.File)6 SQLException (java.sql.SQLException)6 DocumentStoreException (org.apache.jackrabbit.oak.plugins.document.DocumentStoreException)6 ExecutionException (java.util.concurrent.ExecutionException)5 ValidationModel (org.apache.sling.validation.model.ValidationModel)5 CommitFailedException (org.apache.jackrabbit.oak.api.CommitFailedException)4 Root (org.apache.jackrabbit.oak.api.Root)4 Utils.resolveCommitRevision (org.apache.jackrabbit.oak.plugins.document.util.Utils.resolveCommitRevision)4 ResourceResolver (org.apache.sling.api.resource.ResourceResolver)4