Browse Source

Introduce RefDatabase#hasFastTipsWithSha1

The reftable format supports fast inverse (SHA1 => ref) queries.

If the ref database does not support fast inverse queries, it may be
advantageous to build a complete SHA1 to ref map in advance for
multiple uses. To let applications decide, this function indicates
whether the inverse map is available.

Signed-off-by: Han-Wen Nienhuys <hanwen@google.com>
Change-Id: Idaf7e01075906972ec21332cade285289619c2b3
tags/v5.6.0.201912101111-r
Han-Wen Nienhuys 4 years ago
parent
commit
5185d288c1

+ 4
- 0
org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/FileReftableTest.java View File

assertFalse(b.isSymbolic()); assertFalse(b.isSymbolic());
assertTrue(b.isPeeled()); assertTrue(b.isPeeled());
assertEquals(bCommit, b.getObjectId().name()); assertEquals(bCommit, b.getObjectId().name());

assertTrue(db.getRefDatabase().hasFastTipsWithSha1());
} }


@Test @Test
assertFalse(b.isSymbolic()); assertFalse(b.isSymbolic());
assertTrue(b.isPeeled()); assertTrue(b.isPeeled());
assertEquals(bCommit, b.getObjectId().name()); assertEquals(bCommit, b.getObjectId().name());

assertFalse(db.getRefDatabase().hasFastTipsWithSha1());
} }


@Test @Test

+ 66
- 0
org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/reftable/ReftableTest.java View File

assertEquals(expBytes, table.length); assertEquals(expBytes, table.length);
} }


@Test
public void hasObjMapRefs() throws IOException {
ArrayList<Ref> refs = new ArrayList<>();
refs.add(ref(MASTER, 1));
byte[] table = write(refs);
ReftableReader t = read(table);
assertTrue(t.hasObjectMap());
}

@Test
public void hasObjMapRefsSmallTable() throws IOException {
ArrayList<Ref> refs = new ArrayList<>();
ReftableConfig cfg = new ReftableConfig();
cfg.setIndexObjects(false);
refs.add(ref(MASTER, 1));
byte[] table = write(refs);
ReftableReader t = read(table);
assertTrue(t.hasObjectMap());
}

@Test
public void hasObjLogs() throws IOException {
PersonIdent who = new PersonIdent("Log", "Ger", 1500079709, -8 * 60);
String msg = "test";
ReftableConfig cfg = new ReftableConfig();
cfg.setIndexObjects(false);

ByteArrayOutputStream buffer = new ByteArrayOutputStream();
ReftableWriter writer = new ReftableWriter(buffer)
.setMinUpdateIndex(1)
.setConfig(cfg)
.setMaxUpdateIndex(1)
.begin();

writer.writeLog("master", 1, who, ObjectId.zeroId(), id(1), msg);
writer.finish();
byte[] table = buffer.toByteArray();

ReftableReader t = read(table);
assertTrue(t.hasObjectMap());
}

@Test
public void hasObjMapRefsNoIndexObjects() throws IOException {
ArrayList<Ref> refs = new ArrayList<>();
ReftableConfig cfg = new ReftableConfig();
cfg.setIndexObjects(false);
cfg.setRefBlockSize(256);
cfg.setAlignBlocks(true);

// Fill up 5 blocks.
int N = 256 * 5 / 25;
for (int i= 0; i < N; i++) {
refs.add(ref(String.format("%02d/xxxxxxxxxx", i), i));
}
byte[] table = write(refs, cfg);

ReftableReader t = read(table);
assertFalse(t.hasObjectMap());
}

@Test @Test
public void oneIdRef() throws IOException { public void oneIdRef() throws IOException {
Ref exp = ref(MASTER, 1); Ref exp = ref(MASTER, 1);
} }


private byte[] write(Collection<Ref> refs) throws IOException { private byte[] write(Collection<Ref> refs) throws IOException {
return write(refs, new ReftableConfig());
}

private byte[] write(Collection<Ref> refs, ReftableConfig cfg) throws IOException {
ByteArrayOutputStream buffer = new ByteArrayOutputStream(); ByteArrayOutputStream buffer = new ByteArrayOutputStream();
stats = new ReftableWriter(buffer) stats = new ReftableWriter(buffer)
.setConfig(cfg)
.begin() .begin()
.sortAndWriteRefs(refs) .sortAndWriteRefs(refs)
.finish() .finish()

+ 6
- 0
org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsReftableDatabase.java View File

return reftableDatabase.getTipsWithSha1(id); return reftableDatabase.getTipsWithSha1(id);
} }


