/* * Copyright (C) 2012, Google Inc. and others * * 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.internal.storage.file; import org.eclipse.jgit.lib.AnyObjectId; import org.eclipse.jgit.lib.ObjectIdOwnerMap; import com.googlecode.javaewah.EWAHCompressedBitmap; /** * Base implementation of the PackBitmapIndex. */ abstract class BasePackBitmapIndex extends PackBitmapIndex { private final ObjectIdOwnerMap bitmaps; BasePackBitmapIndex(ObjectIdOwnerMap bitmaps) { this.bitmaps = bitmaps; } /** {@inheritDoc} */ @Override public EWAHCompressedBitmap getBitmap(AnyObjectId objectId) { StoredBitmap sb = bitmaps.get(objectId); return sb != null ? sb.getBitmap() : null; } ObjectIdOwnerMap getBitmaps() { return bitmaps; } /** * Data representation of the bitmap entry restored from a pack index. The * commit of the bitmap is the map key. */ static final class StoredBitmap extends ObjectIdOwnerMap.Entry { private volatile Object bitmapContainer; private final int flags; StoredBitmap(AnyObjectId objectId, EWAHCompressedBitmap bitmap, StoredBitmap xorBitmap, int flags) { super(objectId); this.bitmapContainer = xorBitmap == null ? bitmap : new XorCompressedBitmap(bitmap, xorBitmap); this.flags = flags; } /** * Computes and returns the full bitmap. * * @return the full bitmap */ EWAHCompressedBitmap getBitmap() { EWAHCompressedBitmap bitmap = getBitmapWithoutCaching(); // Cache the result. bitmapContainer = bitmap; return bitmap; } /** * Compute and return the full bitmap, do NOT cache the expanded bitmap, * which saves memory and should only be used during bitmap creation in * garbage collection. * * @return the full bitmap */ EWAHCompressedBitmap getBitmapWithoutCaching() { // Fast path to immediately return the expanded result. Object r = bitmapContainer; if (r instanceof EWAHCompressedBitmap) return (EWAHCompressedBitmap) r; // Expand the bitmap but not cache the result. XorCompressedBitmap xb = (XorCompressedBitmap) r; EWAHCompressedBitmap out = xb.bitmap; for (;;) { r = xb.xorBitmap.bitmapContainer; if (r instanceof EWAHCompressedBitmap) { out = out.xor((EWAHCompressedBitmap) r); out.trim(); return out; } xb = (XorCompressedBitmap) r; out = out.xor(xb.bitmap); } } /** @return the flags associated with the bitmap */ int getFlags() { return flags; } } private static final class XorCompressedBitmap { final EWAHCompressedBitmap bitmap; final StoredBitmap xorBitmap; XorCompressedBitmap(EWAHCompressedBitmap b, StoredBitmap xb) { bitmap = b; xorBitmap = xb; } } }