hollow icon indicating copy to clipboard operation
hollow copied to clipboard

long-typed primary key with a value of 0 cannot be accessed depending on the complexity of other long primary keys

Open jkade opened this issue 6 years ago • 1 comments

I've been playing around with storing different data in a Hollow snapshot, and came across an alarming issue in Hollow 3.4.5 that I don't see reported elsewhere.

Using the model:

@HollowPrimaryKey(fields={"id"})
public class Movie {
    long id;
    String title;
    int releaseYear;
}

I've written some tests using hollow-test that seem to show a bug happening depending on how big the long value I use as a primary key index is.

public class HollowZeroLongDemo {
 
    @Test
    public void testZeroLongPrimaryKey_withSmallLong() throws IOException {
        MoviePrimaryKeyIndex moviePrimaryKeyIndex = initializePrimaryKeyIndex(5L);
 
        assertEquals("The Matrix", moviePrimaryKeyIndex.findMatch(5L).getTitle());
        assertEquals("Pulp Fiction", moviePrimaryKeyIndex.findMatch(3L).getTitle());
 
        //No problem!
        assertEquals("Beasts of No Nation", moviePrimaryKeyIndex.findMatch(0L).getTitle());
    }
 
    @Test
    public void testZeroLongPrimaryKey_withBigLong() throws IOException {
        MoviePrimaryKeyIndex moviePrimaryKeyIndex = initializePrimaryKeyIndex(9223372034562340851L);
 
        assertEquals("The Matrix", moviePrimaryKeyIndex.findMatch(9223372034562340851L).getTitle());
        assertEquals("Pulp Fiction", moviePrimaryKeyIndex.findMatch(3L).getTitle());
 
        //Problem!
        assertEquals("Beasts of No Nation", moviePrimaryKeyIndex.findMatch(0L).getTitle());
    }
 
    private MoviePrimaryKeyIndex initializePrimaryKeyIndex(long bigOrLittleLongId) throws IOException {
        final HollowWriteStateEngineBuilder hollowWriteStateEngineBuilder = new HollowWriteStateEngineBuilder();
        Arrays.asList(
                new Movie(longOrShortLongId, "The Matrix", 1999),
                new Movie(0L, "Beasts of No Nation", 2015),
                new Movie(3L, "Pulp Fiction", 1994)
        ).forEach(hollowWriteStateEngineBuilder::add);
        HollowWriteStateEngine writeStateEngine = hollowWriteStateEngineBuilder.build();
 
        TestHollowConsumer consumer = new TestHollowConsumer.Builder()
                .withAnnouncementWatcher(new TestAnnouncementWatcher().setLatestVersion(2L))
                .withBlobRetriever(new TestBlobRetriever())
                .withGeneratedAPIClass(MovieAPI.class)
                .build();
 
        consumer.addSnapshot(latestVersion, writeStateEngine);
        consumer.triggerRefresh();
 
        return new MoviePrimaryKeyIndex(consumer);
    }
}

Calling moviePrimaryKeyIndex.findMatch(0L) returns a result in the first test, but a null in the second test.

If I knew for sure why this happened for 0-value ids, and could be certain that only 0-value ids affected, I wouldn't be so concerned, but I haven't comprehended the bitshifting going on well enough to be sure this only will happen for 0-value ids.

I haven't tested this with 4.2 yet, but none of the changes I've looked at seem extremely likely to remedy this bug.

jkade avatar Feb 21 '19 20:02 jkade

@jkade, thanks for the report and test case to reproduce.

I was able to reproduce with a narrower test in #400. Still investigating the root cause.

It does seem like an interaction between keys of value 0, though I need to dig further before I can confirm that.

ghost avatar Feb 22 '19 22:02 ghost