Skip to content

Commit

Permalink
Add a Strong Type for Memory Sizes (ad-freiburg#1032)
Browse files Browse the repository at this point in the history
Add a class `ad_utility::MemorySize` that stores an amount of memory in bytes in a strongly typed manner. It can be parsed from strings (e.g. "4 kB" or "8.3 GB") and set from user defined literals (`4.34_GB` etc.). This commit does not yet use the `MemorySize`, but this is left for following PRs.
  • Loading branch information
schlegan authored Jul 20, 2023
1 parent 5a12ac0 commit ad6f15e
Show file tree
Hide file tree
Showing 19 changed files with 1,681 additions and 1 deletion.
2 changes: 1 addition & 1 deletion sonar-project.properties
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ sonar.projectVersion=1.0
# Path is relative to the sonar-project.properties file. Replace "\" by "/" on Windows.
sonar.sources=./src,./benchmark
sonar.tests=./test
sonar.exclusions=src/parser/sparqlParser/generated/*,src/util/http/HttpParser/generated/*, src/util/ConfigManager/generated/*
sonar.exclusions=src/parser/sparqlParser/generated/*,src/util/http/HttpParser/generated/*, src/util/ConfigManager/generated/*, src/util/MemorySize/generated/*

# Encoding of the source code. Default is default system encoding
sonar.sourceEncoding=UTF-8
1 change: 1 addition & 0 deletions src/util/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
add_subdirectory(ConfigManager)
add_subdirectory(MemorySize)
add_subdirectory(http)
add_library(util GeoSparqlHelpers.cpp
antlr/ANTLRErrorHandling.cpp ParseException.cpp Conversions.cpp Date.cpp)
Expand Down
4 changes: 4 additions & 0 deletions src/util/MemorySize/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
add_library(memorySize MemorySize.cpp
generated/MemorySizeLanguageLexer.cpp
generated/MemorySizeLanguageParser.cpp MemorySizeParser.cpp)
qlever_target_link_libraries(memorySize antlr4_static util)
75 changes: 75 additions & 0 deletions src/util/MemorySize/MemorySize.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
// Copyright 2022, University of Freiburg,
// Chair of Algorithms and Data Structures.
// Author: Andre Schlegel (July of 2023,
// [email protected])

#include "util/MemorySize/MemorySize.h"

#include <absl/strings/str_cat.h>

#include <cinttypes>
#include <ranges>
#include <string_view>

#include "util/Cache.h"
#include "util/ConstexprMap.h"
#include "util/ConstexprUtils.h"
#include "util/Exception.h"
#include "util/HashMap.h"
#include "util/MemorySize/MemorySizeParser.h"
#include "util/MemorySize/generated/MemorySizeLanguageLexer.h"
#include "util/MemorySize/generated/MemorySizeLanguageParser.h"

namespace ad_utility {
// _____________________________________________________________________________
std::string MemorySize::asString() const {
// Convert number and memory unit name to the string, we want to return.
auto toString = [](const auto number, std::string_view unitName) {
return absl::StrCat(number, " ", unitName);
};

/*
Choosing the memory unit type is done by choosing the unit type, in which
range `memoryInBytes_` is contained.
A memory unit type normally has the range `[hisSize,
sizeOfTheNextBiggerUnit)`.
Only exceptions are:
- `TB`, which has no upper bound, because it's our biggest unit.
- `kB`, which has the lower bound `100'000` instead of `1'000`. Typically, for
such small sizes you still want the exact value because they mean something
,e.g. a block size or a page size etc..
*/
constexpr ad_utility::ConstexprMap<char, size_t, 4> memoryUnitLowerBound(
{std::pair<char, size_t>{'k', ad_utility::pow(10, 5)},
std::pair<char, size_t>{'M', detail::numBytesPerUnit.at("MB")},
std::pair<char, size_t>{'G', detail::numBytesPerUnit.at("GB")},
std::pair<char, size_t>{'T', detail::numBytesPerUnit.at("TB")}});

// Go through the units from top to bottom, in terms of size, and choose the
// first one, that is smaller/equal to `memoryInBytes_`.
if (memoryInBytes_ >= memoryUnitLowerBound.at('T')) {
return toString(getTerabytes(), "TB");
} else if (memoryInBytes_ >= memoryUnitLowerBound.at('G')) {
return toString(getGigabytes(), "GB");
} else if (memoryInBytes_ >= memoryUnitLowerBound.at('M')) {
return toString(getMegabytes(), "MB");
} else if (memoryInBytes_ >= memoryUnitLowerBound.at('k')) {
return toString(getKilobytes(), "kB");
} else {
// Just return the amount of bytes.
return toString(memoryInBytes_, "B");
}
}

// _____________________________________________________________________________
MemorySize MemorySize::parse(std::string_view str) {
return MemorySizeParser::parseMemorySize(str);
}

// _____________________________________________________________________________
std::ostream& operator<<(std::ostream& os, const ad_utility::MemorySize& mem) {
os << mem.asString();
return os;
}

} // namespace ad_utility
Loading

0 comments on commit ad6f15e

Please sign in to comment.