You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

PackBitmapIndexRemapper.java 5.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. /*
  2. * Copyright (C) 2013, 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. package org.eclipse.jgit.internal.storage.file;
  11. import java.util.Collections;
  12. import java.util.Iterator;
  13. import java.util.NoSuchElementException;
  14. import org.eclipse.jgit.internal.storage.file.BasePackBitmapIndex.StoredBitmap;
  15. import org.eclipse.jgit.lib.AnyObjectId;
  16. import org.eclipse.jgit.lib.BitmapIndex;
  17. import org.eclipse.jgit.lib.ObjectId;
  18. import com.googlecode.javaewah.EWAHCompressedBitmap;
  19. import com.googlecode.javaewah.IntIterator;
  20. /**
  21. * A PackBitmapIndex that remaps the bitmaps in the previous index to the
  22. * positions in the new pack index. Note, unlike typical PackBitmapIndex
  23. * implementations this implementation is not thread safe, as it is intended to
  24. * be used with a PackBitmapIndexBuilder, which is also not thread safe.
  25. */
  26. public class PackBitmapIndexRemapper extends PackBitmapIndex
  27. implements Iterable<PackBitmapIndexRemapper.Entry> {
  28. private final BasePackBitmapIndex oldPackIndex;
  29. final PackBitmapIndex newPackIndex;
  30. private final BitSet inflated;
  31. private final int[] prevToNewMapping;
  32. /**
  33. * A PackBitmapIndex that maps the positions in the prevBitmapIndex to the
  34. * ones in the newIndex.
  35. *
  36. * @param prevBitmapIndex
  37. * the bitmap index with the old mapping.
  38. * @param newIndex
  39. * the bitmap index with the new mapping.
  40. * @return a bitmap index that attempts to do the mapping between the two.
  41. */
  42. public static PackBitmapIndexRemapper newPackBitmapIndex(
  43. BitmapIndex prevBitmapIndex, PackBitmapIndex newIndex) {
  44. if (!(prevBitmapIndex instanceof BitmapIndexImpl))
  45. return new PackBitmapIndexRemapper(newIndex);
  46. PackBitmapIndex prevIndex = ((BitmapIndexImpl) prevBitmapIndex)
  47. .getPackBitmapIndex();
  48. if (!(prevIndex instanceof BasePackBitmapIndex))
  49. return new PackBitmapIndexRemapper(newIndex);
  50. return new PackBitmapIndexRemapper(
  51. (BasePackBitmapIndex) prevIndex, newIndex);
  52. }
  53. private PackBitmapIndexRemapper(PackBitmapIndex newPackIndex) {
  54. this.oldPackIndex = null;
  55. this.newPackIndex = newPackIndex;
  56. this.inflated = null;
  57. this.prevToNewMapping = null;
  58. }
  59. private PackBitmapIndexRemapper(
  60. BasePackBitmapIndex oldPackIndex, PackBitmapIndex newPackIndex) {
  61. this.oldPackIndex = oldPackIndex;
  62. this.newPackIndex = newPackIndex;
  63. inflated = new BitSet(newPackIndex.getObjectCount());
  64. prevToNewMapping = new int[oldPackIndex.getObjectCount()];
  65. for (int pos = 0; pos < prevToNewMapping.length; pos++)
  66. prevToNewMapping[pos] = newPackIndex.findPosition(
  67. oldPackIndex.getObject(pos));
  68. }
  69. /** {@inheritDoc} */
  70. @Override
  71. public int findPosition(AnyObjectId objectId) {
  72. return newPackIndex.findPosition(objectId);
  73. }
  74. /** {@inheritDoc} */
  75. @Override
  76. public ObjectId getObject(int position) throws IllegalArgumentException {
  77. return newPackIndex.getObject(position);
  78. }
  79. /** {@inheritDoc} */
  80. @Override
  81. public int getObjectCount() {
  82. return newPackIndex.getObjectCount();
  83. }
  84. /** {@inheritDoc} */
  85. @Override
  86. public EWAHCompressedBitmap ofObjectType(
  87. EWAHCompressedBitmap bitmap, int type) {
  88. return newPackIndex.ofObjectType(bitmap, type);
  89. }
  90. /** {@inheritDoc} */
  91. @Override
  92. public Iterator<Entry> iterator() {
  93. if (oldPackIndex == null)
  94. return Collections.<Entry> emptyList().iterator();
  95. final Iterator<StoredBitmap> it = oldPackIndex.getBitmaps().iterator();
  96. return new Iterator<Entry>() {
  97. private Entry entry;
  98. @Override
  99. public boolean hasNext() {
  100. while (entry == null && it.hasNext()) {
  101. StoredBitmap sb = it.next();
  102. if (newPackIndex.findPosition(sb) != -1)
  103. entry = new Entry(sb, sb.getFlags());
  104. }
  105. return entry != null;
  106. }
  107. @Override
  108. public Entry next() {
  109. if (!hasNext())
  110. throw new NoSuchElementException();
  111. Entry res = entry;
  112. entry = null;
  113. return res;
  114. }
  115. @Override
  116. public void remove() {
  117. throw new UnsupportedOperationException();
  118. }
  119. };
  120. }
  121. /** {@inheritDoc} */
  122. @Override
  123. public EWAHCompressedBitmap getBitmap(AnyObjectId objectId) {
  124. EWAHCompressedBitmap bitmap = newPackIndex.getBitmap(objectId);
  125. if (bitmap != null || oldPackIndex == null)
  126. return bitmap;
  127. StoredBitmap oldBitmap = oldPackIndex.getBitmaps().get(objectId);
  128. if (oldBitmap == null)
  129. return null;
  130. if (newPackIndex.findPosition(objectId) == -1)
  131. return null;
  132. inflated.clear();
  133. for (IntIterator i = oldBitmap.getBitmapWithoutCaching()
  134. .intIterator(); i.hasNext();)
  135. inflated.set(prevToNewMapping[i.next()]);
  136. bitmap = inflated.toEWAHCompressedBitmap();
  137. bitmap.trim();
  138. return bitmap;
  139. }
  140. /** An entry in the old PackBitmapIndex. */
  141. public static final class Entry extends ObjectId {
  142. private final int flags;
  143. Entry(AnyObjectId src, int flags) {
  144. super(src);
  145. this.flags = flags;
  146. }
  147. /** @return the flags associated with the bitmap. */
  148. public int getFlags() {
  149. return flags;
  150. }
  151. }
  152. /** {@inheritDoc} */
  153. @Override
  154. public int getBitmapCount() {
  155. // The count is only useful for the end index, not the remapper.
  156. return 0;
  157. }
  158. }