private long commit() throws SVNException {
    long oldRev = myFSFS.getYoungestRevision();

    if (myTxn.getBaseRevision() != oldRev) {
      SVNErrorMessage err =
          SVNErrorMessage.create(SVNErrorCode.FS_TXN_OUT_OF_DATE, "Transaction out of date");
      SVNErrorManager.error(err, SVNLogType.FSFS);
    }

    verifyLocks();

    final String startNodeId;
    final String startCopyId;
    if (myFSFS.getDBFormat() < FSFS.MIN_NO_GLOBAL_IDS_FORMAT) {
      String[] ids = myFSFS.getNextRevisionIDs();
      startNodeId = ids[0];
      startCopyId = ids[1];
    } else {
      startNodeId = null;
      startCopyId = null;
    }

    final long newRevision = oldRev + 1;
    final OutputStream protoFileOS = null;
    final FSID newRootId = null;
    final FSTransactionRoot txnRoot = getTxnRoot();
    FSWriteLock txnWriteLock = FSWriteLock.getWriteLockForTxn(myTxn.getTxnId(), myFSFS);
    synchronized (txnWriteLock) {
      try {
        // start transaction.
        txnWriteLock.lock();
        final File revisionPrototypeFile = txnRoot.getTransactionProtoRevFile();
        final long offset = revisionPrototypeFile.length();
        if (myFSFS.getRepositoryCacheManager() != null) {
          myFSFS
              .getRepositoryCacheManager()
              .runWriteTransaction(
                  new IFSSqlJetTransaction() {
                    public void run() throws SVNException {
                      commit(
                          startNodeId,
                          startCopyId,
                          newRevision,
                          protoFileOS,
                          newRootId,
                          txnRoot,
                          revisionPrototypeFile,
                          offset);
                    }
                  });
        } else {
          commit(
              startNodeId,
              startCopyId,
              newRevision,
              protoFileOS,
              newRootId,
              txnRoot,
              revisionPrototypeFile,
              offset);
        }
        File dstRevFile = myFSFS.getNewRevisionFile(newRevision);
        SVNFileUtil.rename(revisionPrototypeFile, dstRevFile);
      } finally {
        txnWriteLock.unlock();
        FSWriteLock.release(txnWriteLock);
      }
    }

    String commitTime = SVNDate.formatDate(new Date(System.currentTimeMillis()));
    SVNProperties presetRevisionProperties = myFSFS.getTransactionProperties(myTxn.getTxnId());
    if (presetRevisionProperties == null
        || !presetRevisionProperties.containsName(SVNRevisionProperty.DATE)) {
      myFSFS.setTransactionProperty(
          myTxn.getTxnId(), SVNRevisionProperty.DATE, SVNPropertyValue.create(commitTime));
    }

    File txnPropsFile = myFSFS.getTransactionPropertiesFile(myTxn.getTxnId());

    if (myFSFS.getDBFormat() < FSFS.MIN_PACKED_REVPROP_FORMAT
        || newRevision >= myFSFS.getMinUnpackedRevProp()) {
      File dstRevPropsFile = myFSFS.getNewRevisionPropertiesFile(newRevision);
      SVNFileUtil.rename(txnPropsFile, dstRevPropsFile);
    } else {
      /* Read the revprops, and commit them to the permenant sqlite db. */
      FSFile fsfProps = new FSFile(txnPropsFile);
      try {
        final SVNProperties revProperties = fsfProps.readProperties(false, true);
        final SVNSqlJetStatement stmt =
            myFSFS.getRevisionProperitesDb().getStatement(SVNWCDbStatements.FSFS_SET_REVPROP);
        try {
          stmt.insert(
              new Object[] {newRevision, SVNSkel.createPropList(revProperties.asMap()).getData()});
        } finally {
          stmt.reset();
        }
      } finally {
        fsfProps.close();
      }
    }

    try {
      txnRoot.writeFinalCurrentFile(newRevision, startNodeId, startCopyId);
    } catch (IOException ioe) {
      SVNErrorMessage err =
          SVNErrorMessage.create(SVNErrorCode.IO_ERROR, ioe.getLocalizedMessage());
      SVNErrorManager.error(err, ioe, SVNLogType.FSFS);
    }
    myFSFS.setYoungestRevisionCache(newRevision);
    myFSFS.purgeTxn(myTxn.getTxnId());
    return newRevision;
  }
Exemple #2
0
  public static OutputStream createStream(
      FSRevisionNode revNode, FSTransactionRoot txnRoot, OutputStream dstStream, boolean compress)
      throws SVNException {
    if (revNode.getType() != SVNNodeKind.FILE) {
      SVNErrorMessage err =
          SVNErrorMessage.create(
              SVNErrorCode.FS_NOT_FILE, "Attempted to set textual contents of a *non*-file node");
      SVNErrorManager.error(err, SVNLogType.FSFS);
    }

    if (!revNode.getId().isTxn()) {
      SVNErrorMessage err =
          SVNErrorMessage.create(
              SVNErrorCode.FS_NOT_MUTABLE,
              "Attempted to set textual contents of an immutable node");
      SVNErrorManager.error(err, SVNLogType.FSFS);
    }

    OutputStream targetOS = null;
    InputStream sourceStream = null;
    long offset = -1;
    long deltaStart = -1;
    FSWriteLock txnLock = null;
    try {
      txnLock = FSWriteLock.getWriteLockForTxn(txnRoot.getTxnID(), txnRoot.getOwner());
      txnLock.lock();

      File targetFile = txnRoot.getTransactionProtoRevFile();
      offset = targetFile.length();
      targetOS = SVNFileUtil.openFileForWriting(targetFile, true);
      CountingOutputStream revWriter = new CountingOutputStream(targetOS, offset);

      FSRepresentation baseRep = revNode.chooseDeltaBase(txnRoot.getOwner());
      sourceStream =
          FSInputStream.createDeltaStream(new SVNDeltaCombiner(), baseRep, txnRoot.getOwner());
      String header;

      if (baseRep != null) {
        header =
            FSRepresentation.REP_DELTA
                + " "
                + baseRep.getRevision()
                + " "
                + baseRep.getOffset()
                + " "
                + baseRep.getSize()
                + "\n";
      } else {
        header = FSRepresentation.REP_DELTA + "\n";
      }

      revWriter.write(header.getBytes("UTF-8"));
      deltaStart = revWriter.getPosition();

      if (dstStream instanceof FSOutputStream) {
        FSOutputStream fsOS = (FSOutputStream) dstStream;
        fsOS.reset(
            revNode, revWriter, targetFile, sourceStream, deltaStart, 0, offset, txnRoot, txnLock);
        return dstStream;
      }

      return new FSOutputStream(
          revNode,
          revWriter,
          targetFile,
          sourceStream,
          deltaStart,
          0,
          offset,
          txnRoot,
          compress,
          txnLock);

    } catch (IOException ioe) {
      SVNFileUtil.closeFile(targetOS);
      SVNFileUtil.closeFile(sourceStream);
      txnLock.unlock();
      FSWriteLock.release(txnLock);
      SVNErrorMessage err =
          SVNErrorMessage.create(SVNErrorCode.IO_ERROR, ioe.getLocalizedMessage());
      SVNErrorManager.error(err, ioe, SVNLogType.FSFS);
    } catch (SVNException svne) {
      if (txnLock != null) {
        txnLock.unlock();
        FSWriteLock.release(txnLock);
      }
      SVNFileUtil.closeFile(targetOS);
      SVNFileUtil.closeFile(sourceStream);
      throw svne;
    }
    return null;
  }