Adapt to stricter Eclipse error checking
[egit.git] / org.spearce.egit.core / src / org / spearce / egit / core / project / CheckpointJob.java
blob6150724bd460c7c88d58ecc0a8524416a2d02c84
1 /*
2 * Copyright (C) 2006 Shawn Pearce <spearce@spearce.org>
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License, version 2.1, as published by the Free Software Foundation.
8 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * Lesser General Public License for more details.
13 * You should have received a copy of the GNU Lesser General Public
14 * License along with this library; if not, write to the Free Software
15 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
17 package org.spearce.egit.core.project;
19 import java.io.File;
20 import java.io.IOException;
21 import java.util.ArrayList;
22 import java.util.Collection;
23 import java.util.HashSet;
24 import java.util.Iterator;
25 import java.util.LinkedHashMap;
26 import java.util.Map;
27 import java.util.Set;
29 import org.eclipse.core.runtime.IProgressMonitor;
30 import org.eclipse.core.runtime.IStatus;
31 import org.eclipse.core.runtime.NullProgressMonitor;
32 import org.eclipse.core.runtime.Status;
33 import org.eclipse.core.runtime.jobs.ISchedulingRule;
34 import org.eclipse.core.runtime.jobs.Job;
35 import org.eclipse.core.runtime.jobs.MultiRule;
36 import org.eclipse.osgi.util.NLS;
37 import org.spearce.egit.core.Activator;
38 import org.spearce.egit.core.CoreText;
39 import org.spearce.jgit.lib.FileTreeEntry;
40 import org.spearce.jgit.lib.ObjectWriter;
41 import org.spearce.jgit.lib.Tree;
42 import org.spearce.jgit.lib.TreeEntry;
44 public class CheckpointJob extends Job {
45 private static final Object EXISTS = new Object();
47 private static final int MB = 1024 * 1024;
49 private final Set blobQueue;
51 private final Collection blobRules;
53 private final Map treeQueue;
55 private final ObjectWriter ow;
57 private final RepositoryMapping rm;
59 private long byteCnt;
61 private int objectCnt;
63 public CheckpointJob(final RepositoryMapping m) {
64 super(NLS.bind(CoreText.CheckpointJob_name, m.getContainer()
65 .getFullPath()));
66 setPriority(Job.LONG);
68 blobQueue = new HashSet();
69 blobRules = new ArrayList();
70 treeQueue = new LinkedHashMap();
71 ow = new ObjectWriter(m.getRepository());
72 rm = m;
75 public void scheduleIfNecessary() {
76 if (!blobQueue.isEmpty() || !treeQueue.isEmpty()) {
77 final ISchedulingRule[] r = new ISchedulingRule[blobRules.size()];
78 blobRules.toArray(r);
79 setRule(MultiRule.combine(r));
80 trace("scheduling");
81 schedule();
85 public void enqueue(final ISchedulingRule rule, final File s,
86 final FileTreeEntry e) {
87 if (rule != null && e.isModified() && s.canRead()) {
88 if (blobQueue.add(new QueuedBlob(s, e))) {
89 blobRules.add(rule);
90 byteCnt += s.length();
91 objectCnt++;
96 public void enqueue(final Tree t) {
97 if (t.isModified()) {
98 if (treeQueue.put(t, EXISTS) == null) {
99 objectCnt++;
104 protected IStatus run(IProgressMonitor monitor) {
105 if (monitor == null) {
106 monitor = new NullProgressMonitor();
109 trace("running");
110 monitor.beginTask(CoreText.CheckpointJob_writing, (int) (byteCnt / MB)
111 + objectCnt);
112 try {
113 Iterator i;
114 boolean wroteSomething;
116 monitor.subTask(CoreText.CheckpointJob_writingBlobs);
117 i = blobQueue.iterator();
118 while (i.hasNext()) {
119 if (monitor.isCanceled()) {
120 trace("canceled");
121 return Status.CANCEL_STATUS;
124 final QueuedBlob q = (QueuedBlob) i.next();
125 synchronized (q.ent) {
126 if (q.ent.isModified() && q.src.canRead()) {
127 q.ent.setId(ow.writeBlob(q.src));
130 monitor.worked((int) (q.src.length() / MB) + 1);
133 monitor.subTask(CoreText.CheckpointJob_writingTrees);
134 wroteSomething = true;
135 while (!treeQueue.isEmpty() && wroteSomething) {
136 i = treeQueue.keySet().iterator();
137 wroteSomething = false;
138 PICK_TREE: while (i.hasNext()) {
139 if (monitor.isCanceled()) {
140 trace("canceled");
141 return Status.CANCEL_STATUS;
144 final Tree t = (Tree) i.next();
145 synchronized (t) {
146 if (t.isModified()) {
147 final TreeEntry[] m = t.members();
148 for (int p = 0; p < m.length; p++) {
149 if (m[p].isModified()) {
150 continue PICK_TREE;
153 t.setId(ow.writeTree(t));
156 wroteSomething = true;
157 monitor.worked(1);
158 i.remove();
162 synchronized (rm) {
163 if (!rm.getCacheTree().isModified()) {
164 monitor.subTask(CoreText.CheckpointJob_writingRef);
165 trace("writing ref");
166 rm.saveCache();
167 } else {
168 trace("tree is still dirty; ref can't be written");
171 } catch (IOException ioe) {
172 return Activator.error(CoreText.CheckpointJob_failed, ioe)
173 .getStatus();
174 } finally {
175 trace("done");
176 monitor.done();
179 return Status.OK_STATUS;
182 private void trace(final String m) {
183 Activator.trace("(CheckpointJob " + rm.getContainer().getFullPath()
184 + ") " + m);
187 private static class QueuedBlob {
188 final File src;
190 final FileTreeEntry ent;
192 QueuedBlob(final File s, final FileTreeEntry e) {
193 src = s;
194 ent = e;
197 public int hashCode() {
198 return ent.hashCode();
201 public boolean equals(final Object o) {
202 return ent.equals(((QueuedBlob) o).ent);