Mercurial > jhg
diff src/org/tmatesoft/hg/internal/RevlogDelegate.java @ 695:053bb4397bf9
Refactoring: nice Revlog.indexWalk() implementation
author | Artem Tikhomirov <tikhomirov.artem@gmail.com> |
---|---|
date | Mon, 05 Aug 2013 18:45:16 +0200 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/org/tmatesoft/hg/internal/RevlogDelegate.java Mon Aug 05 18:45:16 2013 +0200 @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2013 TMate Software Ltd + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * For information on how to redistribute this software under + * the terms of a license other than GNU General Public License + * contact TMate Software at support@hg4j.com + */ +package org.tmatesoft.hg.internal; + +import org.tmatesoft.hg.core.Nodeid; +import org.tmatesoft.hg.internal.RevlogStream.Inspector; +import org.tmatesoft.hg.repo.HgRepository; +import org.tmatesoft.hg.repo.HgRuntimeException; + +/** + * Does almost nothing, facilitates chains of inspectors and sharing certain information between them + * + * @author Artem Tikhomirov + * @author TMate Software Ltd. + */ +public abstract class RevlogDelegate implements RevlogStream.Inspector { + + private final Inspector next; + private Nodeid nid; + private final RevlogDelegate nextAsRD; + + protected RevlogDelegate(RevlogStream.Inspector nextInChain) { + next = nextInChain; + if (nextInChain instanceof RevlogDelegate) { + // additional benefits + nextAsRD = (RevlogDelegate) nextInChain; + } else { + nextAsRD = null; + } + } + + /** + * iterates index only and ensures pre/post processing is invoked for the chain + */ + public void walk(HgRepository hgRepo, RevlogStream stream, int from, int to) { + // hgRepo is handy for present uses, but is generally not appropriate, + // it's ok to refactor and let subclasses get what they need through e.g. a cons + stream.iterate(from, to, false, this); + postWalk(hgRepo); + } + + // does nothing but gives a chance to delegate to handle the same + protected void postWalk(HgRepository hgRepo) { + if (nextAsRD != null) { + nextAsRD.postWalk(hgRepo); + } + } + + /** + * @return Nodeid of current revision if already known, or a new instance otherwise. + * The value will propagate to subsequent {@link RevlogDelegate RevlogDelegates}, if any + */ + protected Nodeid getRevision(byte[] nodeid) { + if (nid == null) { + nid = Nodeid.fromBinary(nodeid, 0); + } + return nid; + } + + protected void setRevision(Nodeid nodeid) { + nid = nodeid; + } + + public void next(int revisionIndex, int actualLen, int baseRevision, int linkRevision, int parent1Revision, int parent2Revision, byte[] nodeid, DataAccess data) throws HgRuntimeException { + if (next != null) { + if (nextAsRD != null) { + nextAsRD.setRevision(nid); // null is fine + } + next.next(revisionIndex, actualLen, baseRevision, linkRevision, parent1Revision, parent2Revision, nodeid, data); + } + nid = null; // forget it, get ready for the next iteration + } +}