1
2
3
4
5
6
7
8
9
10
11 package org.eclipse.jgit.internal.storage.file;
12
13 import java.util.Collections;
14 import java.util.Iterator;
15 import java.util.NoSuchElementException;
16
17 import org.eclipse.jgit.internal.storage.file.BasePackBitmapIndex.StoredBitmap;
18 import org.eclipse.jgit.lib.AnyObjectId;
19 import org.eclipse.jgit.lib.BitmapIndex;
20 import org.eclipse.jgit.lib.ObjectId;
21 import org.eclipse.jgit.lib.ObjectIdOwnerMap;
22
23 import com.googlecode.javaewah.EWAHCompressedBitmap;
24 import com.googlecode.javaewah.IntIterator;
25
26
27
28
29
30
31
32 public class PackBitmapIndexRemapper extends PackBitmapIndex
33 implements Iterable<PackBitmapIndexRemapper.Entry> {
34
35 private final BasePackBitmapIndex oldPackIndex;
36 final PackBitmapIndex newPackIndex;
37 private final ObjectIdOwnerMap<StoredBitmap> convertedBitmaps;
38 private final BitSet inflated;
39 private final int[] prevToNewMapping;
40
41
42
43
44
45
46
47
48
49
50
51 public static PackBitmapIndexRemapper newPackBitmapIndex(
52 BitmapIndex prevBitmapIndex, PackBitmapIndex newIndex) {
53 if (!(prevBitmapIndex instanceof BitmapIndexImpl))
54 return new PackBitmapIndexRemapper(newIndex);
55
56 PackBitmapIndex prevIndex = ((BitmapIndexImpl) prevBitmapIndex)
57 .getPackBitmapIndex();
58 if (!(prevIndex instanceof BasePackBitmapIndex))
59 return new PackBitmapIndexRemapper(newIndex);
60
61 return new PackBitmapIndexRemapper(
62 (BasePackBitmapIndex) prevIndex, newIndex);
63 }
64
65 private PackBitmapIndexRemapper(PackBitmapIndex newPackIndex) {
66 this.oldPackIndex = null;
67 this.newPackIndex = newPackIndex;
68 this.convertedBitmaps = null;
69 this.inflated = null;
70 this.prevToNewMapping = null;
71 }
72
73 private PackBitmapIndexRemapper(
74 BasePackBitmapIndex oldPackIndex, PackBitmapIndex newPackIndex) {
75 this.oldPackIndex = oldPackIndex;
76 this.newPackIndex = newPackIndex;
77 convertedBitmaps = new ObjectIdOwnerMap<>();
78 inflated = new BitSet(newPackIndex.getObjectCount());
79
80 prevToNewMapping = new int[oldPackIndex.getObjectCount()];
81 for (int pos = 0; pos < prevToNewMapping.length; pos++)
82 prevToNewMapping[pos] = newPackIndex.findPosition(
83 oldPackIndex.getObject(pos));
84 }
85
86
87 @Override
88 public int findPosition(AnyObjectId objectId) {
89 return newPackIndex.findPosition(objectId);
90 }
91
92
93 @Override
94 public ObjectId getObject(int position) throws IllegalArgumentException {
95 return newPackIndex.getObject(position);
96 }
97
98
99 @Override
100 public int getObjectCount() {
101 return newPackIndex.getObjectCount();
102 }
103
104
105 @Override
106 public EWAHCompressedBitmap ofObjectType(
107 EWAHCompressedBitmap bitmap, int type) {
108 return newPackIndex.ofObjectType(bitmap, type);
109 }
110
111
112 @Override
113 public Iterator<Entry> iterator() {
114 if (oldPackIndex == null)
115 return Collections.<Entry> emptyList().iterator();
116
117 final Iterator<StoredBitmap> it = oldPackIndex.getBitmaps().iterator();
118 return new Iterator<Entry>() {
119 private Entry entry;
120
121 @Override
122 public boolean hasNext() {
123 while (entry == null && it.hasNext()) {
124 StoredBitmap sb = it.next();
125 if (newPackIndex.findPosition(sb) != -1)
126 entry = new Entry(sb, sb.getFlags());
127 }
128 return entry != null;
129 }
130
131 @Override
132 public Entry next() {
133 if (!hasNext())
134 throw new NoSuchElementException();
135
136 Entry res = entry;
137 entry = null;
138 return res;
139 }
140
141 @Override
142 public void remove() {
143 throw new UnsupportedOperationException();
144 }
145 };
146 }
147
148
149 @Override
150 public EWAHCompressedBitmap getBitmap(AnyObjectId objectId) {
151 EWAHCompressedBitmap bitmap = newPackIndex.getBitmap(objectId);
152 if (bitmap != null || oldPackIndex == null)
153 return bitmap;
154
155 StoredBitmap stored = convertedBitmaps.get(objectId);
156 if (stored != null)
157 return stored.getBitmap();
158
159 StoredBitmap oldBitmap = oldPackIndex.getBitmaps().get(objectId);
160 if (oldBitmap == null)
161 return null;
162
163 if (newPackIndex.findPosition(objectId) == -1)
164 return null;
165
166 inflated.clear();
167 for (IntIterator i = oldBitmap.getBitmap().intIterator(); i.hasNext();)
168 inflated.set(prevToNewMapping[i.next()]);
169 bitmap = inflated.toEWAHCompressedBitmap();
170 bitmap.trim();
171 convertedBitmaps.add(
172 new StoredBitmap(objectId, bitmap, null, oldBitmap.getFlags()));
173 return bitmap;
174 }
175
176
177 public static final class Entry extends ObjectId {
178 private final int flags;
179
180 Entry(AnyObjectId src, int flags) {
181 super(src);
182 this.flags = flags;
183 }
184
185
186 public int getFlags() {
187 return flags;
188 }
189 }
190
191
192 @Override
193 public int getBitmapCount() {
194
195 return 0;
196 }
197 }