diff --git a/ConflictSet.cpp b/ConflictSet.cpp index 92c7bce..6ce3d8a 100644 --- a/ConflictSet.cpp +++ b/ConflictSet.cpp @@ -1715,11 +1715,17 @@ struct SearchStepWise { } }; +void onPointRead(ConflictSet::Impl *impl); +void onPrefixRead(ConflictSet::Impl *impl); +void onRangeRead(ConflictSet::Impl *impl); +void onCheckMaxBetween(ConflictSet::Impl *impl); + // Logically this is the same as performing firstGeq and then checking against // point or range version according to cmp, but this version short circuits as // soon as it can prove that there's no conflict. bool checkPointRead(Node *n, const std::span key, InternalVersionT readVersion, ConflictSet::Impl *impl) { + onPointRead(impl); #if DEBUG_VERBOSE && !defined(NDEBUG) fprintf(stderr, "Check point read: %s\n", printable(key).c_str()); #endif @@ -1797,6 +1803,7 @@ downLeftSpine: // short circuits as soon as it can prove that there's no conflict. bool checkPrefixRead(Node *n, const std::span key, InternalVersionT readVersion, ConflictSet::Impl *impl) { + onPrefixRead(impl); #if DEBUG_VERBOSE && !defined(NDEBUG) fprintf(stderr, "Check prefix read: %s\n", printable(key).c_str()); #endif @@ -2312,6 +2319,7 @@ bool checkRangeStartsWith(Node *n, std::span key, int begin, #endif auto remaining = key; if (remaining.size() == 0) { + onCheckMaxBetween(impl); return checkMaxBetweenExclusive(n, begin, end, readVersion); } @@ -2408,6 +2416,7 @@ template struct CheckRangeLeftSide { } if (searchPathLen >= prefixLen) { + onCheckMaxBetween(impl); if (!checkMaxBetweenExclusive(n, remaining[0], 256, readVersion)) { ok = false; @@ -2538,6 +2547,7 @@ template struct CheckRangeRightSide { return true; } + onCheckMaxBetween(impl); if (!checkMaxBetweenExclusive(n, -1, remaining[0], readVersion)) { ok = false; @@ -2635,6 +2645,7 @@ template bool checkRangeReadImpl(Node *n, std::span begin, std::span end, InternalVersionT readVersion, ConflictSet::Impl *impl) { + onRangeRead(impl); int lcp = longestCommonPrefix(begin.data(), end.data(), std::min(begin.size(), end.size())); if (lcp == int(begin.size()) && end.size() == begin.size() + 1 && @@ -3068,6 +3079,10 @@ struct __attribute__((visibility("hidden"))) ConflictSet::Impl { ? Commit : Conflict; } + read_point_total.add(std::exchange(accume_point_read, 0)); + read_prefix_total.add(std::exchange(accume_prefix_read, 0)); + read_range_total.add(std::exchange(accume_range_read, 0)); + read_range_node_total.add(std::exchange(accume_max_between, 0)); } void addWrites(const WriteRange *writes, int count, int64_t writeVersion) { @@ -3101,6 +3116,8 @@ struct __attribute__((visibility("hidden"))) ConflictSet::Impl { this); } } + + memory_bytes.set(totalBytes); } // Spends up to `fuel` gc'ing, and returns its unused fuel. Reclaims memory @@ -3170,6 +3187,8 @@ struct __attribute__((visibility("hidden"))) ConflictSet::Impl { } #endif keyUpdates = gcScanStep(keyUpdates); + + memory_bytes.set(totalBytes); } int64_t getBytes() const { return totalBytes; } @@ -3283,6 +3302,17 @@ struct __attribute__((visibility("hidden"))) ConflictSet::Impl { "Total number of nodes of type \"Node48\" that have been released"); COUNTER(node256_released_total, "Total number of nodes of type \"Node256\" that have been released"); + GAUGE(memory_bytes, "Total number of bytes in use."); + double accume_point_read = 0; + COUNTER(read_point_total, "Total number of point reads checked."); + double accume_prefix_read = 0; + COUNTER(read_prefix_total, "Total number of prefix reads checked."); + double accume_range_read = 0; + COUNTER(read_range_total, "Total number of range reads checked."); + double accume_max_between = 0; + COUNTER(read_range_node_total, + "Total number of range checks of individual nodes while " + "checking a range read."); // ==================== END METRICS DEFINITIONS ==================== #undef GAUGE #undef COUNTER @@ -3334,6 +3364,11 @@ InternalVersionT maxVersion(Node *n, ConflictSet::Impl *impl) { } } +void onPointRead(ConflictSet::Impl *impl) { ++impl->accume_point_read; } +void onPrefixRead(ConflictSet::Impl *impl) { ++impl->accume_prefix_read; } +void onRangeRead(ConflictSet::Impl *impl) { ++impl->accume_range_read; } +void onCheckMaxBetween(ConflictSet::Impl *impl) { ++impl->accume_max_between; } + void setMaxVersion(Node *n, ConflictSet::Impl *impl, InternalVersionT newMax) { int index = n->parentsIndex; n = n->parent;