Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/cmake-multi-platform.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:

strategy:
# Set fail-fast to false to ensure that feedback is delivered for all matrix combinations. Consider changing this to true when your workflow is stable.
fail-fast: false
fail-fast: true

# Set up a matrix to run the following 3 configurations:
# 1. <Windows, Release, latest MSVC compiler toolchain on the default runner image, default generator>
Expand All @@ -31,7 +31,7 @@ jobs:
c_compiler: cl
cpp_compiler: cl
- os: ubuntu-latest
c_compiler: gcc
c_compilel: gcc
cpp_compiler: g++
- os: ubuntu-latest
c_compiler: clang
Expand Down
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ set(CMAKE_CXX_EXTENSIONS OFF)


add_subdirectory(main)
add_subdirectory(hello_world_lib)
add_subdirectory(LRU)


include(CTest)
Expand Down
8 changes: 8 additions & 0 deletions LRU/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
add_library(LRU INTERFACE)

target_sources(LRU
INTERFACE
FILE_SET HEADERS
FILES
LRU.hpp
)
38 changes: 38 additions & 0 deletions LRU/LRU.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#pragma once

#include <list>
#include <unordered_map>

namespace cache {

template <typename T, typename KeyT = int> class LRU_t {
size_t sz_;
std::list<std::pair<KeyT, T>> cache_;

using ListIt = typename decltype(cache_)::iterator;
std::unordered_map<KeyT, ListIt> hash_;

public:
explicit LRU_t(size_t sz) : sz_{sz} {}

bool full() const { return cache_.size() == sz_; };

template <typename F> bool lookup_update(KeyT key, F slow_get_page) {
auto hit = hash_.find(key);
if (hit == hash_.end()) { // not found
if (full()) {
hash_.erase(cache_.back().first);
cache_.pop_back();
}
cache_.emplace_front(key, slow_get_page(key));
hash_.emplace(key, cache_.begin());
return false;
}

auto eltit = hit->second;
cache_.splice(cache_.begin(), cache_, eltit);
return true;
}
};

} // namespace cache
11 changes: 0 additions & 11 deletions hello_world_lib/CMakeLists.txt

This file was deleted.

3 changes: 0 additions & 3 deletions hello_world_lib/hello.cpp

This file was deleted.

3 changes: 0 additions & 3 deletions hello_world_lib/hello.hpp

This file was deleted.

7 changes: 6 additions & 1 deletion main/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,13 @@ target_sources(main
main.cpp
)

target_compile_options(main
PRIVATE
$<$<CXX_COMPILER_ID:MSVC>:/W4 /WX>
$<$<CXX_COMPILER_ID:GNU,Clang>:-Wall -Wextra -Werror>
)

target_link_libraries(main
PRIVATE
hello_world_lib
LRU
)
30 changes: 27 additions & 3 deletions main/main.cpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,32 @@
#include "hello.hpp"
#include "LRU.hpp"
#include <cassert>
#include <iostream>
#include <map>
#include <string>

int slow_get_page(int key) { return key; }


int main() {
std::string str = hello();
std::map<std::string, int> cache_hits;
size_t sz;
int nelts;

std::cin >> sz >> nelts;

cache::LRU_t<int> lru{sz};

for (int i = 0; i < nelts; ++i) {
int p;
std::cin >> p;
assert(std::cin.good());
if (lru.lookup_update(p, slow_get_page))
cache_hits["LRU"] += 1;
}

std::cout << str << std::endl;
std::cout << "Cache type\tN hits\n";
for(auto [cache_type, nhits]: cache_hits){
std::cout << cache_type << "\t" << nhits << std::endl;
}
return 0;
}
17 changes: 12 additions & 5 deletions tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,21 @@ set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
FetchContent_MakeAvailable(googletest)


add_executable(hello_test
hello_test.cc
add_executable(caches_test
LRU_test.cpp
)
target_link_libraries(hello_test

target_compile_options(caches_test
PRIVATE
$<$<CXX_COMPILER_ID:MSVC>:/W4 /WX>
$<$<CXX_COMPILER_ID:GNU,Clang>:-Wall -Wextra -Werror>
)

target_link_libraries(caches_test
PRIVATE
hello_world_lib
LRU
GTest::gtest_main
)

include(GoogleTest)
gtest_discover_tests(hello_test)
gtest_discover_tests(caches_test)
69 changes: 69 additions & 0 deletions tests/LRU_test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
#include "LRU.hpp"
#include <gtest/gtest.h>

namespace {
struct page_t {
int id;
};

page_t slow_get_page(int page_id) { return page_t{page_id}; }
} // namespace

TEST(LRU, no_hit) {
cache::LRU_t<page_t> lru{3};

// cache is empty, no hits
EXPECT_FALSE(lru.lookup_update(1, slow_get_page));
}

TEST(LRU, one_hit) {
cache::LRU_t<page_t> lru{3};

EXPECT_FALSE(lru.lookup_update(1, slow_get_page));
EXPECT_TRUE(lru.lookup_update(1, slow_get_page)); // cache hit
}

TEST(LRU, is_full) {
cache::LRU_t<page_t> lru{2};

lru.lookup_update(1, slow_get_page); // [1]
lru.lookup_update(1, slow_get_page); // [1]
EXPECT_FALSE(lru.full());

lru.lookup_update(2, slow_get_page); // [2, 1]
EXPECT_TRUE(lru.full());
}

TEST(LRU, no_eviction) {
cache::LRU_t<page_t> lru{3};

EXPECT_FALSE(lru.lookup_update(1, slow_get_page)); // [1]
EXPECT_FALSE(lru.lookup_update(2, slow_get_page)); // [2, 1]
EXPECT_TRUE(lru.lookup_update(1, slow_get_page)); // [1, 2]
EXPECT_FALSE(lru.lookup_update(3, slow_get_page)); // [3, 1, 2]
EXPECT_TRUE(lru.lookup_update(1, slow_get_page)); // [1, 3, 2]
EXPECT_TRUE(lru.lookup_update(2, slow_get_page)); // [2, 1, 3]
}

TEST(LRU, eviction) {
cache::LRU_t<page_t> lru{2};

lru.lookup_update(1, slow_get_page); // [1]
lru.lookup_update(2, slow_get_page); // [2, 1]
lru.lookup_update(3, slow_get_page); // [3, 2]

EXPECT_FALSE(
lru.lookup_update(1, slow_get_page)); // 1 is not present before lookup
}

TEST(LRU, example_from_lecture) {
cache::LRU_t<page_t> lru{2};

size_t hits{};
for (int page_id : {1, 2, 1, 2, 1, 2}) {
if (lru.lookup_update(page_id, slow_get_page))
hits += 1;
}

EXPECT_EQ(4, hits);
}
8 changes: 0 additions & 8 deletions tests/hello_test.cc

This file was deleted.

Loading