1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44 package org.eclipse.jgit.internal.storage.dfs;
45
46 import java.io.IOException;
47 import java.util.Arrays;
48 import java.util.HashSet;
49 import java.util.List;
50 import java.util.Map;
51 import java.util.Set;
52 import java.util.TreeSet;
53 import java.util.concurrent.locks.ReentrantLock;
54
55 import org.eclipse.jgit.annotations.Nullable;
56 import org.eclipse.jgit.internal.storage.reftable.MergedReftable;
57 import org.eclipse.jgit.internal.storage.reftable.ReftableConfig;
58 import org.eclipse.jgit.internal.storage.reftable.ReftableDatabase;
59 import org.eclipse.jgit.lib.BatchRefUpdate;
60 import org.eclipse.jgit.lib.NullProgressMonitor;
61 import org.eclipse.jgit.lib.ObjectId;
62 import org.eclipse.jgit.lib.Ref;
63 import org.eclipse.jgit.revwalk.RevWalk;
64 import org.eclipse.jgit.transport.ReceiveCommand;
65 import org.eclipse.jgit.util.RefList;
66 import org.eclipse.jgit.util.RefMap;
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81 public class DfsReftableDatabase extends DfsRefDatabase {
82 final ReftableDatabase reftableDatabase;
83
84 private DfsReader ctx;
85 private DfsReftableStack stack;
86
87
88
89
90
91
92
93 protected DfsReftableDatabase(DfsRepository repo) {
94 super(repo);
95 reftableDatabase = new ReftableDatabase() {
96 @Override
97 public MergedReftable openMergedReftable() throws IOException {
98 DfsReftableDatabase.this.getLock().lock();
99 try {
100 return new MergedReftable(stack().readers());
101 } finally {
102 DfsReftableDatabase.this.getLock().unlock();
103 }
104 }
105 };
106 stack = null;
107 }
108
109
110 @Override
111 public boolean hasVersioning() {
112 return true;
113 }
114
115
116 @Override
117 public boolean performsAtomicTransactions() {
118 return true;
119 }
120
121
122 @Override
123 public BatchRefUpdate newBatchUpdate() {
124 DfsObjDatabase odb = getRepository().getObjectDatabase();
125 return new DfsReftableBatchRefUpdate(this, odb);
126 }
127
128
129
130
131
132
133 public ReftableConfig getReftableConfig() {
134 return new ReftableConfig(getRepository());
135 }
136
137
138
139
140
141
142 protected ReentrantLock getLock() {
143 return reftableDatabase.getLock();
144 }
145
146
147
148
149
150
151
152
153 protected boolean compactDuringCommit() {
154 return true;
155 }
156
157
158
159
160
161
162
163
164
165 protected DfsReftableStack stack() throws IOException {
166 if (!getLock().isLocked()) {
167 throw new IllegalStateException("most hold lock to access stack");
168 }
169 DfsObjDatabase odb = getRepository().getObjectDatabase();
170
171 if (ctx == null) {
172 ctx = odb.newReader();
173 }
174 if (stack == null) {
175 stack = DfsReftableStack.open(ctx, Arrays.asList(odb.getReftables()));
176 }
177 return stack;
178 }
179
180 @Override
181 public boolean isNameConflicting(String refName) throws IOException {
182 return reftableDatabase.isNameConflicting(refName, new TreeSet<>(), new HashSet<>());
183 }
184
185
186 @Override
187 public Ref exactRef(String name) throws IOException {
188 return reftableDatabase.exactRef(name);
189 }
190
191
192 @Override
193 public Map<String, Ref> getRefs(String prefix) throws IOException {
194 List<Ref> refs = reftableDatabase.getRefsByPrefix(prefix);
195 RefList.Builder<Ref> builder = new RefList.Builder<>(refs.size());
196 for (Ref r : refs) {
197 builder.add(r);
198 }
199 return new RefMap(prefix, builder.toRefList(), RefList.emptyList(),
200 RefList.emptyList());
201 }
202
203
204 @Override
205 public List<Ref> getRefsByPrefix(String prefix) throws IOException {
206
207 return reftableDatabase.getRefsByPrefix(prefix);
208 }
209
210
211 @Override
212 public Set<Ref> getTipsWithSha1(ObjectId id) throws IOException {
213 if (!getReftableConfig().isIndexObjects()) {
214 return super.getTipsWithSha1(id);
215 }
216 return reftableDatabase.getTipsWithSha1(id);
217 }
218
219
220 @Override
221 public boolean hasFastTipsWithSha1() throws IOException {
222 return reftableDatabase.hasFastTipsWithSha1();
223 }
224
225
226 @Override
227 public Ref" href="../../../../../../org/eclipse/jgit/lib/Ref.html#Ref">Ref peel(Ref ref) throws IOException {
228 Ref oldLeaf = ref.getLeaf();
229 if (oldLeaf.isPeeled() || oldLeaf.getObjectId() == null) {
230 return ref;
231 }
232 return recreate(ref, doPeel(oldLeaf), hasVersioning());
233 }
234
235 @Override
236 boolean exists() throws IOException {
237 DfsObjDatabase odb = getRepository().getObjectDatabase();
238 return odb.getReftables().length > 0;
239 }
240
241 @Override
242 void clearCache() {
243 getLock().lock();
244 try {
245 if (ctx != null) {
246 ctx.close();
247 ctx = null;
248 }
249 reftableDatabase.clearCache();
250 if (stack != null) {
251 stack.close();
252 stack = null;
253 }
254 } finally {
255 getLock().unlock();
256 }
257 }
258
259
260 @Override
261 protected boolean compareAndPut(Ref/../../../../org/eclipse/jgit/lib/Ref.html#Ref">Ref oldRef, @Nullable Ref newRef)
262 throws IOException {
263 ReceiveCommand cmd = ReftableDatabase.toCommand(oldRef, newRef);
264 try (RevWalkvwalk/RevWalk.html#RevWalk">RevWalk rw = new RevWalk(getRepository())) {
265 rw.setRetainBody(false);
266 newBatchUpdate().setAllowNonFastForwards(true).addCommand(cmd)
267 .execute(rw, NullProgressMonitor.INSTANCE);
268 }
269 switch (cmd.getResult()) {
270 case OK:
271 return true;
272 case REJECTED_OTHER_REASON:
273 throw new IOException(cmd.getMessage());
274 case LOCK_FAILURE:
275 default:
276 return false;
277 }
278 }
279
280
281 @Override
282 protected boolean compareAndRemove(Ref oldRef) throws IOException {
283 return compareAndPut(oldRef, null);
284 }
285
286
287 @Override
288 protected RefCache scanAllRefs() throws IOException {
289 throw new UnsupportedOperationException();
290 }
291
292 @Override
293 void stored(Ref ref) {
294
295 }
296
297 @Override
298 void removed(String refName) {
299
300 }
301
302
303 @Override
304 protected void cachePeeledState(Refef="../../../../../../org/eclipse/jgit/lib/Ref.html#Ref">Ref oldLeaf, Ref newLeaf) {
305
306 }
307
308 }