diff options
author | Shawn O. Pearce | 2011-05-13 16:16:58 +0000 |
---|---|---|
committer | Chris Aniszczyk | 2011-05-25 14:08:33 +0000 |
commit | b8c508e54d64628660aa0d907b37a9648923c1f5 (patch) | |
tree | 222c48b34df9b4b9f70c725f3c3f1f56c2b42414 /org.eclipse.jgit.storage.dht/src/org/eclipse/jgit/storage/dht/DhtRefUpdate.java | |
parent | 6ec6169215eb33683728c583e231eb5fe9617813 (diff) | |
download | jgit-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.java | 52 |
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); } } |