Mercurial > hg4j
view src/org/tmatesoft/hg/repo/HgTags.java @ 104:54562de502f7
Preliminary tags implementation
author | Artem Tikhomirov <tikhomirov.artem@gmail.com> |
---|---|
date | Fri, 28 Jan 2011 17:51:54 +0100 |
parents | a3a2e5deb320 |
children | b2cfbe46f9b6 |
line wrap: on
line source
/* * Copyright (c) 2011 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.repo; import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.TreeMap; import org.tmatesoft.hg.core.Nodeid; /** * @see http://mercurial.selenic.com/wiki/TagDesign * * @author Artem Tikhomirov * @author TMate Software Ltd. */ public class HgTags { // global tags come from ".hgtags" // local come from ".hg/localtags" private final Map<Nodeid, List<String>> globalToName; private final Map<Nodeid, List<String>> localToName; private final Map<String, List<Nodeid>> globalFromName; private final Map<String, List<Nodeid>> localFromName; /*package-local*/ HgTags() { globalToName = new HashMap<Nodeid, List<String>>(); localToName = new HashMap<Nodeid, List<String>>(); globalFromName = new TreeMap<String, List<Nodeid>>(); localFromName = new TreeMap<String, List<Nodeid>>(); } /*package-local*/ void readLocal(File localTags) throws IOException { if (localTags == null || localTags.isDirectory()) { throw new IllegalArgumentException(String.valueOf(localTags)); } read(localTags, localToName, localFromName); } /*package-local*/ void readGlobal(File globalTags) throws IOException { if (globalTags == null || globalTags.isDirectory()) { throw new IllegalArgumentException(String.valueOf(globalTags)); } read(globalTags, globalToName, globalFromName); } private void read(File f, Map<Nodeid,List<String>> nid2name, Map<String, List<Nodeid>> name2nid) throws IOException { if (!f.canRead()) { return; } BufferedReader r = null; try { r = new BufferedReader(new FileReader(f)); read(r, nid2name, name2nid); } finally { if (r != null) { r.close(); } } } private void read(BufferedReader reader, Map<Nodeid,List<String>> nid2name, Map<String, List<Nodeid>> name2nid) throws IOException { String line; while ((line = reader.readLine()) != null) { line = line.trim(); if (line.length() == 0) { continue; } if (line.length() < 40+2 /*nodeid, space and at least single-char tagname*/) { System.out.println("Bad tags line:" + line); // FIXME log or otherwise report (IStatus analog?) continue; } int spacePos = line.indexOf(' '); if (spacePos != -1) { assert spacePos == 40; final byte[] nodeidBytes = line.substring(0, spacePos).getBytes(); Nodeid nid = Nodeid.fromAscii(nodeidBytes, 0, nodeidBytes.length); String tagName = line.substring(spacePos+1); List<Nodeid> nids = name2nid.get(tagName); if (nids == null) { nids = new LinkedList<Nodeid>(); // tagName is substring of full line, thus need a copy to let the line be GC'ed // new String(tagName.toCharArray()) is more expressive, but results in 1 extra arraycopy tagName = new String(tagName); name2nid.put(tagName, nids); } // XXX repo.getNodeidCache().nodeid(nid); ((LinkedList<Nodeid>) nids).addFirst(nid); List<String> revTags = nid2name.get(nid); if (revTags == null) { revTags = new LinkedList<String>(); nid2name.put(nid, revTags); } revTags.add(tagName); } else { System.out.println("Bad tags line:" + line); // FIXME see above } } } public List<String> tags(Nodeid nid) { ArrayList<String> rv = new ArrayList<String>(5); List<String> l; if ((l = localToName.get(nid)) != null) { rv.addAll(l); } if ((l = globalToName.get(nid)) != null) { rv.addAll(l); } return rv; } public boolean isTagged(Nodeid nid) { return localToName.containsKey(nid) || globalToName.containsKey(nid); } public List<Nodeid> tagged(String tagName) { ArrayList<Nodeid> rv = new ArrayList<Nodeid>(5); List<Nodeid> l; if ((l = localFromName.get(tagName)) != null) { rv.addAll(l); } if ((l = globalFromName.get(tagName)) != null) { rv.addAll(l); } return rv; } }