PackFileSnapshot.java

  1. /*
  2.  * Copyright (C) 2019, Matthias Sohn <matthias.sohn@sap.com> and others
  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.file;

  11. import java.io.File;
  12. import java.io.IOException;
  13. import java.io.RandomAccessFile;

  14. import org.eclipse.jgit.lib.AnyObjectId;
  15. import org.eclipse.jgit.lib.ObjectId;

  16. class PackFileSnapshot extends FileSnapshot {

  17.     private static final ObjectId MISSING_CHECKSUM = ObjectId.zeroId();

  18.     /**
  19.      * Record a snapshot for a specific packfile path.
  20.      * <p>
  21.      * This method should be invoked before the packfile is accessed.
  22.      *
  23.      * @param path
  24.      *            the path to later remember. The path's current status
  25.      *            information is saved.
  26.      * @return the snapshot.
  27.      */
  28.     public static PackFileSnapshot save(File path) {
  29.         return new PackFileSnapshot(path);
  30.     }

  31.     private AnyObjectId checksum = MISSING_CHECKSUM;

  32.     private boolean wasChecksumChanged;


  33.     PackFileSnapshot(File packFile) {
  34.         super(packFile);
  35.     }

  36.     void setChecksum(AnyObjectId checksum) {
  37.         this.checksum = checksum;
  38.     }

  39.     /** {@inheritDoc} */
  40.     @Override
  41.     public boolean isModified(File packFile) {
  42.         if (!super.isModified(packFile)) {
  43.             return false;
  44.         }
  45.         if (wasSizeChanged() || wasFileKeyChanged()
  46.                 || !wasLastModifiedRacilyClean()) {
  47.             return true;
  48.         }
  49.         return isChecksumChanged(packFile);
  50.     }

  51.     boolean isChecksumChanged(File packFile) {
  52.         return wasChecksumChanged = checksum != MISSING_CHECKSUM
  53.                 && !checksum.equals(readChecksum(packFile));
  54.     }

  55.     private AnyObjectId readChecksum(File packFile) {
  56.         try (RandomAccessFile fd = new RandomAccessFile(packFile, "r")) { //$NON-NLS-1$
  57.             fd.seek(fd.length() - 20);
  58.             final byte[] buf = new byte[20];
  59.             fd.readFully(buf, 0, 20);
  60.             return ObjectId.fromRaw(buf);
  61.         } catch (IOException e) {
  62.             return MISSING_CHECKSUM;
  63.         }
  64.     }

  65.     boolean wasChecksumChanged() {
  66.         return wasChecksumChanged;
  67.     }

  68.     @SuppressWarnings("nls")
  69.     @Override
  70.     public String toString() {
  71.         return "PackFileSnapshot [checksum=" + checksum + ", "
  72.                 + super.toString() + "]";
  73.     }

  74. }