PageRenderTime 36ms CodeModel.GetById 10ms RepoModel.GetById 0ms app.codeStats 0ms

/hgkit-src/org/freehg/hgkit/core/RevlogEntry.java

https://code.google.com/p/crystalvc/
Java | 270 lines | 114 code | 40 blank | 116 comment | 8 complexity | a4b51cb1390a8adb0ad5d88eaba49abe MD5 | raw file
  1. /**
  2. *
  3. */
  4. package org.freehg.hgkit.core;
  5. import java.io.ByteArrayInputStream;
  6. import java.io.DataInputStream;
  7. import java.io.IOException;
  8. import java.io.RandomAccessFile;
  9. import org.freehg.hgkit.HgInternalError;
  10. /**
  11. * Describes a single entry of the {@link Revlog}.
  12. *
  13. * @see <a
  14. * href="http://www.selenic.com/mercurial/wiki/index.cgi/RevlogNG">RevlogNG</a>
  15. * @see <a
  16. * href="http://www.selenic.com/mercurial/wiki/index.cgi/Revlog">Revlog</a>
  17. */
  18. public final class RevlogEntry {
  19. /**
  20. *
  21. */
  22. private static final int NODE_ID_SIZE = 32;
  23. /** The corresponding length of indexformatng (python) >Qiiiiii20s12x. */
  24. public static final int BINARY_LENGTH = 64;
  25. public static RevlogEntry nullInstance = valueOf(null, new byte[BINARY_LENGTH], 0);
  26. private final Revlog parent;
  27. private final long offset;
  28. private final int flags;
  29. private final long compressedLength;
  30. private final long uncompressedLength;
  31. private final int baseRev;
  32. private final int linkRev;
  33. private final int firstParentRev;
  34. private final int secondParentRev;
  35. final NodeId nodeId;
  36. int revision;
  37. /**
  38. * Initializes a RevlogEntry from the given {@link DataInputStream}.
  39. *
  40. * @param parent
  41. * revlog
  42. * @param reader
  43. * dataInputStream
  44. * @param off
  45. *
  46. * @throws HgInternalError
  47. * if an {@link IOException} is thrown while reading.
  48. */
  49. RevlogEntry(Revlog parent, DataInputStream reader, int off) throws HgInternalError {
  50. this.parent = parent;
  51. try {
  52. final long offsetFromReader = ((long) reader.readShort() << 32) + reader.readInt();
  53. // the first revlog entry (starting with offset 0) contains
  54. // information about
  55. // the revlog and not the actual offset (see bottom of
  56. // RevlogNG-page).
  57. offset = off == 0 ? 0 : offsetFromReader;
  58. flags = reader.readShort();
  59. compressedLength = reader.readInt();
  60. uncompressedLength = reader.readInt();
  61. baseRev = reader.readInt();
  62. linkRev = reader.readInt();
  63. firstParentRev = reader.readInt();
  64. secondParentRev = reader.readInt();
  65. byte[] nodeid = new byte[NODE_ID_SIZE];
  66. final int read = reader.read(nodeid);
  67. assert read == NODE_ID_SIZE;
  68. nodeId = NodeId.valueOf(nodeid);
  69. } catch (IOException e) {
  70. throw new HgInternalError(parent.toString(), e);
  71. }
  72. }
  73. /**
  74. * Creates a specific RevlogEntry.
  75. *
  76. * @param parent
  77. * revlog
  78. * @param data
  79. * data
  80. * @param off
  81. * where in data to begin extracting data
  82. *
  83. * @return revlogEntry
  84. */
  85. public static RevlogEntry valueOf(Revlog parent, byte[] data, int off) throws HgInternalError {
  86. ByteArrayInputStream copy = new ByteArrayInputStream(data, off, BINARY_LENGTH);
  87. DataInputStream reader = new DataInputStream(copy);
  88. RevlogEntry entry = new RevlogEntry(parent, reader, off);
  89. return entry;
  90. }
  91. /**
  92. * Returns the base revision. The first revision going backwards from the
  93. * tip that has two parents (the product of a merge).
  94. *
  95. * @see <a
  96. * href="http://www.selenic.com/mercurial/wiki/index.cgi/WireProtocol">WireProtocol</a>
  97. *
  98. * @return baseRev
  99. */
  100. public int getBaseRev() {
  101. return baseRev;
  102. }
  103. /**
  104. * Returns the link revision of the {@link RevlogEntry}, that is a link to
  105. * the revision in the Revlog.
  106. *
  107. * @return linkRev
  108. */
  109. public int getLinkRev() {
  110. return linkRev;
  111. }
  112. /**
  113. * Loads a block as a byte array from a file. In RevlogNG data may be
  114. * inlined.
  115. *
  116. * @param file
  117. * to read from
  118. * @return byte array
  119. * @throws IOException
  120. * might occur if we can not read from file
  121. */
  122. public byte[] loadBlock(RandomAccessFile file) throws IOException {
  123. long off = this.offset;
  124. if (parent.isDataInline) {
  125. off += (revision + 1L) * RevlogEntry.BINARY_LENGTH;
  126. }
  127. file.seek(off);
  128. return read(file);
  129. }
  130. /**
  131. * Reads compressed data from the Revlog.
  132. *
  133. * @param file
  134. * to read from
  135. * @return data array
  136. * @throws IOException
  137. */
  138. private byte[] read(RandomAccessFile file) throws IOException {
  139. byte[] data = new byte[(int) this.compressedLength];
  140. int read = file.read(data);
  141. assert read == (int) this.compressedLength;
  142. return data;
  143. }
  144. /**
  145. * Returns the offset of the entry in the Revlog.
  146. *
  147. * @return offset
  148. */
  149. public long getOffset() {
  150. return offset;
  151. }
  152. /**
  153. * Returns uncompressed length of data.
  154. *
  155. * @return uncompressed length
  156. */
  157. long getUncompressedLength() {
  158. return uncompressedLength;
  159. }
  160. /**
  161. * Returns compressed length of data.
  162. *
  163. * @return compressed length
  164. */
  165. long getCompressedLength() {
  166. return compressedLength;
  167. }
  168. /** {@inheritDoc} */
  169. @Override
  170. public String toString() {
  171. RevlogEntry p1 = getNullEntry();
  172. RevlogEntry p2 = getNullEntry();
  173. if (0 <= firstParentRev) {
  174. p1 = parent.index.get(firstParentRev);
  175. }
  176. if (0 <= secondParentRev) {
  177. p2 = parent.index.get(secondParentRev);
  178. }
  179. return revision + " " + offset + " " + compressedLength + " "
  180. // + uncompressedLength + " "
  181. + baseRev + " " + linkRev + " " + nodeId.asShort() + " " + p1.nodeId.asShort() + " "
  182. + p2.nodeId.asShort();
  183. }
  184. /**
  185. * Returns the null entry.
  186. *
  187. * @return null entry
  188. */
  189. static RevlogEntry getNullEntry() {
  190. return nullInstance;
  191. }
  192. /**
  193. * Returns the nodeId of the {@link RevlogEntry}.
  194. *
  195. * @return nodeId
  196. */
  197. public NodeId getId() {
  198. return nodeId;
  199. }
  200. /**
  201. * Returns the flags of the {@link RevlogEntry}.
  202. *
  203. * @return flags
  204. */
  205. public int getFlags() {
  206. return flags;
  207. }
  208. /**
  209. * rtholmes: added method
  210. * @return
  211. */
  212. public RevlogEntry getFirstParent() {
  213. RevlogEntry p1 = getNullEntry();
  214. if (0 <= firstParentRev) {
  215. p1 = parent.index.get(firstParentRev);
  216. }
  217. return p1;
  218. }
  219. /**
  220. * rtholmes: added method
  221. * @return
  222. */
  223. public RevlogEntry getSecondParent() {
  224. RevlogEntry p2 = getNullEntry();
  225. if (0 <= secondParentRev) {
  226. p2 = parent.index.get(secondParentRev);
  227. }
  228. return p2;
  229. }
  230. }