Skip to content

Commit

Permalink
feat: finish new cache algorithm s3-fifo
Browse files Browse the repository at this point in the history
Signed-off-by: Certseeds <[email protected]>
  • Loading branch information
Certseeds committed Mar 3, 2024
1 parent d7a66e4 commit c4dc1bd
Show file tree
Hide file tree
Showing 10 changed files with 217 additions and 29 deletions.
2 changes: 1 addition & 1 deletion algorithm/cs302/cache/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")


enable_testing()
set(dependencies lru no fifo fifo_sc clock min)
set(dependencies lru no fifo fifo_sc clock min s3fifo)
foreach (elementName IN LISTS dependencies)
add_executable(${PROJECT_NAME}_${elementName}_test ${CMAKE_CURRENT_SOURCE_DIR}/${elementName}_cache.cpp)
target_link_libraries(${PROJECT_NAME}_${elementName}_test CS203_DSAA_template_INCLUDE)
Expand Down
2 changes: 1 addition & 1 deletion algorithm/cs302/cache/cache_base.hpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
/* CS203_DSAA_template
Copyright (C) 2022-2023 nanoseeds
Copyright (C) 2022-2024 nanoseeds
*/
#ifndef CS203_DSAA_TEMPLATE_ALGORITHM_CACHE_CACHE_BASE_HPP
#define CS203_DSAA_TEMPLATE_ALGORITHM_CACHE_CACHE_BASE_HPP
Expand Down
18 changes: 9 additions & 9 deletions algorithm/cs302/cache/clock_cache.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
/* CS203_DSAA_template
Copyright (C) 2022-2023 nanoseeds
Copyright (C) 2022-2024 nanoseeds
*/
#ifdef CS203_DSAA_TEST_MACRO

