Make Reftable seek* and has* method names more consistent

Make the method names more consistent and their semantics simpler:
hasRef and seekRef to look up a single exact reference by name and
hasRefsByPrefix and seekRefsByPrefix to look up multiple references by
name prefix.

In particular, splitting hasRef into two separate methods for its
different uses makes DfsReftableDatabase.isNameConflicting easier to
follow.

[jn: fleshed out commit message]

Change-Id: I71106068ff3ec4f7e14dd9eb6ee6b5fab8d14d0b
Signed-off-by: Minh Thai <mthai@google.com>
Signed-off-by: Jonathan Nieder <jrn@google.com>
This commit is contained in:
Minh Thai 2018-07-10 12:41:23 -07:00 committed by Jonathan Nieder
parent e04d96e3fa
commit 263a8c1c06
7 changed files with 36 additions and 28 deletions

View File

@ -70,7 +70,7 @@ protected void run() throws Exception {
BlockSource src = BlockSource.from(in); BlockSource src = BlockSource.from(in);
ReftableReader reader = new ReftableReader(src)) { ReftableReader reader = new ReftableReader(src)) {
try (RefCursor rc = ref != null try (RefCursor rc = ref != null
? reader.seekPrefix(ref) ? reader.seekRefsWithPrefix(ref)
: reader.allRefs()) { : reader.allRefs()) {
while (rc.next()) { while (rc.next()) {
write(rc.getRef()); write(rc.getRef());

View File

@ -80,7 +80,7 @@ public void noTables() throws IOException {
try (RefCursor rc = mr.seekRef(HEAD)) { try (RefCursor rc = mr.seekRef(HEAD)) {
assertFalse(rc.next()); assertFalse(rc.next());
} }
try (RefCursor rc = mr.seekPrefix(R_HEADS)) { try (RefCursor rc = mr.seekRefsWithPrefix(R_HEADS)) {
assertFalse(rc.next()); assertFalse(rc.next());
} }
} }
@ -94,7 +94,7 @@ public void oneEmptyTable() throws IOException {
try (RefCursor rc = mr.seekRef(HEAD)) { try (RefCursor rc = mr.seekRef(HEAD)) {
assertFalse(rc.next()); assertFalse(rc.next());
} }
try (RefCursor rc = mr.seekPrefix(R_HEADS)) { try (RefCursor rc = mr.seekRefsWithPrefix(R_HEADS)) {
assertFalse(rc.next()); assertFalse(rc.next());
} }
} }
@ -108,7 +108,7 @@ public void twoEmptyTables() throws IOException {
try (RefCursor rc = mr.seekRef(HEAD)) { try (RefCursor rc = mr.seekRef(HEAD)) {
assertFalse(rc.next()); assertFalse(rc.next());
} }
try (RefCursor rc = mr.seekPrefix(R_HEADS)) { try (RefCursor rc = mr.seekRefsWithPrefix(R_HEADS)) {
assertFalse(rc.next()); assertFalse(rc.next());
} }
} }

View File

@ -101,7 +101,7 @@ public void emptyTable() throws IOException {
try (RefCursor rc = t.seekRef(HEAD)) { try (RefCursor rc = t.seekRef(HEAD)) {
assertFalse(rc.next()); assertFalse(rc.next());
} }
try (RefCursor rc = t.seekPrefix(R_HEADS)) { try (RefCursor rc = t.seekRefsWithPrefix(R_HEADS)) {
assertFalse(rc.next()); assertFalse(rc.next());
} }
try (LogCursor rc = t.allLogs()) { try (LogCursor rc = t.allLogs()) {
@ -317,10 +317,10 @@ public void seekNotFound() throws IOException {
public void namespaceNotFound() throws IOException { public void namespaceNotFound() throws IOException {
Ref exp = ref(MASTER, 1); Ref exp = ref(MASTER, 1);
ReftableReader t = read(write(exp)); ReftableReader t = read(write(exp));
try (RefCursor rc = t.seekPrefix("refs/changes/")) { try (RefCursor rc = t.seekRefsWithPrefix("refs/changes/")) {
assertFalse(rc.next()); assertFalse(rc.next());
} }
try (RefCursor rc = t.seekPrefix("refs/tags/")) { try (RefCursor rc = t.seekRefsWithPrefix("refs/tags/")) {
assertFalse(rc.next()); assertFalse(rc.next());
} }
} }
@ -332,12 +332,12 @@ public void namespaceHeads() throws IOException {
Ref v1 = tag(V1_0, 3, 4); Ref v1 = tag(V1_0, 3, 4);
ReftableReader t = read(write(master, next, v1)); ReftableReader t = read(write(master, next, v1));
try (RefCursor rc = t.seekPrefix("refs/tags/")) { try (RefCursor rc = t.seekRefsWithPrefix("refs/tags/")) {
assertTrue(rc.next()); assertTrue(rc.next());
assertEquals(V1_0, rc.getRef().getName()); assertEquals(V1_0, rc.getRef().getName());
assertFalse(rc.next()); assertFalse(rc.next());
} }
try (RefCursor rc = t.seekPrefix("refs/heads/")) { try (RefCursor rc = t.seekRefsWithPrefix("refs/heads/")) {
assertTrue(rc.next()); assertTrue(rc.next());
assertEquals(MASTER, rc.getRef().getName()); assertEquals(MASTER, rc.getRef().getName());
@ -484,7 +484,7 @@ public void onlyReflog() throws IOException {
try (RefCursor rc = t.allRefs()) { try (RefCursor rc = t.allRefs()) {
assertFalse(rc.next()); assertFalse(rc.next());
} }
try (RefCursor rc = t.seekPrefix("refs/heads/")) { try (RefCursor rc = t.seekRefsWithPrefix("refs/heads/")) {
assertFalse(rc.next()); assertFalse(rc.next());
} }
try (LogCursor lc = t.allLogs()) { try (LogCursor lc = t.allLogs()) {

View File

@ -199,7 +199,7 @@ public boolean isNameConflicting(String refName) throws IOException {
} }
// Cannot be the container of an existing reference. // Cannot be the container of an existing reference.
return table.hasRef(refName + '/'); return table.hasRefsWithPrefix(refName + '/');
} finally { } finally {
lock.unlock(); lock.unlock();
} }
@ -241,7 +241,7 @@ public Map<String, Ref> getRefs(String prefix) throws IOException {
try { try {
Reftable table = reader(); Reftable table = reader();
try (RefCursor rc = ALL.equals(prefix) ? table.allRefs() try (RefCursor rc = ALL.equals(prefix) ? table.allRefs()
: (prefix.endsWith("/") ? table.seekPrefix(prefix) //$NON-NLS-1$ : (prefix.endsWith("/") ? table.seekRefsWithPrefix(prefix) //$NON-NLS-1$
: table.seekRef(prefix))) { : table.seekRef(prefix))) {
while (rc.next()) { while (rc.next()) {
Ref ref = table.resolve(rc.getRef()); Ref ref = table.resolve(rc.getRef());
@ -266,7 +266,7 @@ public List<Ref> getRefsByPrefix(String prefix) throws IOException {
try { try {
Reftable table = reader(); Reftable table = reader();
try (RefCursor rc = ALL.equals(prefix) ? table.allRefs() try (RefCursor rc = ALL.equals(prefix) ? table.allRefs()
: table.seekPrefix(prefix)) { : table.seekRefsWithPrefix(prefix)) {
while (rc.next()) { while (rc.next()) {
Ref ref = table.resolve(rc.getRef()); Ref ref = table.resolve(rc.getRef());
if (ref != null && ref.getObjectId() != null) { if (ref != null && ref.getObjectId() != null) {

View File

@ -113,10 +113,10 @@ public RefCursor seekRef(String name) throws IOException {
/** {@inheritDoc} */ /** {@inheritDoc} */
@Override @Override
public RefCursor seekPrefix(String prefix) throws IOException { public RefCursor seekRefsWithPrefix(String prefix) throws IOException {
MergedRefCursor m = new MergedRefCursor(); MergedRefCursor m = new MergedRefCursor();
for (int i = 0; i < tables.length; i++) { for (int i = 0; i < tables.length; i++) {
m.add(new RefQueueEntry(tables[i].seekPrefix(prefix), i)); m.add(new RefQueueEntry(tables[i].seekRefsWithPrefix(prefix), i));
} }
return m; return m;
} }

View File

@ -135,7 +135,7 @@ public void setIncludeDeletes(boolean deletes) {
* @throws java.io.IOException * @throws java.io.IOException
* if references cannot be read. * if references cannot be read.
*/ */
public abstract RefCursor seekPrefix(String prefix) throws IOException; public abstract RefCursor seekRefsWithPrefix(String prefix) throws IOException;
/** /**
* Match references pointing to a specific object. * Match references pointing to a specific object.
@ -202,24 +202,32 @@ public Ref exactRef(String refName) throws IOException {
} }
/** /**
* Test if a reference or reference subtree exists. * Test if a reference exists.
* <p>
* If {@code refName} ends with {@code "/"}, the method tests if any
* reference starts with {@code refName} as a prefix.
* <p>
* Otherwise, the method checks if {@code refName} exists.
* *
* @param refName * @param refName
* reference name or subtree to find. * reference name or subtree to find.
* @return {@code true} if the reference exists, or at least one reference * @return {@code true} if the reference exists.
* exists in the subtree.
* @throws java.io.IOException * @throws java.io.IOException
* if references cannot be read. * if references cannot be read.
*/ */
public boolean hasRef(String refName) throws IOException { public boolean hasRef(String refName) throws IOException {
try (RefCursor rc = seekPrefix(refName)) { try (RefCursor rc = seekRef(refName)) {
return rc.next() && (refName.endsWith("/") //$NON-NLS-1$ return rc.next();
|| refName.equals(rc.getRef().getName())); }
}
/**
* Test if any reference starts with {@code prefix} as a prefix.
*
* @param prefix
* prefix to find.
* @return {@code true} if at least one reference exists with prefix.
* @throws java.io.IOException
* if references cannot be read.
*/
public boolean hasRefsWithPrefix(String prefix) throws IOException {
try (RefCursor rc = seekRefsWithPrefix(prefix)) {
return rc.next();
} }
} }

View File

@ -190,7 +190,7 @@ public RefCursor seekRef(String refName) throws IOException {
/** {@inheritDoc} */ /** {@inheritDoc} */
@Override @Override
public RefCursor seekPrefix(String prefix) throws IOException { public RefCursor seekRefsWithPrefix(String prefix) throws IOException {
initRefIndex(); initRefIndex();
byte[] key = prefix.getBytes(CHARSET); byte[] key = prefix.getBytes(CHARSET);