Previously, the DfsObjDatabase had a hardcoded getPackFile() and getPackIndex() methods which opens a .pack and .idx file, respectively. A future change to add a bitmap index will need to be stored in a parallel .bitmap file. Update the DfsObjDatabase to support opening and writing of files for any pack extension. Change-Id: I7c403b501e242096a2d435f6865d6025a9f86108tags/v2.3.0.201302130906
@@ -65,6 +65,7 @@ import org.eclipse.jgit.revwalk.RevWalk; | |||
import org.eclipse.jgit.storage.dfs.DfsObjDatabase.PackSource; | |||
import org.eclipse.jgit.storage.file.PackIndex; | |||
import org.eclipse.jgit.storage.pack.PackConfig; | |||
import org.eclipse.jgit.storage.pack.PackConstants; | |||
import org.eclipse.jgit.storage.pack.PackWriter; | |||
import org.eclipse.jgit.util.io.CountingOutputStream; | |||
@@ -318,14 +319,14 @@ public class DfsGarbageCollector { | |||
DfsPackDescription pack = repo.getObjectDatabase().newPack(source); | |||
newPackDesc.add(pack); | |||
out = objdb.writePackFile(pack); | |||
out = objdb.writeFile(pack, PackConstants.PACK_EXT); | |||
try { | |||
pw.writePack(pm, pm, out); | |||
} finally { | |||
out.close(); | |||
} | |||
out = objdb.writePackIndex(pack); | |||
out = objdb.writeFile(pack, PackConstants.PACK_INDEX_EXT); | |||
try { | |||
CountingOutputStream cnt = new CountingOutputStream(out); | |||
pw.writeIndex(cnt); |
@@ -43,6 +43,9 @@ | |||
package org.eclipse.jgit.storage.dfs; | |||
import static org.eclipse.jgit.storage.pack.PackConstants.PACK_EXT; | |||
import static org.eclipse.jgit.storage.pack.PackConstants.PACK_INDEX_EXT; | |||
import java.io.EOFException; | |||
import java.io.IOException; | |||
import java.io.InputStream; | |||
@@ -220,7 +223,7 @@ public class DfsInserter extends ObjectInserter { | |||
rollback = true; | |||
packDsc = db.newPack(DfsObjDatabase.PackSource.INSERT); | |||
packOut = new PackStream(db.writePackFile(packDsc)); | |||
packOut = new PackStream(db.writeFile(packDsc, PACK_EXT)); | |||
packKey = new DfsPackKey(); | |||
// Write the header as though it were a single object pack. | |||
@@ -250,7 +253,7 @@ public class DfsInserter extends ObjectInserter { | |||
packIndex = PackIndex.read(buf.openInputStream()); | |||
} | |||
DfsOutputStream os = db.writePackIndex(pack); | |||
DfsOutputStream os = db.writeFile(pack, PACK_INDEX_EXT); | |||
try { | |||
CountingOutputStream cnt = new CountingOutputStream(os); | |||
if (buf != null) |
@@ -264,62 +264,40 @@ public abstract class DfsObjDatabase extends ObjectDatabase { | |||
protected abstract List<DfsPackDescription> listPacks() throws IOException; | |||
/** | |||
* Open a pack file for reading. | |||
* Open a pack, pack index, or other related file for reading. | |||
* | |||
* @param desc | |||
* description of pack to read. This is an instance previously | |||
* obtained from {@link #listPacks()}, but not necessarily from | |||
* the same DfsObjDatabase instance. | |||
* @return channel to read the pack file. | |||
* description of pack related to the data that will be read. | |||
* This is an instance previously obtained from | |||
* {@link #listPacks()}, but not necessarily from the same | |||
* DfsObjDatabase instance. | |||
* @param ext | |||
* file extension that will be read i.e "pack" or "idx". | |||
* @return channel to read the file. | |||
* @throws FileNotFoundException | |||
* the file does not exist. | |||
* @throws IOException | |||
* the file cannot be opened. | |||
*/ | |||
protected abstract ReadableChannel openPackFile(DfsPackDescription desc) | |||
protected abstract ReadableChannel openFile( | |||
DfsPackDescription desc, String ext) | |||
throws FileNotFoundException, IOException; | |||
/** | |||
* Open a pack index for reading. | |||
* Open a pack, pack index, or other related file for writing. | |||
* | |||
* @param desc | |||
* description of index to read. This is an instance previously | |||
* obtained from {@link #listPacks()}, but not necessarily from | |||
* the same DfsObjDatabase instance. | |||
* @return channel to read the pack file. | |||
* @throws FileNotFoundException | |||
* the file does not exist. | |||
* @throws IOException | |||
* the file cannot be opened. | |||
*/ | |||
protected abstract ReadableChannel openPackIndex(DfsPackDescription desc) | |||
throws FileNotFoundException, IOException; | |||
/** | |||
* Open a pack file for writing. | |||
* | |||
* @param desc | |||
* description of pack to write. This is an instance previously | |||
* obtained from {@link #newPack(PackSource)}. | |||
* @return channel to write the pack file. | |||
* description of pack related to the data that will be written. | |||
* This is an instance previously obtained from | |||
* {@link #newPack(PackSource)}. | |||
* @param ext | |||
* file extension that will be written i.e "pack" or "idx". | |||
* @return channel to write the file. | |||
* @throws IOException | |||
* the file cannot be opened. | |||
*/ | |||
protected abstract DfsOutputStream writePackFile(DfsPackDescription desc) | |||
throws IOException; | |||
/** | |||
* Open a pack index for writing. | |||
* | |||
* @param desc | |||
* description of index to write. This is an instance previously | |||
* obtained from {@link #newPack(PackSource)}. | |||
* @return channel to write the index file. | |||
* @throws IOException | |||
* the file cannot be opened. | |||
*/ | |||
protected abstract DfsOutputStream writePackIndex(DfsPackDescription desc) | |||
throws IOException; | |||
protected abstract DfsOutputStream writeFile( | |||
DfsPackDescription desc, String ext) throws IOException; | |||
void addPack(DfsPackFile newPack) throws IOException { | |||
PackList o, n; |
@@ -50,8 +50,7 @@ import java.nio.ByteBuffer; | |||
/** | |||
* Output stream to create a file on the DFS. | |||
* | |||
* @see DfsObjDatabase#writePackFile(DfsPackDescription) | |||
* @see DfsObjDatabase#writePackIndex(DfsPackDescription) | |||
* @see DfsObjDatabase#writeFile(DfsPackDescription, String) | |||
*/ | |||
public abstract class DfsOutputStream extends OutputStream { | |||
/** |
@@ -44,6 +44,8 @@ | |||
package org.eclipse.jgit.storage.dfs; | |||
import static org.eclipse.jgit.storage.dfs.DfsObjDatabase.PackSource.COMPACT; | |||
import static org.eclipse.jgit.storage.pack.PackConstants.PACK_EXT; | |||
import static org.eclipse.jgit.storage.pack.PackConstants.PACK_INDEX_EXT; | |||
import java.io.IOException; | |||
import java.util.ArrayList; | |||
@@ -283,7 +285,7 @@ public class DfsPackCompactor { | |||
private void writePack(DfsObjDatabase objdb, DfsPackDescription pack, | |||
PackWriter pw, ProgressMonitor pm) throws IOException { | |||
DfsOutputStream out = objdb.writePackFile(pack); | |||
DfsOutputStream out = objdb.writeFile(pack, PACK_EXT); | |||
try { | |||
CountingOutputStream cnt = new CountingOutputStream(out); | |||
pw.writePack(pm, pm, cnt); | |||
@@ -296,7 +298,7 @@ public class DfsPackCompactor { | |||
private void writeIndex(DfsObjDatabase objdb, DfsPackDescription pack, | |||
PackWriter pw) throws IOException { | |||
DfsOutputStream out = objdb.writePackIndex(pack); | |||
DfsOutputStream out = objdb.writeFile(pack, PACK_INDEX_EXT); | |||
try { | |||
CountingOutputStream cnt = new CountingOutputStream(out); | |||
pw.writeIndex(cnt); |
@@ -47,6 +47,7 @@ import java.util.Set; | |||
import org.eclipse.jgit.lib.ObjectId; | |||
import org.eclipse.jgit.storage.dfs.DfsObjDatabase.PackSource; | |||
import org.eclipse.jgit.storage.pack.PackConstants; | |||
import org.eclipse.jgit.storage.pack.PackWriter; | |||
/** | |||
@@ -81,9 +82,9 @@ public class DfsPackDescription implements Comparable<DfsPackDescription> { | |||
/** | |||
* Initialize a description by pack name and repository. | |||
* <p> | |||
* The corresponding index file is assumed to exist and end with ".idx" | |||
* instead of ".pack". If this is not true implementors must extend the | |||
* class and override {@link #getIndexName()}. | |||
* The corresponding index file is assumed to exist. If this is not true | |||
* implementors must extend the class and override | |||
* {@link #getFileName(String)}. | |||
* <p> | |||
* Callers should also try to fill in other fields if they are reasonably | |||
* free to access at the time this instance is being initialized. | |||
@@ -95,7 +96,8 @@ public class DfsPackDescription implements Comparable<DfsPackDescription> { | |||
*/ | |||
public DfsPackDescription(DfsRepositoryDescription repoDesc, String name) { | |||
this.repoDesc = repoDesc; | |||
this.packName = name; | |||
int dot = name.lastIndexOf('.'); | |||
this.packName = (dot < 0) ? name : name.substring(0, dot); | |||
} | |||
/** @return description of the repository. */ | |||
@@ -103,18 +105,13 @@ public class DfsPackDescription implements Comparable<DfsPackDescription> { | |||
return repoDesc; | |||
} | |||
/** @return name of the pack file. */ | |||
public String getPackName() { | |||
return packName; | |||
} | |||
/** @return name of the index file. */ | |||
public String getIndexName() { | |||
String name = getPackName(); | |||
int dot = name.lastIndexOf('.'); | |||
if (dot < 0) | |||
dot = name.length(); | |||
return name.substring(0, dot) + ".idx"; //$NON-NLS-1$ | |||
/** | |||
* @param ext | |||
* the file extension | |||
* @return name of the file. | |||
* */ | |||
public String getFileName(String ext) { | |||
return packName + '.' + ext; | |||
} | |||
/** @return the source of the pack. */ | |||
@@ -261,14 +258,14 @@ public class DfsPackDescription implements Comparable<DfsPackDescription> { | |||
@Override | |||
public int hashCode() { | |||
return getPackName().hashCode(); | |||
return packName.hashCode(); | |||
} | |||
@Override | |||
public boolean equals(Object b) { | |||
if (b instanceof DfsPackDescription) { | |||
DfsPackDescription desc = (DfsPackDescription) b; | |||
return getPackName().equals(desc.getPackName()) && | |||
return packName.equals(desc.packName) && | |||
getRepositoryDescription().equals(desc.getRepositoryDescription()); | |||
} | |||
return false; | |||
@@ -299,6 +296,6 @@ public class DfsPackDescription implements Comparable<DfsPackDescription> { | |||
@Override | |||
public String toString() { | |||
return getPackName(); | |||
return getFileName(PackConstants.PACK_EXT); | |||
} | |||
} |
@@ -45,6 +45,9 @@ | |||
package org.eclipse.jgit.storage.dfs; | |||
import static org.eclipse.jgit.storage.pack.PackConstants.PACK_EXT; | |||
import static org.eclipse.jgit.storage.pack.PackConstants.PACK_INDEX_EXT; | |||
import java.io.BufferedInputStream; | |||
import java.io.EOFException; | |||
import java.io.IOException; | |||
@@ -187,7 +190,7 @@ public final class DfsPackFile { | |||
} | |||
private String getPackName() { | |||
return packDesc.getPackName(); | |||
return packDesc.getFileName(PACK_EXT); | |||
} | |||
void setBlockSize(int newSize) { | |||
@@ -229,7 +232,7 @@ public final class DfsPackFile { | |||
PackIndex idx; | |||
try { | |||
ReadableChannel rc = ctx.db.openPackIndex(packDesc); | |||
ReadableChannel rc = ctx.db.openFile(packDesc, PACK_INDEX_EXT); | |||
try { | |||
InputStream in = Channels.newInputStream(rc); | |||
int wantSize = 8192; | |||
@@ -246,13 +249,15 @@ public final class DfsPackFile { | |||
} catch (EOFException e) { | |||
invalid = true; | |||
IOException e2 = new IOException(MessageFormat.format( | |||
DfsText.get().shortReadOfIndex, packDesc.getIndexName())); | |||
DfsText.get().shortReadOfIndex, | |||
packDesc.getFileName(PACK_INDEX_EXT))); | |||
e2.initCause(e); | |||
throw e2; | |||
} catch (IOException e) { | |||
invalid = true; | |||
IOException e2 = new IOException(MessageFormat.format( | |||
DfsText.get().cannotReadIndex, packDesc.getIndexName())); | |||
DfsText.get().cannotReadIndex, | |||
packDesc.getFileName(PACK_INDEX_EXT))); | |||
e2.initCause(e); | |||
throw e2; | |||
} | |||
@@ -616,7 +621,7 @@ public final class DfsPackFile { | |||
throw new PackInvalidException(getPackName()); | |||
boolean close = true; | |||
ReadableChannel rc = ctx.db.openPackFile(packDesc); | |||
ReadableChannel rc = ctx.db.openFile(packDesc, PACK_EXT); | |||
try { | |||
// If the block alignment is not yet known, discover it. Prefer the | |||
// larger size from either the cache or the file itself. |
@@ -58,6 +58,7 @@ import org.eclipse.jgit.lib.Constants; | |||
import org.eclipse.jgit.lib.ProgressMonitor; | |||
import org.eclipse.jgit.storage.file.PackIndex; | |||
import org.eclipse.jgit.storage.file.PackLock; | |||
import org.eclipse.jgit.storage.pack.PackConstants; | |||
import org.eclipse.jgit.transport.PackParser; | |||
import org.eclipse.jgit.transport.PackedObjectInfo; | |||
@@ -205,7 +206,7 @@ public class DfsPackParser extends PackParser { | |||
packDsc = objdb.newPack(DfsObjDatabase.PackSource.RECEIVE); | |||
packKey = new DfsPackKey(); | |||
out = objdb.writePackFile(packDsc); | |||
out = objdb.writeFile(packDsc, PackConstants.PACK_EXT); | |||
int size = out.blockSize(); | |||
if (size <= 0) | |||
size = blockCache.getBlockSize(); |
@@ -47,6 +47,7 @@ package org.eclipse.jgit.storage.dfs; | |||
import static org.eclipse.jgit.lib.Constants.OBJECT_ID_LENGTH; | |||
import static org.eclipse.jgit.lib.Constants.OBJ_BLOB; | |||
import static org.eclipse.jgit.lib.Constants.OBJ_TREE; | |||
import static org.eclipse.jgit.storage.pack.PackConstants.PACK_EXT; | |||
import java.io.IOException; | |||
import java.io.InterruptedIOException; | |||
@@ -661,7 +662,7 @@ public final class DfsReader extends ObjectReader implements ObjectReuseAsIs { | |||
pack.setInvalid(); | |||
throw new IOException(MessageFormat.format( | |||
JGitText.get().packfileCorruptionDetected, | |||
pack.getPackDescription().getPackName())); | |||
pack.getPackDescription().getFileName(PACK_EXT))); | |||
} | |||
} | |||
} |
@@ -6,7 +6,9 @@ import java.io.IOException; | |||
import java.nio.ByteBuffer; | |||
import java.util.ArrayList; | |||
import java.util.Collection; | |||
import java.util.HashMap; | |||
import java.util.List; | |||
import java.util.Map; | |||
import java.util.concurrent.ConcurrentHashMap; | |||
import java.util.concurrent.ConcurrentMap; | |||
import java.util.concurrent.atomic.AtomicInteger; | |||
@@ -101,50 +103,31 @@ public class InMemoryRepository extends DfsRepository { | |||
} | |||
@Override | |||
protected ReadableChannel openPackFile(DfsPackDescription desc) | |||
throws FileNotFoundException { | |||
protected ReadableChannel openFile(DfsPackDescription desc, String ext) | |||
throws FileNotFoundException, IOException { | |||
MemPack memPack = (MemPack) desc; | |||
if (memPack.packFile == null) | |||
throw new FileNotFoundException(desc.getPackName()); | |||
return new ByteArrayReadableChannel(memPack.packFile); | |||
byte[] file = memPack.fileMap.get(ext); | |||
if (file == null) | |||
throw new FileNotFoundException(desc.getFileName(ext)); | |||
return new ByteArrayReadableChannel(file); | |||
} | |||
@Override | |||
protected ReadableChannel openPackIndex(DfsPackDescription desc) | |||
throws FileNotFoundException { | |||
MemPack memPack = (MemPack) desc; | |||
if (memPack.packIndex == null) | |||
throw new FileNotFoundException(desc.getIndexName()); | |||
return new ByteArrayReadableChannel(memPack.packIndex); | |||
} | |||
@Override | |||
protected DfsOutputStream writePackFile(DfsPackDescription desc) { | |||
final MemPack memPack = (MemPack) desc; | |||
return new Out() { | |||
@Override | |||
public void flush() { | |||
memPack.packFile = getData(); | |||
} | |||
}; | |||
} | |||
@Override | |||
protected DfsOutputStream writePackIndex(DfsPackDescription desc) { | |||
protected DfsOutputStream writeFile( | |||
DfsPackDescription desc, final String ext) throws IOException { | |||
final MemPack memPack = (MemPack) desc; | |||
return new Out() { | |||
@Override | |||
public void flush() { | |||
memPack.packIndex = getData(); | |||
memPack.fileMap.put(ext, getData()); | |||
} | |||
}; | |||
} | |||
} | |||
private static class MemPack extends DfsPackDescription { | |||
private byte[] packFile; | |||
private byte[] packIndex; | |||
private final Map<String, byte[]> | |||
fileMap = new HashMap<String, byte[]>(); | |||
MemPack(String name, DfsRepositoryDescription repoDesc) { | |||
super(repoDesc, name); |
@@ -0,0 +1,57 @@ | |||
/* | |||
* Copyright (C) 2013, Google Inc. | |||
* 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.storage.pack; | |||
/** Misc. constants used with pack files. */ | |||
public class PackConstants { | |||
/** A pack file extension. */ | |||
public static final String PACK_EXT = "pack"; //$NON-NLS-1$ | |||
/** A pack index file extension. */ | |||
public static final String PACK_INDEX_EXT = "idx"; //$NON-NLS-1$ | |||
private PackConstants() { | |||
} | |||
} |