Expand All @@ -21,27 +21,27 @@ static constexpr const auto init = true;
namespace initFalse {
static constexpr const std::array<const std::pair<size_t, const char *const>, 8> pairs{
{
{5, "4.data.in"},
{2, "sample.data.in"},
{1177, "1.data.in"},
{11848, "2.data.in"},
{82382, "3.data.in"},
{5, "4.data.in"},
{5, "5.data.in"},
{6, "6.data.in"},
{1, "7.data.in"},
{1177, "1.data.in"},
{11848, "2.data.in"},
{82382, "3.data.in"},
}};
}
namespace initTrue {
static constexpr const std::array<const std::pair<size_t, const char *const>, 8> pairs{
{
{2, "4.data.in"},
{1, "sample.data.in"},
{1193, "1.data.in"},
{11826, "2.data.in"},
{82382, "3.data.in"},
{2, "4.data.in"},
{5, "5.data.in"},
{4, "6.data.in"},
{2, "7.data.in"},
{1193, "1.data.in"},
{11826, "2.data.in"},
{82382, "3.data.in"},
}};
}
namespace On {
Expand Down
8 changes: 4 additions & 4 deletions algorithm/cs302/cache/fifo_cache.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
/* CS203_DSAA_template
Copyright (C) 2022-2023 nanoseeds
Copyright (C) 2022-2024 nanoseeds
*/
#ifdef CS203_DSAA_TEST_MACRO

Expand All @@ -17,13 +17,13 @@ using std::array;
static constexpr const std::array<const std::pair<size_t, const char *const>, 8> pairs{
{
{1, "sample.data.in"},
{1198, "1.data.in"},
{11854, "2.data.in"},
{82363, "3.data.in"},
{2, "4.data.in"},
{5, "5.data.in"},
{4, "6.data.in"},
{2, "7.data.in"},
{1198, "1.data.in"},
{11854, "2.data.in"},
{82363, "3.data.in"},
}};

namespace On {
Expand Down
10 changes: 5 additions & 5 deletions algorithm/cs302/cache/fifo_sc_cache.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
/* CS203_DSAA_template
Copyright (C) 2022-2023 nanoseeds
Copyright (C) 2022-2024 nanoseeds
*/
#ifdef CS203_DSAA_TEST_MACRO

Expand All @@ -16,14 +16,14 @@ namespace cache::fifo_sc {
using std::array;
static constexpr const std::array<const std::pair<size_t, const char *const>, 8> pairs{
{
{5, "4.data.in"},
{2, "sample.data.in"},
{1177, "1.data.in"},
{11848, "2.data.in"},
{82382, "3.data.in"},
{5, "4.data.in"},
{5, "5.data.in"},
{6, "6.data.in"},
{1, "7.data.in"},
{1177, "1.data.in"},
{11848, "2.data.in"},
{82382, "3.data.in"},
}};

namespace On {
Expand Down
8 changes: 4 additions & 4 deletions algorithm/cs302/cache/lru_cache.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
/* CS203_DSAA_template
Copyright (C) 2022-2023 nanoseeds
Copyright (C) 2022-2024 nanoseeds
*/
#ifdef CS203_DSAA_TEST_MACRO

Expand Down Expand Up @@ -33,13 +33,13 @@ using std::array;
static constexpr const std::array<const std::pair<size_t, const char *const>, 8> pairs{
{
{1, "sample.data.in"},
{1176, "1.data.in"},
{11847, "2.data.in"},
{82394, "3.data.in"},
{4, "4.data.in"},
{3, "5.data.in"},
{5, "6.data.in"},
{1, "7.data.in"},
{1176, "1.data.in"},
{11847, "2.data.in"},
{82394, "3.data.in"},
}};
namespace On {

Expand Down
9 changes: 5 additions & 4 deletions algorithm/cs302/cache/min_cache.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
/* CS203_DSAA_template
Copyright (C) 2022-2023 nanoseeds
Copyright (C) 2022-2024 nanoseeds
*/
#ifdef CS203_DSAA_TEST_MACRO

Expand All @@ -17,13 +17,13 @@ using std::array;
static constexpr const std::array<const std::pair<size_t, const char *const>, 8> pairs{
{
{2, "sample.data.in"},
{4240, "1.data.in"},
{43265, "2.data.in"},
{88583, "3.data.in"},
{7, "4.data.in"},
{5, "5.data.in"},
{9, "6.data.in"},
{3, "7.data.in"},
{4240, "1.data.in"},
{43265, "2.data.in"},
{88583, "3.data.in"},
}};

/**
Expand Down Expand Up @@ -98,6 +98,7 @@ TEST_CASE("min test 1") {
const auto input = inputs::read_input();
const auto inputAll = [&input] {
vector<size_t> vec{};
vec.reserve(input.querys.size());
for (const auto ori: input.querys) {
vec.push_back(ori);
}
Expand Down
2 changes: 1 addition & 1 deletion algorithm/cs302/cache/no_cache.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
/* CS203_DSAA_template
Copyright (C) 2022-2023 nanoseeds
Copyright (C) 2022-2024 nanoseeds
*/
#ifdef CS203_DSAA_TEST_MACRO

Expand Down
184 changes: 184 additions & 0 deletions algorithm/cs302/cache/s3fifo_cache.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
/* CS203_DSAA_template
Copyright (C) 2024 nanoseeds
*/
#ifdef CS203_DSAA_TEST_MACRO

#include <catch_main.hpp>
#include <memory>
#include <queue>
#include "cache_base.hpp"

namespace cache::s3fifo {
using std::array;
static constexpr const std::array<const std::pair<size_t, const char *const>, 8> pairs{
{
{1, "sample.data.in"},
{4, "4.data.in"},
{1, "5.data.in"},
{4, "6.data.in"},
{0, "7.data.in"},
{1110, "1.data.in"},
{11873, "2.data.in"},
{82132, "3.data.in"},
// 这种大规模数据集对比lru只差一点点, 性能很好.
// 更贴合实际的数据集应该能更好.
}
};

namespace Origin {
// algorithm come from
// https://blog.jasony.me/system/cache/2023/08/01/s3fifo
class fifo_cache final {
public:
std::deque<std::pair<size_t, uint8_t>> fifo{};
size_t max_size{0};

explicit fifo_cache(size_t size) {
max_size = std::max(size_t(1), size);
}

bool exists_const(size_t page) const {
const auto pointer = std::find_if(std::begin(fifo), std::end(fifo),
[page](const std::pair<size_t, uint8_t> &pair) {
return pair.first == page;
});
return pointer != std::end(fifo);
}

bool exists(size_t page) {
const auto pointer = std::find_if(std::begin(fifo), std::end(fifo),
[page](const std::pair<size_t, uint8_t> &pair) {
return pair.first == page;
});
if (pointer == std::end(fifo)) {
return false;
}
pointer->second = std::min(3, pointer->second + 1);
return true;
}

bool isFull() const {
return fifo.size() == max_size;
}

bool isEmpty() const {
return fifo.empty();
}

std::pair<size_t, uint8_t> pop() {
assert(!fifo.empty());
const auto result = fifo.front();
fifo.pop_front();
return result;
}

void insert(size_t page, size_t times) {
if (!isFull()) {
fifo.emplace_back(page, times);
}
}
};

class s3fifo_cache final : public cache_base {
private:
fifo_cache small;
fifo_cache main;
fifo_cache ghost;

void insertToSmall(size_t page) {
if (small.isFull()) {
evictSmall();
}
small.insert(page, 0);
}

void insertToMain(size_t page, uint8_t times) {
if (main.isFull()) {
evictMain();
}
main.insert(page, times);
}

void insertToGhost(size_t page) {
if (!ghost.exists_const(page)) {
// 直接驱逐最后一个
if (ghost.isFull()) {
ghost.pop();
}
ghost.insert(page, 0);
}
}

void evictSmall() {
bool evicted = false;
while (!evicted && !small.isEmpty()) {
const auto result = small.pop();
if (result.second > 1) {
if (main.isFull()) {
evictMain();
insertToMain(result.first, 0);
}
} else {
insertToGhost(result.first);
evicted = true;
}
}
}

void evictMain() {
bool evicted = false;
while (!evicted && !main.isEmpty()) {
const auto result = main.pop();
if (result.second > 0) {
insertToMain(result.first, result.second - 1);
} else {
evicted = true;
}
}
}

public:
explicit s3fifo_cache(size_t page) : cache_base(page), small(page / 10), main(page * 9 / 10),
ghost(page * 9 / 10) {}

virtual bool exists(size_t value) const override {
if (small.exists_const(value) || main.exists_const(value)) {
return true;
}
return false;
}

// read true if match
virtual bool read(size_t page) override {
if (small.exists(page) || main.exists(page)) {
return true;
} // cache miss
if (ghost.exists_const(page)) {
insertToMain(page, 0);
} else {
insertToSmall(page);
}
return false;
}


};

TEST_CASE("fifo test n") {
for (const auto &[result, file_name]: pairs) {
const CS203_redirect cr{file_name};
const auto input = inputs::read_input();
const auto cache = std::make_unique<s3fifo_cache>(input.cacheSize);
size_t hits{0};
for (const auto iter: input.querys) {
const auto exist = cache->read(iter);
hits += exist;
}
CHECK(result == hits);
}
}
}

}
#endif
3 changes: 3 additions & 0 deletions algorithm/queue/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# queue

TODO: using ring buffer to simulate a queue

0 comments on commit c4dc1bd

Please sign in to comment.