/** {@inheritDoc} */
@Override
public boolean hasFastTipsWithSha1() throws IOException {
return reftableDatabase.hasFastTipsWithSha1();
}

/** {@inheritDoc} */ /** {@inheritDoc} */
@Override @Override
public Ref peel(Ref ref) throws IOException { public Ref peel(Ref ref) throws IOException {

+ 6
- 0
org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileReftableDatabase.java View File

&& new File(repoDir, Constants.REFTABLE).isDirectory(); && new File(repoDir, Constants.REFTABLE).isDirectory();
} }


/** {@inheritDoc} */
@Override
public boolean hasFastTipsWithSha1() throws IOException {
return reftableDatabase.hasFastTipsWithSha1();
}

/** /**
* Runs a full compaction for GC purposes. * Runs a full compaction for GC purposes.
* @throws IOException on I/O errors * @throws IOException on I/O errors

+ 10
- 0
org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/MergedReftable.java View File

: 0; : 0;
} }


/** {@inheritDoc} */
@Override
public boolean hasObjectMap() throws IOException {
boolean has = true;
for (int i = 0; has && i < tables.length; i++) {
has = has && tables[i].hasObjectMap();
};
return has;
}

/** {@inheritDoc} */ /** {@inheritDoc} */
@Override @Override
public RefCursor allRefs() throws IOException { public RefCursor allRefs() throws IOException {

+ 6
- 0
org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/Reftable.java View File

*/ */
public abstract RefCursor byObjectId(AnyObjectId id) throws IOException; public abstract RefCursor byObjectId(AnyObjectId id) throws IOException;


/**
* @return whether this reftable can do a fast SHA1 => ref lookup.
* @throws IOException on I/O problems.
*/
public abstract boolean hasObjectMap() throws IOException;

/** /**
* Seek reader to read log records. * Seek reader to read log records.
* *

+ 13
- 0
org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/ReftableDatabase.java View File

return Collections.unmodifiableList(all); return Collections.unmodifiableList(all);
} }


/**
* @return whether there is a fast SHA1 to ref map.
* @throws IOException in case of I/O problems.
*/
public boolean hasFastTipsWithSha1() throws IOException {
lock.lock();
try {
return reader().hasObjectMap();
} finally {
lock.unlock();
}
}

/** /**
* Returns all refs that resolve directly to the given {@link ObjectId}. * Returns all refs that resolve directly to the given {@link ObjectId}.
* Includes peeled {@linkObjectId}s. * Includes peeled {@linkObjectId}s.

+ 10
- 0
org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/ReftableReader.java View File

return blockSize; return blockSize;
} }


@Override
public boolean hasObjectMap() throws IOException {
if (objIndexPosition == -1) {
readFileFooter();
}

// We have the map, we have no refs, or the table is small.
return (objPosition > 0 || refEnd == 24 || refIndexPosition == 0);
}

/** /**
* Get the minimum update index for log entries that appear in this * Get the minimum update index for log entries that appear in this
* reftable. * reftable.

+ 14
- 0
org.eclipse.jgit/src/org/eclipse/jgit/lib/RefDatabase.java View File

|| id.equals(r.getPeeledObjectId())).collect(toSet()); || id.equals(r.getPeeledObjectId())).collect(toSet());
} }


/**
* If the ref database does not support fast inverse queries, it may
* be advantageous to build a complete SHA1 to ref map in advance for
* multiple uses. To let applications decide on this decision,
* this function indicates whether the inverse map is available.
*
* @return whether this RefDatabase supports fast inverse ref queries.
* @throws IOException on I/O problems.
* @since 5.6
*/
public boolean hasFastTipsWithSha1() throws IOException {
return false;
}

/** /**
* Check if any refs exist in the ref database. * Check if any refs exist in the ref database.
* <p> * <p>

Loading…
Cancel
Save