Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

floorEntry on BTreeMap behaves incorrectly on border cases #95

Open
michaelpisula opened this issue Sep 12, 2012 · 0 comments
Open

floorEntry on BTreeMap behaves incorrectly on border cases #95

michaelpisula opened this issue Sep 12, 2012 · 0 comments

Comments

@michaelpisula
Copy link

I noticed some irregularities in the floorEntry Method on the BTreeMap, so I extended one of your test cases in BTreeMapNavigableTest:

public void testFloorEntry()
{
    navigableMap.put("ka", "xx");
    navigableMap.put("kc", "aa");
    navigableMap.put("kd", "zz");
    Entry<String, String> floorEntry = navigableMap.floorEntry("ka");
    assertEquals("bad floor entry value", "xx", floorEntry.getValue());
    assertEquals("bad floor entry key", "ka", floorEntry.getKey());
    floorEntry = navigableMap.floorEntry("kb");
    assertEquals("bad floor entry value", "xx", floorEntry.getValue());
    assertEquals("bad floor entry key", "ka", floorEntry.getKey());
    floorEntry = navigableMap.floorEntry("ke");
    assertEquals("bad floor entry value", "zz", floorEntry.getValue());
    assertEquals("bad floor entry key", "kd", floorEntry.getKey());
    floorEntry = navigableMap.floorEntry("k0");
    assertEquals("bad floor entry value", null, floorEntry);
    assertEquals("bad floor entry key", null, floorEntry);
}

Result is a NPE in the comparator. Commenting out the "ke" part, the result for "k0" is "ka". Ran the same tests against the Java TreeMap, and the test succeeded, so I am positive that this should be the expected behaviour ;-)

I made some changes in BTreeMap that fixed the tests for me:
public K floorKey(K key)
{
if (isEmpty())
return null;

    K key2 = Utils.max(key, fromKey, comparator());
    try
    {
        BTree.BTreeTupleBrowser<K, V> b = tree.browse(key2, true);
        BTree.BTreeTuple<K, V> t = new BTree.BTreeTuple<K, V>();
        b.getNext(t);
        K firstGuess = t.key;
        if (t.key == null)
        {
            // Bigger than biggest key
            b.getPrevious(t);
            return t.key;
        }
        Comparator comp = comparator();
        if (comp == null)
            comp = Utils.COMPARABLE_COMPARATOR;
        if (comp.compare(t.key, key2) == 0)
            return t.key;

        b.getPrevious(t);
        b.getPrevious(t);
        if (firstGuess == t.key)
            return null;
        return t.key;

    }
    catch (IOException e)
    {
        throw new IOError(e);
    }
}

New code is the null-check of t.key, and the check if the found entry is still the same after two previous operations.
Probably you can come up with a more elegant solution due to your knowledge of the code, but I hope this information is still of use to you.

Cheers,
Michael

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant