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. import org.eclipse.jgit.util.Equality;

  17. class PackFileSnapshot extends FileSnapshot {

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

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

  32.     private AnyObjectId checksum = MISSING_CHECKSUM;

  33.     private boolean wasChecksumChanged;


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

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

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

  52.     boolean isChecksumChanged(File packFile) {
  53.         return wasChecksumChanged = !Equality.isSameInstance(checksum,
  54.                 MISSING_CHECKSUM)
  55.                 && !checksum.equals(readChecksum(packFile));
  56.     }

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

  67.     boolean wasChecksumChanged() {
  68.         return wasChecksumChanged;
  69.     }

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

  76. }