Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShawn O. Pearce2011-05-13 16:16:58 +0000
committerChris Aniszczyk2011-05-25 14:08:33 +0000
commitb8c508e54d64628660aa0d907b37a9648923c1f5 (patch)
tree222c48b34df9b4b9f70c725f3c3f1f56c2b42414 /org.eclipse.jgit.storage.dht/src/org/eclipse/jgit/storage/dht/DhtRefUpdate.java
parent6ec6169215eb33683728c583e231eb5fe9617813 (diff)
downloadjgit-b8c508e54d64628660aa0d907b37a9648923c1f5.tar.gz
jgit-b8c508e54d64628660aa0d907b37a9648923c1f5.tar.xz
jgit-b8c508e54d64628660aa0d907b37a9648923c1f5.zip
DHT: Add sequence RefData
RefData now uses a sequence number as part of the field, ensuring that updates always increase the sequence number by one whenever a reference is modified. Attaching a sequence number to RefData will help with storing reference log entries during updates. As the sequence number should be unique within the reference name space, log entries can be keyed by the sequence number and remain unique. Making this work over reference delete-create cycles will require an additional RefTable API to return the oldest sequence number previously used in the reference log to seed the recreated reference. Change-Id: I11cfff2a96ef962e57f29925a3eef41bdbf9f9bb Signed-off-by: Shawn O. Pearce <spearce@spearce.org> Signed-off-by: Chris Aniszczyk <caniszczyk@gmail.com>
Diffstat (limited to 'org.eclipse.jgit.storage.dht/src/org/eclipse/jgit/storage/dht/DhtRefUpdate.java')
-rw-r--r--org.eclipse.jgit.storage.dht/src/org/eclipse/jgit/storage/dht/DhtRefUpdate.java52
1 files changed, 38 insertions, 14 deletions
diff --git a/org.eclipse.jgit.storage.dht/src/org/eclipse/jgit/storage/dht/DhtRefUpdate.java b/org.eclipse.jgit.storage.dht/src/org/eclipse/jgit/storage/dht/DhtRefUpdate.java
index f131e2d741..cb363d0376 100644
--- a/org.eclipse.jgit.storage.dht/src/org/eclipse/jgit/storage/dht/DhtRefUpdate.java
+++ b/org.eclipse.jgit.storage.dht/src/org/eclipse/jgit/storage/dht/DhtRefUpdate.java
@@ -54,6 +54,7 @@ import org.eclipse.jgit.lib.RefUpdate;
import org.eclipse.jgit.revwalk.RevObject;
import org.eclipse.jgit.revwalk.RevTag;
import org.eclipse.jgit.revwalk.RevWalk;
+import org.eclipse.jgit.storage.dht.DhtRefDatabase.DhtRef;
import org.eclipse.jgit.storage.dht.spi.Database;
class DhtRefUpdate extends RefUpdate {
@@ -107,7 +108,7 @@ class DhtRefUpdate extends RefUpdate {
dstRef = dstRef.getLeaf();
refKey = RefKey.create(repo, dstRef.getName());
- oldData = RefDataUtil.fromRef(dstRef);
+ oldData = ((DhtRef) dstRef).getRefData();
if (dstRef.isSymbolic())
setOldObjectId(null);
@@ -158,7 +159,11 @@ class DhtRefUpdate extends RefUpdate {
@Override
protected Result doLink(String target) throws IOException {
try {
- newData = RefDataUtil.symbolic(target);
+ RefData.Builder d = RefData.newBuilder(oldData);
+ clearRefData(d);
+ updateSequence(d);
+ d.setSymref(target);
+ newData = d.build();
boolean r = db.ref().compareAndPut(refKey, oldData, newData);
if (r) {
getRefDatabase().stored(dstRef.getName(), newData);
@@ -175,26 +180,45 @@ class DhtRefUpdate extends RefUpdate {
}
private RefData newData() throws IOException {
+ RefData.Builder d = RefData.newBuilder(oldData);
+ clearRefData(d);
+ updateSequence(d);
+
ObjectId newId = getNewObjectId();
+ d.getTargetBuilder().setObjectName(newId.name());
try {
- RevObject obj = rw.parseAny(newId);
DhtReader ctx = (DhtReader) rw.getObjectReader();
+ RevObject obj = rw.parseAny(newId);
- ChunkKey key = ctx.findChunk(newId);
- if (key != null)
- newId = new RefDataUtil.IdWithChunk(newId, key);
+ ChunkKey oKey = ctx.findChunk(newId);
+ if (oKey != null)
+ d.getTargetBuilder().setChunkKey(oKey.asString());
if (obj instanceof RevTag) {
ObjectId pId = rw.peel(obj);
- key = ctx.findChunk(pId);
- pId = key != null ? new RefDataUtil.IdWithChunk(pId, key) : pId;
- return RefDataUtil.peeled(newId, pId);
- } else if (obj != null)
- return RefDataUtil.peeled(newId, null);
- else
- return RefDataUtil.id(newId);
+ ChunkKey pKey = ctx.findChunk(pId);
+ if (pKey != null)
+ d.getPeeledBuilder().setChunkKey(pKey.asString());
+ d.getPeeledBuilder().setObjectName(pId.name());
+ }
} catch (MissingObjectException e) {
- return RefDataUtil.id(newId);
+ // Automatic peeling failed. Ignore the problem and deal with it
+ // during reading later, this is the classical Git behavior on disk.
}
+ return d.build();
+ }
+
+ private static void clearRefData(RefData.Builder d) {
+ // Clear fields individually rather than discarding the RefData.
+ // This way implementation specific extensions are carried
+ // through from the old version to the new version.
+ d.clearSymref();
+ d.clearTarget();
+ d.clearPeeled();
+ d.clearIsPeeled();
+ }
+
+ private static void updateSequence(RefData.Builder d) {
+ d.setSequence(d.getSequence() + 1);
}
}

Back to the top