Skip to content

fix(S3FIFO): size sub-cache hash tables proportionally to avoid OOM#316

Open
manishpaulish wants to merge 2 commits into
1a1a11a:developfrom
manishpaulish:fix/s3fifo-proportional-hashpower
Open

fix(S3FIFO): size sub-cache hash tables proportionally to avoid OOM#316
manishpaulish wants to merge 2 commits into
1a1a11a:developfrom
manishpaulish:fix/s3fifo-proportional-hashpower

Conversation

@manishpaulish
Copy link
Copy Markdown

@manishpaulish manishpaulish commented Jun 6, 2026

Closes / addresses #137.

Problem

As profiled in #137 by @JasonGuo98, S3FIFO allocates four full-sized hash tables at init time (one per cache_struct_init call), each using HASH_POWER_DEFAULT = 23 → 8M buckets × 8 bytes = 128 MB. For a 1 GB cache this means ~512 MB allocated before a single object is stored.

Fix (Option 3 from the issue discussion)

Add a small helper s3fifo_hashpower_for_size() that computes the minimum hashpower needed for a sub-cache of the given byte size (ceil(log2(size / 8))), clamped to [1, HASH_POWER_DEFAULT].

Set ccache_params_local.hashpower before each of the three FIFO_init calls in S3FIFO_init, so each sub-cache starts with a table proportional to its actual configured size fraction rather than the full cache size.

Impact (1 GB cache, default 10/90 split)

Sub-cache Size Old table New table Saving
small FIFO 100 MB 128 MB 16 MB −112 MB
ghost FIFO 900 MB 128 MB 128 MB
main FIFO 900 MB 128 MB 128 MB

The small queue reduction alone saves ~112 MB on a 1 GB cache (8×). Larger caches see proportionally larger savings.

No behaviour change — hashpower only affects initial allocation, the table grows on demand as before.

Summary by CodeRabbit

  • Bug Fixes
    • Improved cache initialization for sub-caches: now computes and applies an appropriate internal sizing parameter based on requested sub-cache byte sizes, leading to better memory allocation and more consistent eviction behavior across different cache configurations.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Jun 6, 2026

Too many files changed? Review this PR in Change Stack to see how the pieces fit before you dive in.

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 6d62e937-1776-41d3-a455-c2143ccdbf38

📥 Commits

Reviewing files that changed from the base of the PR and between c8dc889 and 54ebe8a.

📒 Files selected for processing (1)
  • libCacheSim/cache/eviction/S3FIFO.c
🚧 Files skipped from review as they are similar to previous changes (1)
  • libCacheSim/cache/eviction/S3FIFO.c

📝 Walkthrough

Walkthrough

S3FIFO_init now computes a size-based hashpower via a new helper and assigns it to the small FIFO, optional ghost FIFO, and main FIFO before calling FIFO_init for each sub-cache.

Changes

S3FIFO Hashpower Configuration

Layer / File(s) Summary
Hashpower computation helper
libCacheSim/cache/eviction/S3FIFO.c
New s3fifo_hashpower_for_size() static inline helper derives hash table power from a target byte size, enforcing a minimum of 1 and clamping growth by HASH_POWER_DEFAULT.
Hashpower application in initialization
libCacheSim/cache/eviction/S3FIFO.c
S3FIFO_init sets ccache_params_local.hashpower for small FIFO and optional ghost FIFO using the helper, and applies computed hashpower to the main FIFO before each FIFO_init call.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

A rabbit pads through C and code so neat, 🐇
Hashpower counted to keep buckets meet,
Small, ghost, and main get numbers terse and true,
Each FIFO wakes with just the size it knew,
A tiny hop, a tidy cache review.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'fix(S3FIFO): size sub-cache hash tables proportionally to avoid OOM' accurately captures the main change: proportionally sizing hash tables in S3FIFO to prevent excessive memory allocation.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 Infer (1.2.0)
libCacheSim/cache/eviction/S3FIFO.c

libCacheSim/cache/eviction/S3FIFO.c:32:10: fatal error: 'dataStructure/hashtable/hashtable.h' file not found
32 | #include "dataStructure/hashtable/hashtable.h"
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1 error generated.
Error: the following clang command did not run successfully:
/opt/infer-linux-x86_64-v1.2.0/lib/infer/facebook-clang-plugins/clang/install/bin/clang-18
@/tmp/coderabbit-infer/54ebe8a8d815f9156db5ad006d909e34a2f5031e-a126e7aa447c55cd/tmp/clang_command_.tmp.46abba.txt
++Contents of '/tmp/coderabbit-infer/54ebe8a8d815f9156db5ad006d909e34a2f5031e-a126e7aa447c55cd/tmp/clang_command_.tmp.46abba.txt':
"-cc1" "-load"
"/opt/infer-linux-x86_64-v1.2.0/lib/infer/infer/bin/../../facebook-clang-plugins/libtooling/build/FacebookClangPlugin.dylib"
"-add-plugin" "BiniouASTExporter" "-plugin-arg-BiniouASTExporter" "-"
"-plugin-arg-BiniouASTExporter" "PREPEND_CURRENT_DIR=1"
"-plugin-arg-BiniouASTExporter" "MAX_STRING_SIZE=65535" "-cc1" "-tri

