Skip to content

Conversation

AlexSutila
Copy link
Contributor

This PR adds the following features, without requiring any additional changes to the underlying libCacheSim backend:

  1. The following bindings for the existing admission policies in libCacheSim, BloomFilterAdmissioner, ProbAdmissioner, SizeAdmissioner, SizeProbabilisticAdmissioner, and AdaptSizeAdmissioner. Arguments that would otherwise be passed through cli can now be configured optionally through the constructors of these classes. Example below:
from libcachesim import SizeAdmissioner, LRU

'''
Both of these invoke the corresponding `create_size_admissioner` function in
the C++ backend. Either one of these is an option, if no arguments are provided
it will fallback to whatever `create_size_admissioner` uses by default.

If the default values within the C++ backend change for what ever reason, there
is no reason to modify the python binding code.
'''
adm = SizeAdmissioner(size_threshold=100)
adm = SizeAdmissioner()
lru = LRU(cache_size=1024, admissioner=adm)
  • Here is also a quick sanity check to make sure things add up via looking at the info statements coming from the backend when the code I showed up above is run (ignore the fact that the script I'm running here is called bloomfilter.py lol):
image
  1. A PluginAdmissioner which is similar to the PluginCache in nature, allowing custom admission policies to be defined easily through hooks to each function pointer in struct admissioner_t.

  2. I've included an additional admission directory under examples showing how to use existing policies and also the PluginAdmissioner with a toy example that randomly admits 10% of incoming requests and tracks the admit rate, displaying it in the free hook as another sanity check. From what I've seen the admit rate has always been reasonably close.

image

Lastly, I feel it is still worth mentioning that providing an admissioner at all is still optional and the library should continue to work as it did otherwise if no admissioner is provided.

Copy link
Contributor

Summary of Changes

Hello @AlexSutila, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly enhances the libCacheSim Python interface by integrating cache admission policies. It provides direct Python access to a suite of pre-existing C++ admission algorithms and introduces a flexible mechanism for users to implement their own custom admission logic. This expansion allows for more nuanced cache simulation and analysis, empowering users to experiment with various strategies for managing cache content effectively, all while preserving the library's ease of use and existing functionality.

Highlights

  • Python Bindings for Admission Policies: Introduced Python bindings for several existing libCacheSim admission policies, including BloomFilterAdmissioner, ProbAdmissioner, SizeAdmissioner, SizeProbabilisticAdmissioner, and AdaptSizeAdmissioner. These policies can now be configured directly through their Python constructors.
  • PluginAdmissioner for Custom Policies: Added a new PluginAdmissioner class, which allows users to define custom admission policies using Python hooks, similar to the PluginCache functionality.
  • New Examples and Documentation: Included a new admission directory under examples with scripts demonstrating the usage of both existing admission policies and the new PluginAdmissioner.
  • Optional Admissioner Integration: Ensured that providing an admissioner remains optional, maintaining backward compatibility with existing libCacheSim usage where no admission policy is specified.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
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 Python bindings for cache admission policies, a valuable addition that enhances the library's flexibility. The implementation includes bindings for existing policies and a PluginAdmissioner for custom logic, complete with examples. While the overall approach is sound, I've identified a couple of critical memory management issues in the C++ bindings that must be addressed. Additionally, there are several suggestions for the Python code to improve type safety, robustness, and adherence to conventions. Addressing these points will significantly improve the quality and reliability of this new feature.

Comment on lines +105 to +109
static void pypluginAdmissioner_free(admissioner_t *admissioner) {
pypluginAdmissioner_params_t *params =
(pypluginAdmissioner_params_t *)admissioner->params;
params->admissioner_free_hook(params->data);
}
Copy link
Contributor

Choose a reason for hiding this comment

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

critical

The pypluginAdmissioner_free function calls the Python free_hook but fails to deallocate the pypluginAdmissioner_params_t struct, which was allocated using new. This results in a memory leak every time a PluginAdmissioner is destroyed. The implementation should be updated to ensure proper cleanup by using a std::unique_ptr with the custom deleter, similar to the pattern in pypluginCache_free.

static void pypluginAdmissioner_free(admissioner_t *admissioner) {
  if (!admissioner || !admissioner->params) {
    return;
  }
  // Take ownership to ensure proper cleanup via the custom deleter.
  std::unique_ptr<pypluginAdmissioner_params_t, PypluginAdmissionerParamsDeleter> params_deleter(
      static_cast<pypluginAdmissioner_params_t *>(admissioner->params));
  admissioner->params = nullptr;
}



def admit_hook(data, request):
admit = random.randint(1, 10) == 5
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

Using random.randint(1, 10) == 5 to achieve a 10% probability is functionally correct but can be a bit obscure. A more idiomatic and clearer way to express this probability is by using random.random() < 0.1.

Suggested change
admit = random.randint(1, 10) == 5
admit = random.random() < 0.1

@1a1a11a
Copy link
Member

1a1a11a commented Sep 23, 2025

Can you add tests and documentation?

@AlexSutila
Copy link
Contributor Author

Can you add tests and documentation?

Yes, I will try to do so later tonight if I am able to find the time.

Copy link
Collaborator

@haochengxia haochengxia left a comment

Choose a reason for hiding this comment

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

Thanks for your PR. Looks good to me overall, just a few comments.

@AlexSutila
Copy link
Contributor Author

Thanks for your PR. Looks good to me overall, just a few comments.

Understood, I'm in agreement with all suggestions mentioned above. I was able to write some admissioner tests this morning, and will be sure to mention the extra optional arguments when I add to the documentation. I'll try to push something out addressing all the above soon.

Thank you.

@AlexSutila
Copy link
Contributor Author

AlexSutila commented Sep 27, 2025

I have just pushed a few more commits which do the following:

  1. I addressed the comments regarding the additions in export_*.cpp, and the type hints within the Python wrapper classes
  2. I have written a handful of tests for some of the admission bindings (not all of them because I couldn't think of a way to test some of them deterministically), including the PluginAdmissioner
  3. Finally, I added some info to the docs regarding everything I added in this PR

Some notes on the docs, I felt writing about the admission bindings for existing admission algorithms under the Cache Simulation page made the most sense. Since this page was initially blank, I also tried to document some of the existing replacement policies as well before showing documentation for admissioners.

Final note on the docs, similar to PluginCache, I wrote the documentation for PluginAdmissioner under the Plugin System page, just because it felt appropriate. Ofc, if you feel anything I added to the docs is best placed somewhere else I have no issues moving any of it.

Copy link
Member

@1a1a11a 1a1a11a left a comment

Choose a reason for hiding this comment

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

Great work! LGTM.

@1a1a11a
Copy link
Member

1a1a11a commented Sep 27, 2025

I will leave it to @haochengxia to merge it.

Copy link
Contributor

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR adds comprehensive Python bindings for cache admission policies in libCacheSim, enabling users to apply admission policies to existing cache algorithms without modifying the underlying C++ backend. The main purpose is to provide both bindings for existing admission policies (BloomFilter, Prob, Size, SizeProbabilistic, AdaptSize) and a plugin system for custom admission policies.

Key changes include:

  • Bindings for existing admission policies with configurable parameters
  • A PluginAdmissioner system allowing custom admission policies via Python hooks
  • Integration of admission policies into all cache classes through an optional admissioner parameter

Reviewed Changes

Copilot reviewed 13 out of 13 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
src/export_admissioner.cpp Core C++ bindings for admission policies and plugin system implementation
libcachesim/admissioner.py Python wrapper classes for admission policies including the plugin system
libcachesim/cache.py Integration of admission policies into all cache classes via optional parameter
tests/test_admission.py Comprehensive test suite for all admission policy types
examples/admission/ Example usage of both existing and custom admission policies
docs/src/en/examples/ Documentation updates for admission policies and plugin system

@haochengxia
Copy link
Collaborator

LGTM. Thank you!

@haochengxia haochengxia merged commit 00482c9 into cacheMon:main Sep 29, 2025
18 checks passed
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.

3 participants