Skip to content

Add MultiQueue (MQ) eviction algorithm#307

Open
1a1a11a wants to merge 1 commit intodevelopfrom
codex/add-multi-queue-algorithm
Open

Add MultiQueue (MQ) eviction algorithm#307
1a1a11a wants to merge 1 commit intodevelopfrom
codex/add-multi-queue-algorithm

Conversation

@1a1a11a
Copy link
Owner

@1a1a11a 1a1a11a commented Mar 14, 2026

Motivation

  • Provide a frequency-aware multi-queue eviction policy (MQ) to complement existing eviction algorithms and offer a configurable, lightweight multi-LRU design that promotes objects across queues based on logarithmic frequency.

Description

  • Added new implementation MultiQueue at libCacheSim/cache/eviction/MultiQueue.c that tracks objects in multiple LRU queues and promotes them by logarithmic-frequency levels, with a default of 8 queues and a parseable n-queue (n-queues/nq) parameter.
  • Integrated the algorithm into the public API by adding MultiQueue_init to libCacheSim/include/libCacheSim/evictionAlgo.h.
  • Registered CLI names/aliases (mq, multi-queue, multiqueue) in libCacheSim/bin/cachesim/cache_init.h so the algorithm can be selected by the simulator frontend.
  • Added eviction/MultiQueue.c to libCacheSim/cache/CMakeLists.txt and updated README.md to list MultiQueue among supported eviction algorithms.

Testing

  • Ran automated integration checks (rg/sed inspections) to verify new symbols, file additions, and registrations succeeded and found the new files referenced in header, CMake, and README (success).
  • Attempted a configuration build with cmake -S . -B build which failed due to a missing system dependency: Package 'glib-2.0', required by 'virtual:world', not found, so a full compile/test run could not be completed in this environment.
  • No unit tests were present/added for MQ as part of this change; basic runtime wiring was validated by the file/registration checks above.

Codex Task

@1a1a11a 1a1a11a requested a review from haochengxia as a code owner March 14, 2026 23:39
Copilot AI review requested due to automatic review settings March 14, 2026 23:39
@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello, 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 introduces the MultiQueue (MQ) cache eviction algorithm, a frequency-aware policy designed to enhance cache performance by managing objects across multiple LRU queues based on their logarithmic frequency. This new algorithm expands the simulator's capabilities, offering a configurable multi-LRU design to complement existing eviction strategies.

Highlights

  • New Eviction Algorithm: Implemented the MultiQueue (MQ) eviction algorithm, a frequency-aware policy that uses multiple LRU queues to manage objects based on logarithmic frequency.
  • API Integration: Integrated the new MultiQueue algorithm into the public API by adding MultiQueue_init to libCacheSim/include/libCacheSim/evictionAlgo.h.
  • CLI Support: Registered command-line interface (CLI) names and aliases (mq, multi-queue, multiqueue) in libCacheSim/bin/cachesim/cache_init.h for selecting the MultiQueue algorithm.
  • Build and Documentation Updates: Updated libCacheSim/cache/CMakeLists.txt to include the new source file and README.md to list MultiQueue among supported eviction algorithms.
Changelog
  • README.md
    • Added "MultiQueue" to the list of supported eviction algorithms.
  • libCacheSim/bin/cachesim/cache_init.h
    • Registered "mq", "multi-queue", and "multiqueue" as CLI aliases for MultiQueue_init.
  • libCacheSim/cache/CMakeLists.txt
    • Included eviction/MultiQueue.c in the eviction_sources_c list.
  • libCacheSim/cache/eviction/MultiQueue.c
    • Added a new file implementing the MultiQueue (MQ) cache eviction policy.
    • Defined the MQ_params_t structure to manage multiple LRU queues.
    • Implemented MultiQueue_init to initialize the cache with configurable queue parameters.
    • Provided functions for MQ_free, MQ_get, MQ_find, MQ_insert, MQ_to_evict, MQ_evict, MQ_remove, and MQ_parse_params.
    • Included logic for promoting objects between queues based on logarithmic frequency.
  • libCacheSim/include/libCacheSim/evictionAlgo.h
    • Declared the MultiQueue_init function, making it available in the public API.
Activity
  • Automated integration checks (rg/sed inspections) were run to verify new symbols, file additions, and registrations, which succeeded.
  • A configuration build attempt with cmake -S . -B build failed due to a missing system dependency (Package 'glib-2.0', required by 'virtual:world', not found), preventing a full compile/test run.
  • No unit tests were present or added for the new MQ algorithm as part of this change; basic runtime wiring was validated by file/registration checks.
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
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

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 the Multi-Queue (MQ) eviction algorithm, a frequency-aware policy. The implementation is well-structured and follows the existing patterns in the codebase. However, there are several critical areas that need attention. Most importantly, the PR lacks unit tests for the new algorithm. Given that the author was unable to perform a full compile and test run due to environment issues, adding comprehensive tests in test/test_evictionAlgo.c is crucial to verify the correctness and prevent regressions. My review also identified several high-severity issues in MultiQueue.c, including missing NULL checks for memory allocations and a portability issue with a hardcoded metadata size. These should be addressed before merging.

cache->get_n_obj = cache_get_n_obj_default;

