LCOV - code coverage report
Current view: top level - server/patch/filediff - FileSizeEvaluator.java (source / functions) Hit Total Coverage
Test: _coverage_report.dat Lines: 16 26 61.5 %
Date: 2022-11-19 15:00:39 Functions: 4 6 66.7 %

          Line data    Source code
       1             : // Copyright (C) 2020 The Android Open Source Project
       2             : //
       3             : // Licensed under the Apache License, Version 2.0 (the "License");
       4             : // you may not use this file except in compliance with the License.
       5             : // You may obtain a copy of the License at
       6             : //
       7             : // http://www.apache.org/licenses/LICENSE-2.0
       8             : //
       9             : // Unless required by applicable law or agreed to in writing, software
      10             : // distributed under the License is distributed on an "AS IS" BASIS,
      11             : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      12             : // See the License for the specific language governing permissions and
      13             : // limitations under the License.
      14             : 
      15             : package com.google.gerrit.server.patch.filediff;
      16             : 
      17             : import static org.eclipse.jgit.lib.Constants.OBJ_BLOB;
      18             : 
      19             : import com.google.common.collect.Iterables;
      20             : import com.google.gerrit.common.Nullable;
      21             : import com.google.gerrit.entities.Patch;
      22             : import com.google.gerrit.entities.Patch.FileMode;
      23             : import com.google.gerrit.exceptions.StorageException;
      24             : import java.io.IOException;
      25             : import java.util.Collection;
      26             : import java.util.Optional;
      27             : import org.eclipse.jgit.lib.AbbreviatedObjectId;
      28             : import org.eclipse.jgit.lib.ObjectId;
      29             : import org.eclipse.jgit.lib.ObjectReader;
      30             : import org.eclipse.jgit.revwalk.RevTree;
      31             : import org.eclipse.jgit.treewalk.TreeWalk;
      32             : 
      33             : /** Helper class for computing the size of a file in a given git tree. */
      34             : class FileSizeEvaluator {
      35             :   private final ObjectReader reader;
      36             :   private final RevTree tree;
      37             : 
      38          93 :   FileSizeEvaluator(ObjectReader reader, RevTree tree) {
      39          93 :     this.reader = reader;
      40          93 :     this.tree = tree;
      41          93 :   }
      42             : 
      43             :   /**
      44             :    * Computes the file size identified by the {@code path} parameter at the given git tree
      45             :    * identified by {@code gitTreeId}.
      46             :    */
      47             :   long compute(AbbreviatedObjectId gitTreeId, Patch.FileMode mode, String path) throws IOException {
      48          93 :     if (!isBlob(mode)) {
      49           4 :       return 0;
      50             :     }
      51          93 :     ObjectId fileId =
      52          93 :         toObjectId(reader, gitTreeId).orElseGet(() -> lookupObjectId(reader, path, tree));
      53          93 :     if (ObjectId.zeroId().equals(fileId)) {
      54           0 :       return 0;
      55             :     }
      56          93 :     return reader.getObjectSize(fileId, OBJ_BLOB);
      57             :   }
      58             : 
      59             :   private static ObjectId lookupObjectId(ObjectReader reader, String path, RevTree tree) {
      60             :     // This variant is very expensive.
      61           0 :     try (TreeWalk treeWalk = TreeWalk.forPath(reader, path, tree)) {
      62           0 :       return treeWalk != null ? treeWalk.getObjectId(0) : ObjectId.zeroId();
      63           0 :     } catch (IOException e) {
      64           0 :       throw new StorageException(e);
      65             :     }
      66             :   }
      67             : 
      68             :   private static Optional<ObjectId> toObjectId(
      69             :       ObjectReader reader, @Nullable AbbreviatedObjectId abbreviatedId) throws IOException {
      70          93 :     if (abbreviatedId == null) {
      71             :       // In theory, DiffEntry#getOldId or DiffEntry#getNewId can be null for pure renames or pure
      72             :       // mode changes (e.g. DiffEntry#modify doesn't set the IDs). However, the method we call for
      73             :       // diffs (DiffFormatter#scan) seems to always produce DiffEntries with set IDs, even for pure
      74             :       // renames.
      75           0 :       return Optional.empty();
      76             :     }
      77          93 :     if (abbreviatedId.isComplete()) {
      78             :       // With the current JGit version and the method we call for diffs (DiffFormatter#scan),
      79             :       // this
      80             :       // is the only code path taken right now.
      81          93 :       return Optional.ofNullable(abbreviatedId.toObjectId());
      82             :     }
      83           0 :     Collection<ObjectId> objectIds = reader.resolve(abbreviatedId);
      84             :     // It seems very unlikely that an ObjectId which was just abbreviated by the diff
      85             :     // computation
      86             :     // now can't be resolved to exactly one ObjectId. The API allows this possibility, though.
      87           0 :     return objectIds.size() == 1
      88           0 :         ? Optional.of(Iterables.getOnlyElement(objectIds))
      89           0 :         : Optional.empty();
      90             :   }
      91             : 
      92             :   private static boolean isBlob(Patch.FileMode mode) {
      93          93 :     return mode.equals(FileMode.REGULAR_FILE)
      94           6 :         || mode.equals(FileMode.EXECUTABLE_FILE)
      95          93 :         || mode.equals(FileMode.SYMLINK);
      96             :   }
      97             : }

Generated by: LCOV version 1.16+git.20220603.dfeb750