Mercurial > jhg
annotate hg4j/src/main/java/org/tmatesoft/hg/repo/HgDataFile.java @ 213:6ec4af642ba8 gradle
Project uses Gradle for build - actual changes
author | Alexander Kitaev <kitaev@gmail.com> |
---|---|
date | Tue, 10 May 2011 10:52:53 +0200 |
parents | |
children |
rev | line source |
---|---|
213
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
1 /* |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
2 * Copyright (c) 2010-2011 TMate Software Ltd |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
3 * |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
4 * This program is free software; you can redistribute it and/or modify |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
5 * it under the terms of the GNU General Public License as published by |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
6 * the Free Software Foundation; version 2 of the License. |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
7 * |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
8 * This program is distributed in the hope that it will be useful, |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
11 * GNU General Public License for more details. |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
12 * |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
13 * For information on how to redistribute this software under |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
14 * the terms of a license other than GNU General Public License |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
15 * contact TMate Software at support@hg4j.com |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
16 */ |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
17 package org.tmatesoft.hg.repo; |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
18 |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
19 import static org.tmatesoft.hg.repo.HgInternals.wrongLocalRevision; |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
20 import static org.tmatesoft.hg.repo.HgRepository.*; |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
21 |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
22 import java.io.ByteArrayOutputStream; |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
23 import java.io.IOException; |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
24 import java.nio.ByteBuffer; |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
25 import java.util.ArrayList; |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
26 import java.util.Collection; |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
27 import java.util.TreeMap; |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
28 |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
29 import org.tmatesoft.hg.core.HgDataStreamException; |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
30 import org.tmatesoft.hg.core.HgException; |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
31 import org.tmatesoft.hg.core.Nodeid; |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
32 import org.tmatesoft.hg.internal.DataAccess; |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
33 import org.tmatesoft.hg.internal.FilterByteChannel; |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
34 import org.tmatesoft.hg.internal.RevlogStream; |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
35 import org.tmatesoft.hg.util.ByteChannel; |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
36 import org.tmatesoft.hg.util.CancelledException; |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
37 import org.tmatesoft.hg.util.Path; |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
38 |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
39 |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
40 |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
41 /** |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
42 * ? name:HgFileNode? |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
43 * |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
44 * @author Artem Tikhomirov |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
45 * @author TMate Software Ltd. |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
46 */ |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
47 public class HgDataFile extends Revlog { |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
48 |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
49 // absolute from repo root? |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
50 // slashes, unix-style? |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
51 // repo location agnostic, just to give info to user, not to access real storage |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
52 private final Path path; |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
53 private Metadata metadata; // get initialized on first access to file content. |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
54 |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
55 /*package-local*/HgDataFile(HgRepository hgRepo, Path filePath, RevlogStream content) { |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
56 super(hgRepo, content); |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
57 path = filePath; |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
58 } |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
59 |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
60 /*package-local*/HgDataFile(HgRepository hgRepo, Path filePath) { |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
61 super(hgRepo); |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
62 path = filePath; |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
63 } |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
64 |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
65 // exists is not the best name possible. now it means no file with such name was ever known to the repo. |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
66 // it might be confused with files existed before but lately removed. |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
67 public boolean exists() { |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
68 return content != null; // XXX need better impl |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
69 } |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
70 |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
71 // human-readable (i.e. "COPYING", not "store/data/_c_o_p_y_i_n_g.i") |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
72 public Path getPath() { |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
73 return path; // hgRepo.backresolve(this) -> name? In this case, what about hashed long names? |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
74 } |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
75 |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
76 public int length(Nodeid nodeid) { |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
77 return content.dataLength(getLocalRevision(nodeid)); |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
78 } |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
79 |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
80 public void workingCopy(ByteChannel sink) throws IOException, CancelledException { |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
81 throw HgRepository.notImplemented(); |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
82 } |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
83 |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
84 // public void content(int revision, ByteChannel sink, boolean applyFilters) throws HgDataStreamException, IOException, CancelledException { |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
85 // byte[] content = content(revision); |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
86 // final CancelSupport cancelSupport = CancelSupport.Factory.get(sink); |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
87 // final ProgressSupport progressSupport = ProgressSupport.Factory.get(sink); |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
88 // ByteBuffer buf = ByteBuffer.allocate(512); |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
89 // int left = content.length; |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
90 // progressSupport.start(left); |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
91 // int offset = 0; |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
92 // cancelSupport.checkCancelled(); |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
93 // ByteChannel _sink = applyFilters ? new FilterByteChannel(sink, getRepo().getFiltersFromRepoToWorkingDir(getPath())) : sink; |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
94 // do { |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
95 // buf.put(content, offset, Math.min(left, buf.remaining())); |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
96 // buf.flip(); |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
97 // cancelSupport.checkCancelled(); |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
98 // // XXX I may not rely on returned number of bytes but track change in buf position instead. |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
99 // int consumed = _sink.write(buf); |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
100 // buf.compact(); |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
101 // offset += consumed; |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
102 // left -= consumed; |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
103 // progressSupport.worked(consumed); |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
104 // } while (left > 0); |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
105 // progressSupport.done(); // XXX shall specify whether #done() is invoked always or only if completed successfully. |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
106 // } |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
107 |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
108 /*XXX not sure distinct method contentWithFilters() is the best way to do, perhaps, callers shall add filters themselves?*/ |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
109 public void contentWithFilters(int revision, ByteChannel sink) throws HgDataStreamException, IOException, CancelledException { |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
110 content(revision, new FilterByteChannel(sink, getRepo().getFiltersFromRepoToWorkingDir(getPath()))); |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
111 } |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
112 |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
113 // for data files need to check heading of the file content for possible metadata |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
114 // @see http://mercurial.selenic.com/wiki/FileFormats#data.2BAC8- |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
115 public void content(int revision, ByteChannel sink) throws HgDataStreamException, IOException, CancelledException { |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
116 if (revision == TIP) { |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
117 revision = getLastRevision(); |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
118 } |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
119 if (revision == WORKING_COPY) { |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
120 workingCopy(sink); |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
121 return; |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
122 } |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
123 if (wrongLocalRevision(revision) || revision == BAD_REVISION) { |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
124 throw new IllegalArgumentException(String.valueOf(revision)); |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
125 } |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
126 if (sink == null) { |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
127 throw new IllegalArgumentException(); |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
128 } |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
129 if (metadata == null) { |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
130 metadata = new Metadata(); |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
131 } |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
132 ContentPipe insp; |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
133 if (metadata.none(revision)) { |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
134 insp = new ContentPipe(sink, 0); |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
135 } else if (metadata.known(revision)) { |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
136 insp = new ContentPipe(sink, metadata.dataOffset(revision)); |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
137 } else { |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
138 // do not know if there's metadata |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
139 insp = new MetadataContentPipe(sink, metadata); |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
140 } |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
141 insp.checkCancelled(); |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
142 super.content.iterate(revision, revision, true, insp); |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
143 try { |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
144 insp.checkFailed(); |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
145 } catch (HgDataStreamException ex) { |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
146 throw ex; |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
147 } catch (HgException ex) { |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
148 // shall not happen, unless we changed ContentPipe or its subclass |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
149 throw new HgDataStreamException(ex.getClass().getName(), ex); |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
150 } |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
151 } |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
152 |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
153 public void history(HgChangelog.Inspector inspector) { |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
154 history(0, getLastRevision(), inspector); |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
155 } |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
156 |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
157 public void history(int start, int end, HgChangelog.Inspector inspector) { |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
158 if (!exists()) { |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
159 throw new IllegalStateException("Can't get history of invalid repository file node"); |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
160 } |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
161 final int last = getLastRevision(); |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
162 if (start < 0 || start > last) { |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
163 throw new IllegalArgumentException(); |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
164 } |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
165 if (end == TIP) { |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
166 end = last; |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
167 } else if (end < start || end > last) { |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
168 throw new IllegalArgumentException(); |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
169 } |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
170 final int[] commitRevisions = new int[end - start + 1]; |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
171 RevlogStream.Inspector insp = new RevlogStream.Inspector() { |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
172 int count = 0; |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
173 |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
174 public void next(int revisionNumber, int actualLen, int baseRevision, int linkRevision, int parent1Revision, int parent2Revision, byte[] nodeid, DataAccess data) { |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
175 commitRevisions[count++] = linkRevision; |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
176 } |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
177 }; |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
178 content.iterate(start, end, false, insp); |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
179 getRepo().getChangelog().range(inspector, commitRevisions); |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
180 } |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
181 |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
182 // for a given local revision of the file, find out local revision in the changelog |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
183 public int getChangesetLocalRevision(int revision) { |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
184 return content.linkRevision(revision); |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
185 } |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
186 |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
187 public Nodeid getChangesetRevision(Nodeid nid) { |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
188 int changelogRevision = getChangesetLocalRevision(getLocalRevision(nid)); |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
189 return getRepo().getChangelog().getRevision(changelogRevision); |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
190 } |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
191 |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
192 public boolean isCopy() throws HgDataStreamException { |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
193 if (metadata == null || !metadata.checked(0)) { |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
194 // content() always initializes metadata. |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
195 // FIXME this is expensive way to find out metadata, distinct RevlogStream.Iterator would be better. |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
196 // Alternatively, may parameterize MetadataContentPipe to do prepare only. |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
197 // For reference, when throwing CancelledException, hg status -A --rev 3:80 takes 70 ms |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
198 // however, if we just consume buffer instead (buffer.position(buffer.limit()), same command takes ~320ms |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
199 // (compared to command-line counterpart of 190ms) |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
200 try { |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
201 content(0, new ByteChannel() { // No-op channel |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
202 public int write(ByteBuffer buffer) throws IOException, CancelledException { |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
203 // pretend we consumed whole buffer |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
204 // int rv = buffer.remaining(); |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
205 // buffer.position(buffer.limit()); |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
206 // return rv; |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
207 throw new CancelledException(); |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
208 } |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
209 }); |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
210 } catch (CancelledException ex) { |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
211 // it's ok, we did that |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
212 } catch (Exception ex) { |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
213 throw new HgDataStreamException("Can't initialize metadata", ex); |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
214 } |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
215 } |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
216 if (!metadata.known(0)) { |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
217 return false; |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
218 } |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
219 return metadata.find(0, "copy") != null; |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
220 } |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
221 |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
222 public Path getCopySourceName() throws HgDataStreamException { |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
223 if (isCopy()) { |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
224 return Path.create(metadata.find(0, "copy")); |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
225 } |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
226 throw new UnsupportedOperationException(); // XXX REVISIT, think over if Exception is good (clients would check isCopy() anyway, perhaps null is sufficient?) |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
227 } |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
228 |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
229 public Nodeid getCopySourceRevision() throws HgDataStreamException { |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
230 if (isCopy()) { |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
231 return Nodeid.fromAscii(metadata.find(0, "copyrev")); // XXX reuse/cache Nodeid |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
232 } |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
233 throw new UnsupportedOperationException(); |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
234 } |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
235 |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
236 @Override |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
237 public String toString() { |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
238 StringBuilder sb = new StringBuilder(getClass().getSimpleName()); |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
239 sb.append('('); |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
240 sb.append(getPath()); |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
241 sb.append(')'); |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
242 return sb.toString(); |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
243 } |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
244 |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
245 private static final class MetadataEntry { |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
246 private final String entry; |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
247 private final int valueStart; |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
248 /*package-local*/MetadataEntry(String key, String value) { |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
249 entry = key + value; |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
250 valueStart = key.length(); |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
251 } |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
252 /*package-local*/boolean matchKey(String key) { |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
253 return key.length() == valueStart && entry.startsWith(key); |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
254 } |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
255 // uncomment once/if needed |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
256 // public String key() { |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
257 // return entry.substring(0, valueStart); |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
258 // } |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
259 public String value() { |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
260 return entry.substring(valueStart); |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
261 } |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
262 } |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
263 |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
264 private static class Metadata { |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
265 // XXX sparse array needed |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
266 private final TreeMap<Integer, Integer> offsets = new TreeMap<Integer, Integer>(); |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
267 private final TreeMap<Integer, MetadataEntry[]> entries = new TreeMap<Integer, MetadataEntry[]>(); |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
268 |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
269 private final Integer NONE = new Integer(-1); // do not duplicate -1 integers at least within single file (don't want statics) |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
270 |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
271 // true when there's metadata for given revision |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
272 boolean known(int revision) { |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
273 Integer i = offsets.get(revision); |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
274 return i != null && NONE != i; |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
275 } |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
276 |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
277 // true when revision has been checked for metadata presence. |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
278 public boolean checked(int revision) { |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
279 return offsets.containsKey(revision); |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
280 } |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
281 |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
282 // true when revision has been checked and found not having any metadata |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
283 boolean none(int revision) { |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
284 Integer i = offsets.get(revision); |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
285 return i == NONE; |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
286 } |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
287 |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
288 // mark revision as having no metadata. |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
289 void recordNone(int revision) { |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
290 Integer i = offsets.get(revision); |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
291 if (i == NONE) { |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
292 return; // already there |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
293 } |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
294 if (i != null) { |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
295 throw new IllegalStateException(String.format("Trying to override Metadata state for revision %d (known offset: %d)", revision, i)); |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
296 } |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
297 offsets.put(revision, NONE); |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
298 } |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
299 |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
300 // since this is internal class, callers are supposed to ensure arg correctness (i.e. ask known() before) |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
301 int dataOffset(int revision) { |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
302 return offsets.get(revision); |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
303 } |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
304 void add(int revision, int dataOffset, Collection<MetadataEntry> e) { |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
305 assert !offsets.containsKey(revision); |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
306 offsets.put(revision, dataOffset); |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
307 entries.put(revision, e.toArray(new MetadataEntry[e.size()])); |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
308 } |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
309 String find(int revision, String key) { |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
310 for (MetadataEntry me : entries.get(revision)) { |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
311 if (me.matchKey(key)) { |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
312 return me.value(); |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
313 } |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
314 } |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
315 return null; |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
316 } |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
317 } |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
318 |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
319 private static class MetadataContentPipe extends ContentPipe { |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
320 |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
321 private final Metadata metadata; |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
322 |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
323 public MetadataContentPipe(ByteChannel sink, Metadata _metadata) { |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
324 super(sink, 0); |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
325 metadata = _metadata; |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
326 } |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
327 |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
328 @Override |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
329 protected void prepare(int revisionNumber, DataAccess da) throws HgException, IOException { |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
330 final int daLength = da.length(); |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
331 if (daLength < 4 || da.readByte() != 1 || da.readByte() != 10) { |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
332 metadata.recordNone(revisionNumber); |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
333 da.reset(); |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
334 return; |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
335 } |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
336 int lastEntryStart = 2; |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
337 int lastColon = -1; |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
338 ArrayList<MetadataEntry> _metadata = new ArrayList<MetadataEntry>(); |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
339 // XXX in fact, need smth like ByteArrayBuilder, similar to StringBuilder, |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
340 // which can't be used here because we can't convert bytes to chars as we read them |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
341 // (there might be multi-byte encoding), and we need to collect all bytes before converting to string |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
342 ByteArrayOutputStream bos = new ByteArrayOutputStream(); |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
343 String key = null, value = null; |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
344 boolean byteOne = false; |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
345 for (int i = 2; i < daLength; i++) { |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
346 byte b = da.readByte(); |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
347 if (b == '\n') { |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
348 if (byteOne) { // i.e. \n follows 1 |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
349 lastEntryStart = i+1; |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
350 // XXX is it possible to have here incomplete key/value (i.e. if last pair didn't end with \n) |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
351 break; |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
352 } |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
353 if (key == null || lastColon == -1 || i <= lastColon) { |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
354 throw new IllegalStateException(); // FIXME log instead and record null key in the metadata. Ex just to fail fast during dev |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
355 } |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
356 value = new String(bos.toByteArray()).trim(); |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
357 bos.reset(); |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
358 _metadata.add(new MetadataEntry(key, value)); |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
359 key = value = null; |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
360 lastColon = -1; |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
361 lastEntryStart = i+1; |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
362 continue; |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
363 } |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
364 // byteOne has to be consumed up to this line, if not jet, consume it |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
365 if (byteOne) { |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
366 // insert 1 we've read on previous step into the byte builder |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
367 bos.write(1); |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
368 // fall-through to consume current byte |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
369 byteOne = false; |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
370 } |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
371 if (b == (int) ':') { |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
372 assert value == null; |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
373 key = new String(bos.toByteArray()); |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
374 bos.reset(); |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
375 lastColon = i; |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
376 } else if (b == 1) { |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
377 byteOne = true; |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
378 } else { |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
379 bos.write(b); |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
380 } |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
381 } |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
382 _metadata.trimToSize(); |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
383 metadata.add(revisionNumber, lastEntryStart, _metadata); |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
384 if (da.isEmpty() || !byteOne) { |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
385 throw new HgDataStreamException(String.format("Metadata for revision %d is not closed properly", revisionNumber), null); |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
386 } |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
387 // da is in prepared state (i.e. we consumed all bytes up to metadata end). |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
388 } |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
389 } |
6ec4af642ba8
Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff
changeset
|
390 } |