You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

CommitGraphOutPutStream.java 2.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. /*
  2. * Copyright (C) 2021, Tencent.
  3. *
  4. * This program and the accompanying materials are made available under the
  5. * terms of the Eclipse Distribution License v. 1.0 which is available at
  6. * https://www.eclipse.org/org/documents/edl-v10.php.
  7. *
  8. * SPDX-License-Identifier: BSD-3-Clause
  9. */
  10. package org.eclipse.jgit.internal.storage.commitgraph;
  11. import static org.eclipse.jgit.internal.storage.commitgraph.CommitGraphConstants.COMMIT_GRAPH_MAGIC;
  12. import java.io.IOException;
  13. import java.io.OutputStream;
  14. import java.security.MessageDigest;
  15. import org.eclipse.jgit.internal.JGitText;
  16. import org.eclipse.jgit.lib.Constants;
  17. import org.eclipse.jgit.lib.ProgressMonitor;
  18. import org.eclipse.jgit.util.NB;
  19. /**
  20. * Custom output stream to support
  21. * {@link org.eclipse.jgit.internal.storage.commitgraph.CommitGraphWriter}.
  22. */
  23. public class CommitGraphOutPutStream extends OutputStream {
  24. private static final int BYTES_TO_WRITE_BEFORE_CANCEL_CHECK = 128 * 1024;
  25. private final ProgressMonitor writeMonitor;
  26. private final OutputStream out;
  27. private final MessageDigest md = Constants.newMessageDigest();
  28. private long count;
  29. private long checkCancelAt;
  30. private final byte[] headerBuffer = new byte[16];
  31. /**
  32. * Initialize a commit-graph output stream.
  33. *
  34. * @param writeMonitor
  35. * monitor to update on output progress.
  36. * @param out
  37. * target stream to receive all contents.
  38. */
  39. public CommitGraphOutPutStream(ProgressMonitor writeMonitor,
  40. OutputStream out) {
  41. this.writeMonitor = writeMonitor;
  42. this.out = out;
  43. this.checkCancelAt = BYTES_TO_WRITE_BEFORE_CANCEL_CHECK;
  44. }
  45. /** {@inheritDoc} */
  46. @Override
  47. public final void write(int b) throws IOException {
  48. count++;
  49. out.write(b);
  50. md.update((byte) b);
  51. }
  52. /** {@inheritDoc} */
  53. @Override
  54. public final void write(byte[] b, int off, int len) throws IOException {
  55. while (0 < len) {
  56. int n = Math.min(len, BYTES_TO_WRITE_BEFORE_CANCEL_CHECK);
  57. count += n;
  58. if (checkCancelAt <= count) {
  59. if (writeMonitor.isCancelled()) {
  60. throw new IOException(JGitText
  61. .get().commitGraphGeneratingCancelledDuringWriting);
  62. }
  63. checkCancelAt = count + BYTES_TO_WRITE_BEFORE_CANCEL_CHECK;
  64. }
  65. out.write(b, off, n);
  66. md.update(b, off, n);
  67. off += n;
  68. len -= n;
  69. }
  70. }
  71. /** {@inheritDoc} */
  72. @Override
  73. public void flush() throws IOException {
  74. out.flush();
  75. }
  76. void writeFileHeader(int version, int hashVersion, int chunksNumber)
  77. throws IOException {
  78. NB.encodeInt32(headerBuffer, 0, COMMIT_GRAPH_MAGIC);
  79. byte[] buff = { (byte) version, (byte) hashVersion, (byte) chunksNumber,
  80. (byte) 0 };
  81. System.arraycopy(buff, 0, headerBuffer, 4, 4);
  82. write(headerBuffer, 0, 8);
  83. }
  84. /** @return obtain the current SHA-1 digest. */
  85. byte[] getDigest() {
  86. return md.digest();
  87. }
  88. void updateMonitor() {
  89. writeMonitor.update(1);
  90. }
  91. }