private FSRepresentationState buildRepresentationList( FSRepresentation firstRep, LinkedList result, FSFS owner) throws SVNException { FSFile file = null; FSRepresentation rep = new FSRepresentation(firstRep); ByteBuffer buffer = ByteBuffer.allocate(4); try { while (true) { file = owner.openAndSeekRepresentation(rep); FSRepresentationState repState = readRepresentationLine(file); repState.myFile = file; repState.myStart = file.position(); repState.myOffset = repState.myStart; repState.myEnd = repState.myStart + rep.getSize(); if (!repState.myIsDelta) { return repState; } buffer.clear(); int r = file.read(buffer); byte[] header = buffer.array(); if (!(header[0] == 'S' && header[1] == 'V' && header[2] == 'N' && r == 4)) { SVNErrorMessage err = SVNErrorMessage.create( SVNErrorCode.FS_CORRUPT, "Malformed svndiff data in representation"); SVNErrorManager.error(err, SVNLogType.FSFS); } repState.myVersion = header[3]; repState.myChunkIndex = 0; repState.myOffset += 4; /* * Push this rep onto the list. If it's self-compressed, we're * done. */ result.addLast(repState); if (repState.myIsDeltaVsEmpty) { return null; } rep.setRevision(repState.myBaseRevision); rep.setOffset(repState.myBaseOffset); rep.setSize(repState.myBaseLength); rep.setTxnId(null); } } catch (IOException ioe) { file.close(); SVNErrorMessage err = SVNErrorMessage.create(SVNErrorCode.IO_ERROR, ioe.getLocalizedMessage()); SVNErrorManager.error(err, ioe, SVNLogType.FSFS); } catch (SVNException svne) { file.close(); throw svne; } return null; }
public static FSRepresentationState readRepresentationLine(FSFile file) throws SVNException { try { String line = file.readLine(160); FSRepresentationState repState = new FSRepresentationState(); repState.myIsDelta = false; if (FSRepresentation.REP_PLAIN.equals(line)) { return repState; } if (FSRepresentation.REP_DELTA.equals(line)) { /* This is a delta against the empty stream. */ repState.myIsDelta = true; repState.myIsDeltaVsEmpty = true; return repState; } repState.myIsDelta = true; repState.myIsDeltaVsEmpty = false; /* We have hopefully a DELTA vs. a non-empty base revision. */ int delimiterInd = line.indexOf(' '); if (delimiterInd == -1) { SVNErrorMessage err = SVNErrorMessage.create(SVNErrorCode.FS_CORRUPT, "Malformed representation header"); SVNErrorManager.error(err, SVNLogType.FSFS); } String header = line.substring(0, delimiterInd); if (!FSRepresentation.REP_DELTA.equals(header)) { SVNErrorMessage err = SVNErrorMessage.create(SVNErrorCode.FS_CORRUPT, "Malformed representation header"); SVNErrorManager.error(err, SVNLogType.FSFS); } line = line.substring(delimiterInd + 1); try { delimiterInd = line.indexOf(' '); if (delimiterInd == -1) { SVNErrorMessage err = SVNErrorMessage.create(SVNErrorCode.FS_CORRUPT, "Malformed representation header"); SVNErrorManager.error(err, SVNLogType.FSFS); } String baseRevision = line.substring(0, delimiterInd); repState.myBaseRevision = Long.parseLong(baseRevision); line = line.substring(delimiterInd + 1); delimiterInd = line.indexOf(' '); if (delimiterInd == -1) { SVNErrorMessage err = SVNErrorMessage.create(SVNErrorCode.FS_CORRUPT, "Malformed representation header"); SVNErrorManager.error(err, SVNLogType.FSFS); } String baseOffset = line.substring(0, delimiterInd); repState.myBaseOffset = Long.parseLong(baseOffset); line = line.substring(delimiterInd + 1); repState.myBaseLength = Long.parseLong(line); } catch (NumberFormatException nfe) { SVNErrorMessage err = SVNErrorMessage.create(SVNErrorCode.FS_CORRUPT, "Malformed representation header"); SVNErrorManager.error(err, SVNLogType.FSFS); } return repState; } catch (SVNException svne) { file.close(); throw svne; } }
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; }