... [truncated 785 characters] ...

x86_64-v1.2.0/lib/infer/facebook-clang-plugins/clang/install/lib/clang/18/include"
"-internal-isystem" "/usr/local/include" "-internal-isystem"
"/usr/lib/gcc/x86_64-linux-gnu/12/../../../../x86_64-linux-gnu/include"
"-internal-externc-isystem" "/usr/include/x86_64-linux-gnu"
"-internal-externc-isystem" "/include" "-internal-externc-isystem"
"/usr/include" "-Wno-ignored-optimization-argument" "-Wno-everything"
"-ferror-limit" "19" "-fgnuc-version=4.2.1" "-fskip-odr-check-in-gmf"
"-D__GCC_HAVE_DWARF2_CFI_ASM=1" "-o"
"/tmp/coderabbit-infer/a126e7aa447c55cd/file.o" "-x" "c"
"libCacheSim/cache/eviction/S3FIFO.c" "-O0" "-fno-builtin" "-include"
"/opt/infer-linux-x86_64-v1.2.0/lib/infer/infer/bin/../lib/clang_wrappers/global_defines.h"
"-Wno-everything"


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a helper function s3fifo_hashpower_for_size to dynamically compute the initial hashpower for S3FIFO sub-caches (small, ghost, and main FIFOs) based on their byte sizes. However, a typo was introduced in the S3FIFO_init function signature where common_cache_params_t was misspelled as common_cacheparams_t, which will cause a compilation error.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread libCacheSim/cache/eviction/S3FIFO.c Outdated
return hp;
}

cache_t *S3FIFO_init(const common_cacheparams_t ccache_params,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

There is a typo in the parameter type: common_cacheparams_t should be common_cache_params_t. This will cause a compilation error.

cache_t *S3FIFO_init(const common_cache_params_t ccache_params,

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@libCacheSim/cache/eviction/S3FIFO.c`:
- Around line 91-93: The slot count uses truncating division (slots = size_bytes
/ 8) causing underestimates; change to ceil division so sizes just over a
boundary increment slots (compute slots using (size_bytes + 7) / 8 or
equivalent) before the loop that increments hp (the code that checks (1LL << hp)
< slots and compares to HASH_POWER_DEFAULT) so the while loop uses the correctly
rounded-up slot count.
- Line 96: The function signature for S3FIFO_init uses the incorrect type name
common_cacheparams_t; update the parameter type to the correct project type
common_cache_params_t in the S3FIFO_init declaration (and any corresponding
prototype/uses) so the compiler recognizes the type; ensure references to
ccache_params remain unchanged except for the corrected type name.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 9d1bca38-a916-4255-926c-b040bc9aac7b

📥 Commits

Reviewing files that changed from the base of the PR and between da022c2 and c8dc889.

📒 Files selected for processing (1)
  • libCacheSim/cache/eviction/S3FIFO.c

Comment on lines +91 to +93
int64_t slots = size_bytes / 8;
while ((1LL << hp) < slots && hp < HASH_POWER_DEFAULT) hp++;
return hp;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Round up slot count to match the intended ceil behavior.

slots = size_bytes / 8 truncates, so sizes just above a boundary are underestimated (e.g., 17 bytes computes like 16). Use ceil division before the loop.

Suggested fix
-    int64_t slots = size_bytes / 8;
-    while ((1LL << hp) < slots && hp < HASH_POWER_DEFAULT) hp++;
+    int64_t slots = (size_bytes + 7) / 8;
+    while (hp < HASH_POWER_DEFAULT && (1LL << hp) < slots) hp++;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
int64_t slots = size_bytes / 8;
while ((1LL << hp) < slots && hp < HASH_POWER_DEFAULT) hp++;
return hp;
int64_t slots = (size_bytes + 7) / 8;
while (hp < HASH_POWER_DEFAULT && (1LL << hp) < slots) hp++;
return hp;
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@libCacheSim/cache/eviction/S3FIFO.c` around lines 91 - 93, The slot count
uses truncating division (slots = size_bytes / 8) causing underestimates; change
to ceil division so sizes just over a boundary increment slots (compute slots
using (size_bytes + 7) / 8 or equivalent) before the loop that increments hp
(the code that checks (1LL << hp) < slots and compares to HASH_POWER_DEFAULT) so
the while loop uses the correctly rounded-up slot count.

Comment thread libCacheSim/cache/eviction/S3FIFO.c Outdated
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

Successfully merging this pull request may close these issues.

1 participant