if (ccache_params.consider_obj_metadata) {
cache->obj_md_size = 8 * 2;
Copy link
Contributor

Choose a reason for hiding this comment

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

high

The metadata size is hardcoded as 8 * 2. This assumes a pointer size of 8 bytes, which is not portable across different architectures (e.g., 32-bit systems). It's better to use sizeof(cache_obj_t *) * 2 to calculate the size of the prev and next pointers dynamically, ensuring portability.

Suggested change
cache->obj_md_size = 8 * 2;
cache->obj_md_size = sizeof(cache_obj_t *) * 2;

cache->obj_md_size = 0;
}

cache->eviction_params = malloc(sizeof(MQ_params_t));
Copy link
Contributor

Choose a reason for hiding this comment

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

high

The memory allocated by malloc is not checked for NULL. If malloc fails, this will result in a NULL pointer dereference later, causing a crash. Please add a check for the return value and handle the error, for example by calling abort() as is done elsewhere in the project.

Comment on lines +78 to +81
params->q_heads = calloc(params->n_queue, sizeof(cache_obj_t *));
params->q_tails = calloc(params->n_queue, sizeof(cache_obj_t *));
params->q_n_bytes = calloc(params->n_queue, sizeof(int64_t));
params->q_n_objs = calloc(params->n_queue, sizeof(int64_t));
Copy link
Contributor

Choose a reason for hiding this comment

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

high

The memory allocated by these calloc calls is not checked for NULL. An allocation failure would lead to a crash when the returned pointers are dereferenced. Please add NULL checks for each allocation and handle potential failures gracefully.

static void MQ_parse_params(cache_t *cache, const char *cache_specific_params) {
MQ_params_t *params = (MQ_params_t *)cache->eviction_params;

char *params_str = strdup(cache_specific_params);
Copy link
Contributor

Choose a reason for hiding this comment

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

high

strdup can return NULL if memory allocation fails. This would cause a crash in the while loop condition or when strsep is called. Please add a NULL check for params_str after this line.

cache_obj_t *obj = cache_insert_base(cache, req);

obj->misc.freq = 1;
obj->SLRU.lru_id = 0;
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

The SLRU.lru_id field is being reused to store the queue level for an object. While this appears to be a common pattern in this codebase to avoid modifying cache_obj_t, it's not immediately obvious. Adding a comment here would improve code clarity and maintainability for future developers.

Suggested change
obj->SLRU.lru_id = 0;
obj->SLRU.lru_id = 0; // Use SLRU field to store MQ level

Copy link
Contributor

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 a new frequency-aware Multi-Queue (MQ) eviction policy to libCacheSim and wires it into the library API and simulator frontend so it can be selected via CLI.

Changes:

  • Implemented MultiQueue eviction algorithm with configurable n-queue / n-queues / nq parameter.
  • Exposed MultiQueue_init in the public eviction algorithm header and registered CLI aliases (mq, multi-queue, multiqueue).
  • Updated build system and documentation to include/list the new algorithm.

Reviewed changes

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

Show a summary per file
File Description
libCacheSim/include/libCacheSim/evictionAlgo.h Adds MultiQueue_init to the public eviction algorithm API.
libCacheSim/cache/eviction/MultiQueue.c New MQ eviction implementation (multi-LRU queues with log-frequency promotion).
libCacheSim/cache/CMakeLists.txt Adds MQ source file to the cache library build.
libCacheSim/bin/cachesim/cache_init.h Registers MQ names/aliases for simulator cache creation.
README.md Lists MultiQueue among supported eviction algorithms.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

Comment on lines +46 to +86
cache_t *MultiQueue_init(const common_cache_params_t ccache_params,
const char *cache_specific_params) {
cache_t *cache =
cache_struct_init("MultiQueue", ccache_params, cache_specific_params);
cache->cache_init = MultiQueue_init;
cache->cache_free = MQ_free;
cache->get = MQ_get;
cache->find = MQ_find;
cache->insert = MQ_insert;
cache->evict = MQ_evict;
cache->remove = MQ_remove;
cache->to_evict = MQ_to_evict;
cache->get_occupied_byte = cache_get_occupied_byte_default;
cache->can_insert = cache_can_insert_default;
cache->get_n_obj = cache_get_n_obj_default;

if (ccache_params.consider_obj_metadata) {
cache->obj_md_size = 8 * 2;
} else {
cache->obj_md_size = 0;
}

cache->eviction_params = malloc(sizeof(MQ_params_t));
memset(cache->eviction_params, 0, sizeof(MQ_params_t));
MQ_params_t *params = (MQ_params_t *)cache->eviction_params;

params->n_queue = 8;
MQ_parse_params(cache, DEFAULT_CACHE_PARAMS);
if (cache_specific_params != NULL) {
MQ_parse_params(cache, cache_specific_params);
}

params->q_heads = calloc(params->n_queue, sizeof(cache_obj_t *));
params->q_tails = calloc(params->n_queue, sizeof(cache_obj_t *));
params->q_n_bytes = calloc(params->n_queue, sizeof(int64_t));
params->q_n_objs = calloc(params->n_queue, sizeof(int64_t));

snprintf(cache->cache_name, CACHE_NAME_ARRAY_LEN, "MQ(%d)", params->n_queue);

return cache;
}
return obj;
}

obj->misc.freq += 1;
Comment on lines +202 to +208
while (params_str != NULL && params_str[0] != '\0') {
char *key = strsep((char **)&params_str, "=");
char *value = strsep((char **)&params_str, ",");

if (strcasecmp(key, "n-queue") == 0 || strcasecmp(key, "n-queues") == 0 ||
strcasecmp(key, "nq") == 0) {
params->n_queue = (int)strtol(value, NULL, 0);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants