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();