|
17 | 17 | LIRS_init, |
18 | 18 | TwoQ_init, |
19 | 19 | SLRU_init, |
| 20 | + LRU_K_init, |
| 21 | + MQ_init, |
20 | 22 | # Advanced algorithms |
21 | 23 | S3FIFO_init, |
22 | 24 | Sieve_init, |
23 | 25 | WTinyLFU_init, |
24 | 26 | LeCaR_init, |
25 | 27 | LFUDA_init, |
26 | 28 | ClockPro_init, |
| 29 | + Clock2QPlus_init, |
27 | 30 | Cacheus_init, |
28 | 31 | # Optimal algorithms |
29 | 32 | Belady_init, |
@@ -231,6 +234,36 @@ def __init__( |
231 | 234 | ) |
232 | 235 |
|
233 | 236 |
|
| 237 | +class LRUK(CacheBase): |
| 238 | + """LRU-K: evict the object with the largest backward K-distance |
| 239 | +
|
| 240 | + Objects accessed fewer than K times have an infinite backward K-distance |
| 241 | + and are evicted first in FIFO order. |
| 242 | +
|
| 243 | + Special parameters: |
| 244 | + k: the number of recent accesses to track (default: 2) |
| 245 | + """ |
| 246 | + |
| 247 | + def __init__( |
| 248 | + self, |
| 249 | + cache_size: int | float, |
| 250 | + default_ttl: int = 86400 * 300, |
| 251 | + hashpower: int = 24, |
| 252 | + consider_obj_metadata: bool = False, |
| 253 | + k: int = 2, |
| 254 | + admissioner: AdmissionerBase = None, |
| 255 | + reader: ReaderProtocol = None, |
| 256 | + ): |
| 257 | + cache_specific_params = f"k={k}" |
| 258 | + super().__init__( |
| 259 | + _cache=LRU_K_init( |
| 260 | + _create_common_params(cache_size, default_ttl, hashpower, consider_obj_metadata, reader), |
| 261 | + cache_specific_params, |
| 262 | + ), |
| 263 | + admissioner=admissioner |
| 264 | + ) |
| 265 | + |
| 266 | + |
234 | 267 | class FIFO(CacheBase): |
235 | 268 | """First In First Out cache (no special parameters)""" |
236 | 269 |
|
@@ -447,12 +480,51 @@ def __init__( |
447 | 480 | ) |
448 | 481 |
|
449 | 482 |
|
| 483 | +class MQ(CacheBase): |
| 484 | + """Multi-Queue replacement algorithm |
| 485 | +
|
| 486 | + Objects are held in a hierarchy of LRU queues ordered by access frequency; |
| 487 | + an object that is not re-accessed within its lifetime is demoted to the |
| 488 | + next lower queue. Evicted objects keep their frequency in a FIFO ghost |
| 489 | + queue (Qout). |
| 490 | +
|
| 491 | + Special parameters: |
| 492 | + n_queue: number of queues in the hierarchy, must be in [1, 64] (default: 8) |
| 493 | + lifetime: number of requests an object may stay in its queue without being |
| 494 | + accessed before it is demoted (default: 10000) |
| 495 | + qout_size_ratio: size of the Qout ghost queue relative to the cache size, |
| 496 | + must be in (0, 64] (default: 4.0) |
| 497 | + """ |
| 498 | + |
| 499 | + def __init__( |
| 500 | + self, |
| 501 | + cache_size: int | float, |
| 502 | + default_ttl: int = 86400 * 300, |
| 503 | + hashpower: int = 24, |
| 504 | + consider_obj_metadata: bool = False, |
| 505 | + n_queue: int = 8, |
| 506 | + lifetime: int = 10000, |
| 507 | + qout_size_ratio: float = 4.0, |
| 508 | + admissioner: AdmissionerBase = None, |
| 509 | + reader: ReaderProtocol = None, |
| 510 | + ): |
| 511 | + cache_specific_params = f"n-queue={n_queue}, lifetime={lifetime}, Qout-size-ratio={qout_size_ratio}" |
| 512 | + super().__init__( |
| 513 | + _cache=MQ_init( |
| 514 | + _create_common_params(cache_size, default_ttl, hashpower, consider_obj_metadata, reader), |
| 515 | + cache_specific_params, |
| 516 | + ), |
| 517 | + admissioner=admissioner |
| 518 | + ) |
| 519 | + |
| 520 | + |
450 | 521 | class WTinyLFU(CacheBase): |
451 | 522 | """Window TinyLFU |
452 | 523 |
|
453 | 524 | Special parameters: |
454 | 525 | main_cache: the type of the main cache (default: "SLRU") |
455 | | - window_size: ratio of the window size to the main cache size (default: 0.01) |
| 526 | + window_size: ratio of the window LRU size to the total cache size, must be |
| 527 | + in [0, 1); the main cache receives the remainder (default: 0.01) |
456 | 528 | """ |
457 | 529 |
|
458 | 530 | def __init__( |
@@ -552,6 +624,45 @@ def __init__( |
552 | 624 | ) |
553 | 625 |
|
554 | 626 |
|
| 627 | +class Clock2QPlus(CacheBase): |
| 628 | + """Clock-2Q+ replacement algorithm |
| 629 | +
|
| 630 | + A 2Q variant that uses a small FIFO probationary queue in front of a Clock |
| 631 | + main cache, with a ghost queue and an adaptive correlation window. |
| 632 | +
|
| 633 | + Special parameters: |
| 634 | + fifo_size_ratio: ratio of the FIFO queue size to the total cache size (default: 0.1) |
| 635 | + ghost_size_ratio: ratio of the ghost queue size to the total cache size (default: 0.9) |
| 636 | + move_to_main_threshold: number of hits before an object is promoted to the main cache (default: 1) |
| 637 | + corr_window_ratio: initial ratio of the correlation window to the FIFO queue size (default: 0.5) |
| 638 | + """ |
| 639 | + |
| 640 | + def __init__( |
| 641 | + self, |
| 642 | + cache_size: int | float, |
| 643 | + default_ttl: int = 86400 * 300, |
| 644 | + hashpower: int = 24, |
| 645 | + consider_obj_metadata: bool = False, |
| 646 | + fifo_size_ratio: float = 0.1, |
| 647 | + ghost_size_ratio: float = 0.9, |
| 648 | + move_to_main_threshold: int = 1, |
| 649 | + corr_window_ratio: float = 0.5, |
| 650 | + admissioner: AdmissionerBase = None, |
| 651 | + reader: ReaderProtocol = None, |
| 652 | + ): |
| 653 | + cache_specific_params = ( |
| 654 | + f"fifo-size-ratio={fifo_size_ratio}, ghost-size-ratio={ghost_size_ratio}, " |
| 655 | + f"move-to-main-threshold={move_to_main_threshold}, corr-window-ratio={corr_window_ratio}" |
| 656 | + ) |
| 657 | + super().__init__( |
| 658 | + _cache=Clock2QPlus_init( |
| 659 | + _create_common_params(cache_size, default_ttl, hashpower, consider_obj_metadata, reader), |
| 660 | + cache_specific_params, |
| 661 | + ), |
| 662 | + admissioner=admissioner |
| 663 | + ) |
| 664 | + |
| 665 | + |
555 | 666 | class Cacheus(CacheBase): |
556 | 667 | """Cacheus algorithm (no special parameters)""" |
557 | 668 |
|
@@ -606,7 +717,8 @@ def __init__( |
606 | 717 | admissioner: AdmissionerBase = None, |
607 | 718 | reader: ReaderProtocol = None, |
608 | 719 | ): |
609 | | - cache_specific_params = f"n-samples={n_samples}" |
| 720 | + # NOTE: the C parser accepts "n-sample" (singular) |
| 721 | + cache_specific_params = f"n-sample={n_samples}" |
610 | 722 | super().__init__( |
611 | 723 | _cache=BeladySize_init( |
612 | 724 | _create_common_params(cache_size, default_ttl, hashpower, consider_obj_metadata, reader), |
|
0 commit comments