diff --git a/HashTable.cpp b/HashTable.cpp index f76e8c2..c7f878a 100644 --- a/HashTable.cpp +++ b/HashTable.cpp @@ -96,7 +96,9 @@ void ConflictSet::setOldestVersion(int64_t oldestVersion) { return impl->setOldestVersion(oldestVersion); } -int64_t ConflictSet::getBytes() const { return -1; } +// The hash_table implementation does not track memory usage, so return 0 to +// satisfy the API contract that getBytes() returns a non-negative value. +int64_t ConflictSet::getBytes() const { return 0; } void ConflictSet::getMetricsV1(MetricsV1 **metrics, int *count) const { *metrics = nullptr; @@ -161,7 +163,10 @@ __attribute__((__visibility__("default"))) void ConflictSet_destroy(void *cs) { } __attribute__((__visibility__("default"))) int64_t ConflictSet_getBytes(void *cs) { - using Impl = ConflictSet::Impl; - return -1; + (void)cs; + // The hash_table implementation does not track memory usage, so return 0 to + // satisfy the API contract that ConflictSet_getBytes returns a non-negative + // value. + return 0; } } diff --git a/include/ConflictSet.h b/include/ConflictSet.h index f02c9ee..3822058 100644 --- a/include/ConflictSet.h +++ b/include/ConflictSet.h @@ -88,7 +88,8 @@ struct __attribute__((__visibility__("default"))) ConflictSet { ~ConflictSet(); - /** Returns the total bytes in use by this ConflictSet */ + /** Returns the total bytes in use by this ConflictSet. Implementations that + * do not track memory usage return 0. */ int64_t getBytes() const; /** Experimental! */ @@ -218,7 +219,8 @@ ConflictSet *ConflictSet_create(int64_t oldestVersion); void ConflictSet_destroy(ConflictSet *cs); -/** Returns the total bytes in use by this ConflictSet */ +/** Returns the total bytes in use by this ConflictSet. Implementations that + * do not track memory usage return 0. */ int64_t ConflictSet_getBytes(const ConflictSet *cs); #endif diff --git a/test_conflict_set.py b/test_conflict_set.py index 3c284ba..c530b79 100644 --- a/test_conflict_set.py +++ b/test_conflict_set.py @@ -57,6 +57,17 @@ def test_conflict_set(): assert cs.check(read(0, key), read(1, key)) == [Result.TOO_OLD, Result.COMMIT] +def test_hash_table_getBytes(): + # Regression test for issue #62: the hash_table implementation is + # point-query only and does not track memory usage, but getBytes() must + # still return a non-negative value rather than -1. + with ConflictSet(0, build_dir=build_dir, implementation="hash_table") as cs: + assert cs.getBytes() == 0 + cs.addWrites(1, write(b"key")) + assert cs.getBytes() >= 0 + assert cs.check(read(0, b"key")) == [Result.CONFLICT] + + def test_write_read_without_outer_reference(): # Regression test for issue #42: WriteRange/ReadRange must keep their # backing key buffers alive, because the C library reads the pointer