| /* |
| * Copyright (C) 2023, Google LLC |
| * |
| * This program and the accompanying materials are made available under the |
| * terms of the Eclipse Distribution License v. 1.0 which is available at |
| * https://www.eclipse.org/org/documents/edl-v10.php. |
| * |
| * SPDX-License-Identifier: BSD-3-Clause |
| */ |
| |
| package org.eclipse.jgit.pgm.debug; |
| |
| import java.io.FileInputStream; |
| import java.util.HashSet; |
| |
| import org.eclipse.jgit.pgm.Command; |
| import org.eclipse.jgit.pgm.TextBuiltin; |
| import org.eclipse.jgit.util.NB; |
| import org.kohsuke.args4j.Argument; |
| |
| /** |
| * Prints the contents of the BDAT chunk from commit-graph file. |
| * <p> |
| * This is a debugging tool for changed path filter development. |
| */ |
| @Command |
| class ReadChangedPathFilter extends TextBuiltin { |
| |
| static final int CHUNK_ID_OID_FANOUT = 0x4f494446; /* "OIDF" */ |
| |
| static final int CHUNK_ID_BLOOM_FILTER_INDEX = 0x42494458; /* "BIDX" */ |
| |
| static final int CHUNK_ID_BLOOM_FILTER_DATA = 0x42444154; /* "BDAT" */ |
| |
| @Argument(index = 0) |
| private String input; |
| |
| static HashSet<String> changedPathStrings(byte[] data) { |
| int oidf_offset = -1; |
| int bidx_offset = -1; |
| int bdat_offset = -1; |
| for (int i = 8; i < data.length - 4; i += 12) { |
| switch (NB.decodeInt32(data, i)) { |
| case CHUNK_ID_OID_FANOUT: |
| oidf_offset = (int) NB.decodeInt64(data, i + 4); |
| break; |
| case CHUNK_ID_BLOOM_FILTER_INDEX: |
| bidx_offset = (int) NB.decodeInt64(data, i + 4); |
| break; |
| case CHUNK_ID_BLOOM_FILTER_DATA: |
| bdat_offset = (int) NB.decodeInt64(data, i + 4); |
| break; |
| } |
| } |
| bdat_offset += 12; // skip version, hash count, bits per entry |
| int commit_count = NB.decodeInt32(data, oidf_offset + 255 * 4); |
| int[] changed_path_length_cumuls = new int[commit_count]; |
| for (int i = 0; i < commit_count; i++) { |
| changed_path_length_cumuls[i] = NB.decodeInt32(data, |
| bidx_offset + i * 4); |
| } |
| HashSet<String> changed_paths = new HashSet<>(); |
| for (int i = 0; i < commit_count; i++) { |
| int prior_cumul = i == 0 ? 0 : changed_path_length_cumuls[i - 1]; |
| String changed_path = ""; //$NON-NLS-1$ |
| for (int j = prior_cumul; j < changed_path_length_cumuls[i]; j++) { |
| changed_path += data[bdat_offset + j] + ","; //$NON-NLS-1$ |
| } |
| changed_paths.add(changed_path); |
| } |
| return changed_paths; |
| } |
| |
| /** {@inheritDoc} */ |
| @Override |
| protected void run() throws Exception { |
| try (FileInputStream in = new FileInputStream(input) |
| ) { |
| byte[] data = in.readAllBytes(); |
| outw.println(changedPathStrings(data).toString()); |
| } |
| } |
| } |