Browse Source

DfsObjectDatabase: Expose PackList and move markDirty there

What's invalidated when an object database is "dirty" is not the whole
database, but rather a specific list of packs. If there is a race
between getting the pack list and setting the volatile dirty flag
where the packs are rescanned, we don't need to mark the new pack list
as dirty.

This is a fine point that only really applies if the decision of
whether or not to mark dirty actually requires introspecting the pack
list (say, its timestamps). The general operation of "take whatever
is the current pack list and mark it dirty" may still be inherently
racy, but the cost is not so high.

Change-Id: I159e9154bd8b2d348b4e383627a503e85462dcc6
stable-4.5
Dave Borowitz 8 years ago
parent
commit
0f1c361e62
  1. 55
      org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsObjDatabase.java
  2. 2
      org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/InMemoryRepository.java

55
org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsObjDatabase.java

@ -68,7 +68,7 @@ public abstract class DfsObjDatabase extends ObjectDatabase {
}
@Override
void markDirty() {
public void markDirty() {
// Always dirty.
}
};
@ -186,7 +186,16 @@ public abstract class DfsObjDatabase extends ObjectDatabase {
return getPackList().packs;
}
PackList getPackList() throws IOException {
/**
* Scan and list all available pack files in the repository.
*
* @return list of available packs, with some additional metadata. The
* returned array is shared with the implementation and must not be
* modified by the caller.
* @throws IOException
* the pack list cannot be initialized.
*/
public PackList getPackList() throws IOException {
return scanPacks(NO_PACKS);
}
@ -202,7 +211,18 @@ public abstract class DfsObjDatabase extends ObjectDatabase {
* implementation and must not be modified by the caller.
*/
public DfsPackFile[] getCurrentPacks() {
return packList.get().packs;
return getCurrentPackList().packs;
}
/**
* List currently known pack files in the repository, without scanning.
*
* @return list of available packs, with some additional metadata. The
* returned array is shared with the implementation and must not be
* modified by the caller.
*/
public PackList getCurrentPackList() {
return packList.get();
}
/**
@ -460,17 +480,6 @@ public abstract class DfsObjDatabase extends ObjectDatabase {
packList.set(NO_PACKS);
}
/**
* Mark object database as dirty.
* <p>
* Used when the caller knows that new data might have been written to the
* repository that could invalidate open readers, for example if refs are
* newly scanned.
*/
protected void markDirty() {
packList.get().markDirty();
}
@Override
public void close() {
// PackList packs = packList.get();
@ -481,17 +490,25 @@ public abstract class DfsObjDatabase extends ObjectDatabase {
// p.close();
}
static abstract class PackList {
/** Snapshot of packs scanned in a single pass. */
public static abstract class PackList {
/** All known packs, sorted. */
final DfsPackFile[] packs;
public final DfsPackFile[] packs;
PackList(final DfsPackFile[] packs) {
PackList(DfsPackFile[] packs) {
this.packs = packs;
}
abstract boolean dirty();
abstract void markDirty();
/**
* Mark pack list as dirty.
* <p>
* Used when the caller knows that new data might have been written to the
* repository that could invalidate open readers depending on this pack list,
* for example if refs are newly scanned.
*/
public abstract void markDirty();
}
private static final class PackListImpl extends PackList {
@ -507,7 +524,7 @@ public abstract class DfsObjDatabase extends ObjectDatabase {
}
@Override
void markDirty() {
public void markDirty() {
dirty = true;
}
}

2
org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/InMemoryRepository.java

@ -310,7 +310,7 @@ public class InMemoryRepository extends DfsRepository {
}
ids.sort();
sym.sort();
objdb.markDirty();
objdb.getCurrentPackList().markDirty();
return new RefCache(ids.toRefList(), sym.toRefList());
}

Loading…
Cancel
Save