Mercurial > hg4j
comparison src/com/tmate/hgkit/ll/RevlogStream.java @ 22:603806cd2dc6
Status of local working dir against non-tip base revision
| author | Artem Tikhomirov <tikhomirov.artem@gmail.com> |
|---|---|
| date | Thu, 06 Jan 2011 03:30:20 +0100 |
| parents | 382cfe9463db |
| children | d4fdd1845b3f |
comparison
equal
deleted
inserted
replaced
| 21:e929cecae4e1 | 22:603806cd2dc6 |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright (c) 2010 Artem Tikhomirov | 2 * Copyright (c) 2010, 2011 Artem Tikhomirov |
| 3 */ | 3 */ |
| 4 package com.tmate.hgkit.ll; | 4 package com.tmate.hgkit.ll; |
| 5 | 5 |
| 6 import static com.tmate.hgkit.ll.HgRepository.TIP; | 6 import static com.tmate.hgkit.ll.HgRepository.TIP; |
| 7 | 7 |
| 49 | 49 |
| 50 public int revisionCount() { | 50 public int revisionCount() { |
| 51 initOutline(); | 51 initOutline(); |
| 52 return index.size(); | 52 return index.size(); |
| 53 } | 53 } |
| 54 | |
| 55 public int dataLength(int revision) { | |
| 56 // XXX in fact, use of iterate() instead of this implementation may be quite reasonable. | |
| 57 // | |
| 58 final int indexSize = revisionCount(); | |
| 59 DataAccess daIndex = getIndexStream(); // XXX may supply a hint that I'll need really few bytes of data (although at some offset) | |
| 60 if (revision == TIP) { | |
| 61 revision = indexSize - 1; | |
| 62 } | |
| 63 try { | |
| 64 int recordOffset = inline ? (int) index.get(revision).offset : revision * REVLOGV1_RECORD_SIZE; | |
| 65 daIndex.seek(recordOffset + 12); // 6+2+4 | |
| 66 int actualLen = daIndex.readInt(); | |
| 67 return actualLen; | |
| 68 } catch (IOException ex) { | |
| 69 ex.printStackTrace(); // log error. FIXME better handling | |
| 70 throw new IllegalStateException(ex); | |
| 71 } finally { | |
| 72 daIndex.done(); | |
| 73 } | |
| 74 } | |
| 75 | |
| 76 public int findLocalRevisionNumber(Nodeid nodeid) { | |
| 77 // XXX this one may be implemented with iterate() once there's mechanism to stop iterations | |
| 78 final int indexSize = revisionCount(); | |
| 79 DataAccess daIndex = getIndexStream(); | |
| 80 try { | |
| 81 for (int i = 0; i < indexSize; i++) { | |
| 82 daIndex.skip(8); | |
| 83 int compressedLen = daIndex.readInt(); | |
| 84 daIndex.skip(20); | |
| 85 byte[] buf = new byte[20]; | |
| 86 daIndex.readBytes(buf, 0, 20); | |
| 87 if (nodeid.equalsTo(buf)) { | |
| 88 return i; | |
| 89 } | |
| 90 daIndex.skip(inline ? 12 + compressedLen : 12); | |
| 91 } | |
| 92 } catch (IOException ex) { | |
| 93 ex.printStackTrace(); // log error. FIXME better handling | |
| 94 throw new IllegalStateException(ex); | |
| 95 } finally { | |
| 96 daIndex.done(); | |
| 97 } | |
| 98 throw new IllegalArgumentException(String.format("%s doesn't represent a revision of %s", nodeid.toString(), indexFile.getName() /*XXX HgDataFile.getPath might be more suitable here*/)); | |
| 99 } | |
| 100 | |
| 54 | 101 |
| 55 private final int REVLOGV1_RECORD_SIZE = 64; | 102 private final int REVLOGV1_RECORD_SIZE = 64; |
| 56 | 103 |
| 57 // should be possible to use TIP, ALL, or -1, -2, -n notation of Hg | 104 // should be possible to use TIP, ALL, or -1, -2, -n notation of Hg |
| 58 // ? boolean needsNodeid | 105 // ? boolean needsNodeid |
| 90 extraReadsToBaseRev = true; | 137 extraReadsToBaseRev = true; |
| 91 } else { | 138 } else { |
| 92 i = start; | 139 i = start; |
| 93 } | 140 } |
| 94 | 141 |
| 95 daIndex.seek(inline ? (int) index.get(i).offset : start * REVLOGV1_RECORD_SIZE); | 142 daIndex.seek(inline ? (int) index.get(i).offset : i * REVLOGV1_RECORD_SIZE); |
| 96 for (; i <= end; i++ ) { | 143 for (; i <= end; i++ ) { |
| 97 long l = daIndex.readLong(); | 144 long l = daIndex.readLong(); |
| 98 long offset = l >>> 16; | 145 long offset = l >>> 16; |
| 99 int flags = (int) (l & 0X0FFFF); | 146 int flags = (int) (l & 0X0FFFF); |
| 100 int compressedLen = daIndex.readInt(); | 147 int compressedLen = daIndex.readInt(); |
| 203 res.add(new IndexEntry(offset, baseRevision)); | 250 res.add(new IndexEntry(offset, baseRevision)); |
| 204 da.skip(3*4 + 32); | 251 da.skip(3*4 + 32); |
| 205 } | 252 } |
| 206 if (da.isEmpty()) { | 253 if (da.isEmpty()) { |
| 207 // fine, done then | 254 // fine, done then |
| 255 res.trimToSize(); | |
| 208 index = res; | 256 index = res; |
| 209 break; | 257 break; |
| 210 } else { | 258 } else { |
| 211 // start reading next record | 259 // start reading next record |
| 212 long l = da.readLong(); | 260 long l = da.readLong(); |
