ncm: use static memory pools for different allocations

This commit is contained in:
Michael Scire
2020-03-29 17:20:25 -07:00
parent 7fc1e86bf5
commit bd4c608b08
11 changed files with 159 additions and 44 deletions

View File

@@ -49,7 +49,7 @@ namespace ams::kvdb {
void Reset() {
if (this->buffer != nullptr) {
std::free(this->buffer);
delete[] this->buffer;
this->buffer = nullptr;
this->size = 0;
}
@@ -68,7 +68,7 @@ namespace ams::kvdb {
AMS_ABORT_UNLESS(this->buffer == nullptr);
/* Allocate a buffer. */
this->buffer = static_cast<u8 *>(std::malloc(size));
this->buffer = new (std::nothrow) u8[size];
R_UNLESS(this->buffer != nullptr, ResultAllocationFailed());
this->size = size;

View File

@@ -93,13 +93,14 @@ namespace ams::kvdb {
size_t count;
size_t capacity;
Entry *entries;
MemoryResource *memory_resource;
public:
Index() : count(0), capacity(0), entries(nullptr) { /* ... */ }
Index() : count(0), capacity(0), entries(nullptr), memory_resource(nullptr) { /* ... */ }
~Index() {
if (this->entries != nullptr) {
this->ResetEntries();
std::free(this->entries);
this->memory_resource->Deallocate(this->entries, sizeof(Entry) * this->capacity);
this->entries = nullptr;
}
}
@@ -114,30 +115,25 @@ namespace ams::kvdb {
void ResetEntries() {
for (size_t i = 0; i < this->count; i++) {
std::free(this->entries[i].GetValuePointer());
this->memory_resource->Deallocate(this->entries[i].GetValuePointer(), this->entries[i].GetValueSize());
}
this->count = 0;
}
Result Initialize(size_t capacity) {
this->entries = reinterpret_cast<Entry *>(std::malloc(sizeof(Entry) * capacity));
Result Initialize(size_t capacity, MemoryResource *mr) {
this->entries = reinterpret_cast<Entry *>(mr->Allocate(sizeof(Entry) * capacity));
R_UNLESS(this->entries != nullptr, ResultAllocationFailed());
this->capacity = capacity;
this->memory_resource = mr;
return ResultSuccess();
}
Result Set(const Key &key, const void *value, size_t value_size) {
/* Allocate new value. */
void *new_value = std::malloc(value_size);
R_UNLESS(new_value != nullptr, ResultAllocationFailed());
auto value_guard = SCOPE_GUARD { std::free(new_value); };
std::memcpy(new_value, value, value_size);
/* Find entry for key. */
Entry *it = this->lower_bound(key);
if (it != this->end() && it->GetKey() == key) {
/* Entry already exists. Free old value. */
std::free(it->GetValuePointer());
this->memory_resource->Deallocate(it->GetValuePointer(), it->GetValueSize());
} else {
/* We need to add a new entry. Check we have room, move future keys forward. */
R_UNLESS(this->count < this->capacity, ResultOutOfKeyResource());
@@ -145,8 +141,12 @@ namespace ams::kvdb {
this->count++;
}
/* Allocate new value. */
void *new_value = this->memory_resource->Allocate(value_size);
R_UNLESS(new_value != nullptr, ResultAllocationFailed());
std::memcpy(new_value, value, value_size);
/* Save the new Entry in the map. */
value_guard.Cancel();
*it = Entry(key, new_value, value_size);
return ResultSuccess();
}
@@ -164,7 +164,7 @@ namespace ams::kvdb {
R_UNLESS(it != this->end(), ResultKeyNotFound());
/* Free the value, move entries back. */
std::free(it->GetValuePointer());
this->memory_resource->Deallocate(it->GetValuePointer(), it->GetValueSize());
std::memmove(it, it + 1, sizeof(*it) * (this->end() - (it + 1)));
this->count--;
return ResultSuccess();
@@ -258,10 +258,11 @@ namespace ams::kvdb {
Index index;
Path path;
Path temp_path;
MemoryResource *memory_resource;
public:
MemoryKeyValueStore() { /* ... */ }
Result Initialize(const char *dir, size_t capacity) {
Result Initialize(const char *dir, size_t capacity, MemoryResource *mr) {
/* Ensure that the passed path is a directory. */
fs::DirectoryEntryType entry_type;
R_TRY(fs::GetEntryType(std::addressof(entry_type), dir));
@@ -272,18 +273,21 @@ namespace ams::kvdb {
this->temp_path.SetFormat("%s%s", dir, "/imkvdb.tmp");
/* Initialize our index. */
R_TRY(this->index.Initialize(capacity));
R_TRY(this->index.Initialize(capacity, mr));
this->memory_resource = mr;
return ResultSuccess();
}
Result Initialize(size_t capacity) {
Result Initialize(size_t capacity, MemoryResource *mr) {
/* This initializes without an archive file. */
/* A store initialized this way cannot have its contents loaded from or flushed to disk. */
this->path.Set("");
this->temp_path.Set("");
/* Initialize our index. */
R_TRY(this->index.Initialize(capacity));
R_TRY(this->index.Initialize(capacity, mr));
this->memory_resource = mr;
return ResultSuccess();
}
@@ -319,9 +323,9 @@ namespace ams::kvdb {
R_TRY(reader.GetEntrySize(&key_size, &value_size));
/* Allocate memory for value. */
void *new_value = std::malloc(value_size);
void *new_value = this->memory_resource->Allocate(value_size);
R_UNLESS(new_value != nullptr, ResultAllocationFailed());
auto value_guard = SCOPE_GUARD { std::free(new_value); };
auto value_guard = SCOPE_GUARD { this->memory_resource->Deallocate(new_value, value_size); };
/* Read key and value. */
Key key;