summaryrefslogtreecommitdiffstats
path: root/org.eclipse.jgit
diff options
context:
space:
mode:
Diffstat (limited to 'org.eclipse.jgit')
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/lib/AlternateRepositoryDatabase.java6
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/lib/CachedObjectDatabase.java132
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/lib/CachedObjectDirectory.java112
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/lib/Config.java49
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectChecker.java10
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectDatabase.java12
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectDirectory.java5
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/transport/IndexPack.java10
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportHttp.java1
9 files changed, 328 insertions, 9 deletions
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/AlternateRepositoryDatabase.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/AlternateRepositoryDatabase.java
index 311839e430..f8570a4203 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/AlternateRepositoryDatabase.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/AlternateRepositoryDatabase.java
@@ -1,4 +1,5 @@
/*
+ * Copyright (C) 2010, Constantine Plotnikov <constantine.plotnikov@gmail.com>
* Copyright (C) 2009, Google Inc.
* and other copyright owners as documented in the project's IP log.
*
@@ -130,4 +131,9 @@ public final class AlternateRepositoryDatabase extends ObjectDatabase {
protected void closeAlternates(final ObjectDatabase[] alt) {
// Do nothing; these belong to odb to close, not us.
}
+
+ @Override
+ public ObjectDatabase newCachedDatabase() {
+ return odb.newCachedDatabase();
+ }
}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/CachedObjectDatabase.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/CachedObjectDatabase.java
new file mode 100644
index 0000000000..3dcea1636f
--- /dev/null
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/CachedObjectDatabase.java
@@ -0,0 +1,132 @@
+/*
+ * Copyright (C) 2010, Constantine Plotnikov <constantine.plotnikov@gmail.com>
+ * Copyright (C) 2010, JetBrains s.r.o.
+ * and other copyright owners as documented in the project's IP log.
+ *
+ * This program and the accompanying materials are made available
+ * under the terms of the Eclipse Distribution License v1.0 which
+ * accompanies this distribution, is reproduced below, and is
+ * available at http://www.eclipse.org/org/documents/edl-v10.php
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * - Neither the name of the Eclipse Foundation, Inc. nor the
+ * names of its contributors may be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package org.eclipse.jgit.lib;
+
+import java.io.IOException;
+import java.util.Collection;
+
+/**
+ * {@link ObjectDatabase} wrapper providing temporary lookup caching.
+ * <p>
+ * The base class for {@code ObjectDatabase}s that wrap other database instances
+ * and optimize querying for objects by caching some database dependent
+ * information. Instances of this class (or any of its subclasses) can be
+ * returned from the method {@link ObjectDatabase#newCachedDatabase()}. This
+ * class can be used in scenarios where the database does not change, or when
+ * changes in the database while some operation is in progress is an acceptable
+ * risk.
+ * <p>
+ * The default implementation delegates all requests to the wrapped database.
+ * The instance might be indirectly invalidated if the wrapped instance is
+ * closed. Closing the delegating instance does not implies closing the wrapped
+ * instance. For alternative databases, cached instances are used as well.
+ */
+public class CachedObjectDatabase extends ObjectDatabase {
+ /**
+ * The wrapped database instance
+ */
+ protected final ObjectDatabase wrapped;
+
+ /**
+ * Create the delegating database instance
+ *
+ * @param wrapped
+ * the wrapped object database
+ */
+ public CachedObjectDatabase(ObjectDatabase wrapped) {
+ this.wrapped = wrapped;
+ }
+
+ @Override
+ protected boolean hasObject1(AnyObjectId objectId) {
+ return wrapped.hasObject1(objectId);
+ }
+
+ @Override
+ protected ObjectLoader openObject1(WindowCursor curs, AnyObjectId objectId)
+ throws IOException {
+ return wrapped.openObject1(curs, objectId);
+ }
+
+ @Override
+ protected boolean hasObject2(String objectName) {
+ return wrapped.hasObject2(objectName);
+ }
+
+ @Override
+ protected ObjectDatabase[] loadAlternates() throws IOException {
+ ObjectDatabase[] loaded = wrapped.getAlternates();
+ ObjectDatabase[] result = new ObjectDatabase[loaded.length];
+ for (int i = 0; i < loaded.length; i++) {
+ result[i] = loaded[i].newCachedDatabase();
+ }
+ return result;
+ }
+
+ @Override
+ protected ObjectLoader openObject2(WindowCursor curs, String objectName,
+ AnyObjectId objectId) throws IOException {
+ return wrapped.openObject2(curs, objectName, objectId);
+ }
+
+ @Override
+ void openObjectInAllPacks1(Collection<PackedObjectLoader> out,
+ WindowCursor curs, AnyObjectId objectId) throws IOException {
+ wrapped.openObjectInAllPacks1(out, curs, objectId);
+ }
+
+ @Override
+ protected boolean tryAgain1() {
+ return wrapped.tryAgain1();
+ }
+
+ @Override
+ public ObjectDatabase newCachedDatabase() {
+ // Note that "this" is not returned since subclasses might actually do something,
+ // on closeSelf() (for example closing database connections or open repositories).
+ // The situation might become even more tricky if we will consider alternates.
+ return wrapped.newCachedDatabase();
+ }
+}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/CachedObjectDirectory.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/CachedObjectDirectory.java
new file mode 100644
index 0000000000..3724f84463
--- /dev/null
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/CachedObjectDirectory.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2010, Constantine Plotnikov <constantine.plotnikov@gmail.com>
+ * Copyright (C) 2010, JetBrains s.r.o.
+ * and other copyright owners as documented in the project's IP log.
+ *
+ * This program and the accompanying materials are made available
+ * under the terms of the Eclipse Distribution License v1.0 which
+ * accompanies this distribution, is reproduced below, and is
+ * available at http://www.eclipse.org/org/documents/edl-v10.php
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * - Neither the name of the Eclipse Foundation, Inc. nor the
+ * names of its contributors may be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package org.eclipse.jgit.lib;
+
+import java.io.File;
+import java.io.IOException;
+
+/**
+ * The cached instance of an {@link ObjectDirectory}.
+ * <p>
+ * This class caches the list of loose objects in memory, so the file system is
+ * not queried with stat calls.
+ */
+public class CachedObjectDirectory extends CachedObjectDatabase {
+ /**
+ * The set that contains unpacked objects identifiers, it is created when
+ * the cached instance is created.
+ */
+ private final ObjectIdSubclassMap<ObjectId> unpackedObjects = new ObjectIdSubclassMap<ObjectId>();
+
+ /**
+ * The constructor
+ *
+ * @param wrapped
+ * the wrapped database
+ */
+ public CachedObjectDirectory(ObjectDirectory wrapped) {
+ super(wrapped);
+ File objects = wrapped.getDirectory();
+ String[] fanout = objects.list();
+ if (fanout == null)
+ fanout = new String[0];
+ for (String d : fanout) {
+ if (d.length() != 2)
+ continue;
+ String[] entries = new File(objects, d).list();
+ if (entries == null)
+ continue;
+ for (String e : entries) {
+ if (e.length() != Constants.OBJECT_ID_STRING_LENGTH - 2)
+ continue;
+ try {
+ unpackedObjects.add(ObjectId.fromString(d + e));
+ } catch (IllegalArgumentException notAnObject) {
+ // ignoring the file that does not represent loose object
+ }
+ }
+ }
+ }
+
+ @Override
+ protected ObjectLoader openObject2(WindowCursor curs, String objectName,
+ AnyObjectId objectId) throws IOException {
+ if (unpackedObjects.get(objectId) == null)
+ return null;
+ return super.openObject2(curs, objectName, objectId);
+ }
+
+ @Override
+ protected boolean hasObject1(AnyObjectId objectId) {
+ if (unpackedObjects.get(objectId) != null)
+ return true; // known to be loose
+ return super.hasObject1(objectId);
+ }
+
+ @Override
+ protected boolean hasObject2(String name) {
+ return false; // loose objects were tested by hasObject1
+ }
+}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/Config.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/Config.java
index 661371ca21..0d0c377f8f 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/Config.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/Config.java
@@ -577,6 +577,43 @@ public class Config {
}
/**
+ * Remove all configuration values under a single section.
+ *
+ * @param section
+ * section name, e.g "branch"
+ * @param subsection
+ * optional subsection value, e.g. a branch name
+ */
+ public void unsetSection(String section, String subsection) {
+ State src, res;
+ do {
+ src = state.get();
+ res = unsetSection(src, section, subsection);
+ } while (!state.compareAndSet(src, res));
+ }
+
+ private State unsetSection(final State srcState, final String section,
+ final String subsection) {
+ final int max = srcState.entryList.size();
+ final ArrayList<Entry> r = new ArrayList<Entry>(max);
+
+ boolean lastWasMatch = false;
+ for (Entry e : srcState.entryList) {
+ if (e.match(section, subsection)) {
+ // Skip this record, it's for the section we are removing.
+ lastWasMatch = true;
+ continue;
+ }
+
+ if (lastWasMatch && e.section == null && e.subsection == null)
+ continue; // skip this padding line in the section.
+ r.add(e);
+ }
+
+ return newState(r);
+ }
+
+ /**
* Set a configuration value.
*
* <pre>
@@ -715,9 +752,10 @@ public class Config {
if (e.prefix == null || "".equals(e.prefix))
out.append('\t');
out.append(e.name);
- if (e.value != null) {
- if (MAGIC_EMPTY_VALUE != e.value) {
- out.append(" = ");
+ if (MAGIC_EMPTY_VALUE != e.value) {
+ out.append(" =");
+ if (e.value != null) {
+ out.append(' ');
out.append(escapeValue(e.value));
}
}
@@ -1103,6 +1141,11 @@ public class Config {
&& eqIgnoreCase(name, aKey);
}
+ boolean match(final String aSection, final String aSubsection) {
+ return eqIgnoreCase(section, aSection)
+ && eqSameCase(subsection, aSubsection);
+ }
+
private static boolean eqIgnoreCase(final String a, final String b) {
if (a == null && b == null)
return true;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectChecker.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectChecker.java
index 82a8c38257..5906802d18 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectChecker.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectChecker.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008, Google Inc.
+ * Copyright (C) 2008-2010, Google Inc.
* Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
* and other copyright owners as documented in the project's IP log.
*
@@ -217,10 +217,10 @@ public class ObjectChecker {
throw new CorruptObjectException("no tag header");
ptr = nextLF(raw, ptr);
- if ((ptr = match(raw, ptr, tagger)) < 0)
- throw new CorruptObjectException("no tagger header");
- if ((ptr = personIdent(raw, ptr)) < 0 || raw[ptr++] != '\n')
- throw new CorruptObjectException("invalid tagger");
+ if ((ptr = match(raw, ptr, tagger)) > 0) {
+ if ((ptr = personIdent(raw, ptr)) < 0 || raw[ptr++] != '\n')
+ throw new CorruptObjectException("invalid tagger");
+ }
}
private static int lastPathChar(final int mode) {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectDatabase.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectDatabase.java
index 21b7b9dc93..7eac79fb78 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectDatabase.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectDatabase.java
@@ -380,4 +380,16 @@ public abstract class ObjectDatabase {
d.close();
}
}
+
+ /**
+ * Create a new cached database instance over this database. This instance might
+ * optimize queries by caching some information about database. So some modifications
+ * done after instance creation might fail to be noticed.
+ *
+ * @return new cached database instance
+ * @see CachedObjectDatabase
+ */
+ public ObjectDatabase newCachedDatabase() {
+ return new CachedObjectDatabase(this);
+ }
}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectDirectory.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectDirectory.java
index a6fdbfae5c..a8d6dda066 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectDirectory.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectDirectory.java
@@ -541,4 +541,9 @@ public class ObjectDirectory extends ObjectDatabase {
return true;
}
}
+
+ @Override
+ public ObjectDatabase newCachedDatabase() {
+ return new CachedObjectDirectory(this);
+ }
}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/IndexPack.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/IndexPack.java
index 6e0f228079..7c94767b49 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/IndexPack.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/IndexPack.java
@@ -68,6 +68,7 @@ import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.InflaterCache;
import org.eclipse.jgit.lib.MutableObjectId;
import org.eclipse.jgit.lib.ObjectChecker;
+import org.eclipse.jgit.lib.ObjectDatabase;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.ObjectIdSubclassMap;
import org.eclipse.jgit.lib.ObjectLoader;
@@ -130,6 +131,11 @@ public class IndexPack {
private final Repository repo;
+ /**
+ * Object database used for loading existing objects
+ */
+ private final ObjectDatabase objectDatabase;
+
private Inflater inflater;
private final MessageDigest objectDigest;
@@ -199,6 +205,7 @@ public class IndexPack {
public IndexPack(final Repository db, final InputStream src,
final File dstBase) throws IOException {
repo = db;
+ objectDatabase = db.getObjectDatabase().newCachedDatabase();
in = src;
inflater = InflaterCache.get();
readCurs = new WindowCursor();
@@ -350,6 +357,7 @@ public class IndexPack {
InflaterCache.release(inflater);
} finally {
inflater = null;
+ objectDatabase.close();
}
readCurs = WindowCursor.release(readCurs);
@@ -756,7 +764,7 @@ public class IndexPack {
}
}
- final ObjectLoader ldr = repo.openObject(readCurs, id);
+ final ObjectLoader ldr = objectDatabase.openObject(readCurs, id);
if (ldr != null) {
final byte[] existingData = ldr.getCachedBytes();
if (ldr.getType() != type || !Arrays.equals(data, existingData)) {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportHttp.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportHttp.java
index f041765b8a..c53bcf2601 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportHttp.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportHttp.java
@@ -373,6 +373,7 @@ public class TransportHttp extends HttpTransport implements WalkTransport,
final HttpURLConnection httpOpen(final URL u) throws IOException {
final Proxy proxy = HttpSupport.proxyFor(proxySelector, u);
HttpURLConnection conn = (HttpURLConnection) u.openConnection(proxy);
+ conn.setUseCaches(false);
conn.setRequestProperty(HDR_ACCEPT_ENCODING, ENCODING_GZIP);
conn.setRequestProperty(HDR_PRAGMA, "no-cache");//$NON-NLS-1$
conn.setRequestProperty(HDR_USER_AGENT, userAgent);