tikhomirov@660: /* tikhomirov@660: * Copyright (c) 2013 TMate Software Ltd tikhomirov@660: * tikhomirov@660: * This program is free software; you can redistribute it and/or modify tikhomirov@660: * it under the terms of the GNU General Public License as published by tikhomirov@660: * the Free Software Foundation; version 2 of the License. tikhomirov@660: * tikhomirov@660: * This program is distributed in the hope that it will be useful, tikhomirov@660: * but WITHOUT ANY WARRANTY; without even the implied warranty of tikhomirov@660: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the tikhomirov@660: * GNU General Public License for more details. tikhomirov@660: * tikhomirov@660: * For information on how to redistribute this software under tikhomirov@660: * the terms of a license other than GNU General Public License tikhomirov@660: * contact TMate Software at support@hg4j.com tikhomirov@660: */ tikhomirov@660: package org.tmatesoft.hg.internal; tikhomirov@660: tikhomirov@663: import java.io.IOException; tikhomirov@660: import java.util.HashMap; tikhomirov@660: import java.util.Set; tikhomirov@660: tikhomirov@660: import org.tmatesoft.hg.core.HgIOException; tikhomirov@660: import org.tmatesoft.hg.core.Nodeid; tikhomirov@660: import org.tmatesoft.hg.repo.HgBundle; tikhomirov@660: import org.tmatesoft.hg.repo.HgBundle.GroupElement; tikhomirov@660: import org.tmatesoft.hg.repo.HgDataFile; tikhomirov@660: import org.tmatesoft.hg.repo.HgInvalidControlFileException; tikhomirov@660: import org.tmatesoft.hg.repo.HgRepository; tikhomirov@660: import org.tmatesoft.hg.repo.HgRuntimeException; tikhomirov@660: import org.tmatesoft.hg.util.Pair; tikhomirov@660: tikhomirov@660: /** tikhomirov@663: * FIXME pretty much alike HgCloneCommand.WriteDownMate, shall converge tikhomirov@663: * tikhomirov@660: * @author Artem Tikhomirov tikhomirov@660: * @author TMate Software Ltd. tikhomirov@660: */ tikhomirov@660: public final class AddRevInspector implements HgBundle.Inspector { tikhomirov@660: private final Internals repo; tikhomirov@660: private final Transaction tr; tikhomirov@663: private final FNCacheFile.Mediator fncache; tikhomirov@660: private Set added; tikhomirov@660: private RevlogStreamWriter revlog; tikhomirov@660: private RevMap clogRevs; tikhomirov@660: private RevMap revlogRevs; tikhomirov@663: private HgDataFile fileNode; tikhomirov@663: private boolean newFile = false; tikhomirov@660: tikhomirov@660: public AddRevInspector(Internals implRepo, Transaction transaction) { tikhomirov@660: repo = implRepo; tikhomirov@660: tr = transaction; tikhomirov@663: fncache = new FNCacheFile.Mediator(implRepo); tikhomirov@660: } tikhomirov@660: tikhomirov@660: public void changelogStart() throws HgRuntimeException { tikhomirov@660: RevlogStream rs = repo.getImplAccess().getChangelogStream(); tikhomirov@660: revlog = new RevlogStreamWriter(repo, rs, tr); tikhomirov@660: revlogRevs = clogRevs = new RevMap(rs); tikhomirov@660: } tikhomirov@660: tikhomirov@660: public void changelogEnd() throws HgRuntimeException { tikhomirov@660: revlog = null; tikhomirov@660: revlogRevs = null; tikhomirov@660: added = clogRevs.added(); tikhomirov@660: } tikhomirov@660: tikhomirov@660: public void manifestStart() throws HgRuntimeException { tikhomirov@660: RevlogStream rs = repo.getImplAccess().getManifestStream(); tikhomirov@660: revlog = new RevlogStreamWriter(repo, rs, tr); tikhomirov@660: revlogRevs = new RevMap(rs); tikhomirov@660: } tikhomirov@660: tikhomirov@660: public void manifestEnd() throws HgRuntimeException { tikhomirov@660: revlog = null; tikhomirov@660: revlogRevs = null; tikhomirov@660: } tikhomirov@660: tikhomirov@660: public void fileStart(String name) throws HgRuntimeException { tikhomirov@663: fileNode = repo.getRepo().getFileNode(name); tikhomirov@663: newFile = !fileNode.exists(); tikhomirov@663: RevlogStream rs = repo.getImplAccess().getStream(fileNode); tikhomirov@660: revlog = new RevlogStreamWriter(repo, rs, tr); tikhomirov@660: revlogRevs = new RevMap(rs); tikhomirov@660: } tikhomirov@660: tikhomirov@660: public void fileEnd(String name) throws HgRuntimeException { tikhomirov@663: if (newFile) { tikhomirov@663: fncache.registerNew(fileNode.getPath(), revlog.getRevlogStream()); tikhomirov@663: } tikhomirov@660: revlog = null; tikhomirov@660: revlogRevs = null; tikhomirov@660: } tikhomirov@660: tikhomirov@660: public boolean element(GroupElement ge) throws HgRuntimeException { tikhomirov@660: assert clogRevs != null; tikhomirov@660: assert revlogRevs != null; tikhomirov@663: if (revlog.getRevlogStream().findRevisionIndex(ge.node()) != HgRepository.BAD_REVISION) { tikhomirov@663: // HgRemoteRepository.getChanges(common) builds a bundle that includes these common tikhomirov@663: // revisions. Hence, shall not add these common (i.e. known locally) revisions tikhomirov@663: // once again tikhomirov@663: return true; tikhomirov@663: } tikhomirov@660: try { tikhomirov@660: Pair newRev = revlog.addPatchRevision(ge, clogRevs, revlogRevs); tikhomirov@660: revlogRevs.update(newRev.first(), newRev.second()); tikhomirov@660: return true; tikhomirov@660: } catch (HgIOException ex) { tikhomirov@660: throw new HgInvalidControlFileException(ex, true); tikhomirov@660: } tikhomirov@660: } tikhomirov@660: tikhomirov@660: public RevisionSet addedChangesets() { tikhomirov@660: return new RevisionSet(added); tikhomirov@660: } tikhomirov@663: tikhomirov@663: public void done() throws IOException { tikhomirov@663: fncache.complete(); tikhomirov@663: } tikhomirov@660: tikhomirov@660: private static class RevMap implements RevlogStreamWriter.RevisionToIndexMap { tikhomirov@660: tikhomirov@660: private final RevlogStream revlog; tikhomirov@660: private HashMap added = new HashMap(); tikhomirov@660: tikhomirov@660: public RevMap(RevlogStream revlogStream) { tikhomirov@660: revlog = revlogStream; tikhomirov@660: } tikhomirov@660: tikhomirov@660: public int revisionIndex(Nodeid revision) { tikhomirov@660: Integer a = added.get(revision); tikhomirov@660: if (a != null) { tikhomirov@660: return a; tikhomirov@660: } tikhomirov@660: int f = revlog.findRevisionIndex(revision); tikhomirov@660: return f == HgRepository.BAD_REVISION ? HgRepository.NO_REVISION : f; tikhomirov@660: } tikhomirov@660: tikhomirov@660: public void update(Integer revIndex, Nodeid rev) { tikhomirov@660: added.put(rev, revIndex); tikhomirov@660: } tikhomirov@660: tikhomirov@660: Set added() { tikhomirov@660: return added.keySet(); tikhomirov@660: } tikhomirov@660: } tikhomirov@660: }