View Javadoc
1   /*
2    * Copyright (C) 2012, Google Inc. 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  
11  package org.eclipse.jgit.internal.storage.file;
12  
13  import org.eclipse.jgit.lib.AnyObjectId;
14  import org.eclipse.jgit.lib.ObjectIdOwnerMap;
15  
16  import com.googlecode.javaewah.EWAHCompressedBitmap;
17  
18  /**
19   * Base implementation of the PackBitmapIndex.
20   */
21  abstract class BasePackBitmapIndex extends PackBitmapIndex {
22  	private final ObjectIdOwnerMap<StoredBitmap> bitmaps;
23  
24  	BasePackBitmapIndex(ObjectIdOwnerMap<StoredBitmap> bitmaps) {
25  		this.bitmaps = bitmaps;
26  	}
27  
28  	/** {@inheritDoc} */
29  	@Override
30  	public EWAHCompressedBitmap getBitmap(AnyObjectId objectId) {
31  		StoredBitmap sb = bitmaps.get(objectId);
32  		return sb != null ? sb.getBitmap() : null;
33  	}
34  
35  	ObjectIdOwnerMap<StoredBitmap> getBitmaps() {
36  		return bitmaps;
37  	}
38  
39  	/**
40  	 * Data representation of the bitmap entry restored from a pack index. The
41  	 * commit of the bitmap is the map key.
42  	 */
43  	static final class StoredBitmap extends ObjectIdOwnerMap.Entry {
44  		private volatile Object bitmapContainer;
45  		private final int flags;
46  
47  		StoredBitmap(AnyObjectId objectId, EWAHCompressedBitmap bitmap,
48  				StoredBitmap xorBitmap, int flags) {
49  			super(objectId);
50  			this.bitmapContainer = xorBitmap == null
51  					? bitmap
52  					: new XorCompressedBitmap(bitmap, xorBitmap);
53  			this.flags = flags;
54  		}
55  
56  		/**
57  		 * Computes and returns the full bitmap.
58  		 *
59  		 * @return the full bitmap
60  		 */
61  		EWAHCompressedBitmap getBitmap() {
62  			EWAHCompressedBitmap bitmap = getBitmapWithoutCaching();
63  			// Cache the result.
64  			bitmapContainer = bitmap;
65  			return bitmap;
66  		}
67  
68  		/**
69  		 * Compute and return the full bitmap, do NOT cache the expanded bitmap,
70  		 * which saves memory and should only be used during bitmap creation in
71  		 * garbage collection.
72  		 *
73  		 * @return the full bitmap
74  		 */
75  		EWAHCompressedBitmap getBitmapWithoutCaching() {
76  			// Fast path to immediately return the expanded result.
77  			Object r = bitmapContainer;
78  			if (r instanceof EWAHCompressedBitmap)
79  				return (EWAHCompressedBitmap) r;
80  
81  			// Expand the bitmap but not cache the result.
82  			XorCompressedBitmap xb = (XorCompressedBitmap) r;
83  			EWAHCompressedBitmap out = xb.bitmap;
84  			for (;;) {
85  				r = xb.xorBitmap.bitmapContainer;
86  				if (r instanceof EWAHCompressedBitmap) {
87  					out = out.xor((EWAHCompressedBitmap) r);
88  					out.trim();
89  					return out;
90  				}
91  				xb = (XorCompressedBitmap) r;
92  				out = out.xor(xb.bitmap);
93  			}
94  		}
95  
96  		/** @return the flags associated with the bitmap */
97  		int getFlags() {
98  			return flags;
99  		}
100 	}
101 
102 	private static final class XorCompressedBitmap {
103 		final EWAHCompressedBitmap bitmap;
104 		final StoredBitmap xorBitmap;
105 
106 		XorCompressedBitmap(EWAHCompressedBitmap b, StoredBitmap xb) {
107 			bitmap = b;
108 			xorBitmap = xb;
109 		}
110 	}
111 }