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