Skip to content

Commit

Permalink
Feature: integrate dice-group/metall-ffi (#14)
Browse files Browse the repository at this point in the history
  • Loading branch information
liss-h authored Dec 12, 2023
1 parent 4276853 commit de06c5f
Show file tree
Hide file tree
Showing 8 changed files with 352 additions and 142 deletions.
31 changes: 14 additions & 17 deletions examples/c_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,48 +4,45 @@
// SPDX-License-Identifier: (Apache-2.0 OR MIT)

#include <assert.h>
#include <dice/ffi/deprecated_metall.h>
#include <stdint.h>
#include <dice/ffi/metall.h>

int main(void) {
// Basic allocation
{
metall_open(METALL_CREATE_ONLY, "/tmp/metall1");
metall_manager *manager = metall_create("/tmp/metall1");

uint64_t *x = metall_malloc(sizeof(uint64_t));
uint64_t *x = metall_malloc(manager, sizeof(uint64_t));
x[0] = 1;

metall_free(x);

metall_close();
metall_free(manager, x);
metall_close(manager);
}

// Allocate named object
{
metall_open(METALL_CREATE_ONLY, "/tmp/metall2");
metall_manager *manager = metall_create("/tmp/metall1");

uint64_t *array = metall_named_malloc("array", sizeof(uint64_t) * 10);
uint64_t *array = metall_named_malloc(manager, "array", sizeof(uint64_t) * 10);

array[0] = 0;

metall_flush();

array[1] = 1;

metall_close();
metall_close(manager);
}

// Retrieve named object
{
metall_open(METALL_OPEN_ONLY, "/tmp/metall2");
metall_manager *manager = metall_open("/tmp/metall1");

uint64_t *array = metall_find("array");
uint64_t *array = metall_find(manager, "array");

assert(array[0] == 0);
assert(array[1] == 1);

metall_named_free("array");

metall_close();
metall_named_free(manager, "array");
metall_close(manager);
metall_remove("/tmp/metalll1");
}

return 0;
Expand Down
86 changes: 0 additions & 86 deletions libs/ffi/src/dice/ffi/deprecated_metall.h

This file was deleted.

129 changes: 90 additions & 39 deletions libs/ffi/src/dice/ffi/metall.cpp
Original file line number Diff line number Diff line change
@@ -1,60 +1,111 @@
// Copyright 2019 Lawrence Livermore National Security, LLC and other Metall
// Project Developers. See the top-level COPYRIGHT file for details.
//
// SPDX-License-Identifier: (Apache-2.0 OR MIT)
#include <dice/ffi/metall.h>
#include <dice/ffi/metall_internal.hpp>

#include <dice/ffi/deprecated_metall.h>
#include <dice/metall/metall.hpp>
using metall_manager_t = dice::metall_ffi::internal::metall_manager;

dice::metall::manager *g_manager = nullptr;
template <auto open_mode>
metall_manager *open_impl(char const *path) {
if (!dice::metall::manager::consistent(path)) {
// prevents opening the same datastore twice
// (because opening removes the properly_closed_mark and this checks for it)
errno = ENOTRECOVERABLE;
return nullptr;
}

int metall_open(const int mode, const char *const path) {
if (mode == METALL_CREATE_ONLY) {
g_manager = new dice::metall::manager(dice::metall::create_only, path);
} else if (mode == METALL_OPEN_ONLY) {
g_manager = new dice::metall::manager(dice::metall::open_only, path);
} else if (mode == METALL_OPEN_READ_ONLY) {
g_manager = new dice::metall::manager(dice::metall::open_read_only, path);
} else {
g_manager = nullptr;
auto *manager = new metall_manager_t{open_mode, path};
if (!manager->check_sanity()) {
delete manager;
errno = ENOTRECOVERABLE;
return nullptr;
}

if (g_manager) {
return 0;
} else {
return -1; // error
return reinterpret_cast<metall_manager *>(manager);
}

metall_manager *metall_open(char const *path) {
return open_impl<dice::metall::open_only>(path);
}

metall_manager *metall_open_read_only(char const *path) {
return open_impl<dice::metall::open_read_only>(path);
}

metall_manager *metall_create(char const *path) {
if (std::filesystem::exists(path)) {
// prevent accidental overwrite
errno = EEXIST;
return nullptr;
}

auto *manager = new metall_manager_t{dice::metall::create_only, path};
if (!manager->check_sanity()) {
delete manager;
errno = ENOTRECOVERABLE;
return nullptr;
}

return reinterpret_cast<metall_manager *>(manager);
}

bool metall_snapshot(metall_manager *manager, char const *dst_path) {
return reinterpret_cast<metall_manager_t *>(manager)->snapshot(dst_path);
}

void metall_close(metall_manager *manager) {
delete reinterpret_cast<metall_manager_t *>(manager);
}

void metall_close() { delete g_manager; }
bool metall_remove(char const *path) {
return dice::metall::manager::remove(path);
}

void metall_flush() { g_manager->flush(); }
void *metall_named_malloc(metall_manager *manager, char const *name,
size_t size) {
auto *ptr =
reinterpret_cast<metall_manager_t *>(manager)->construct<unsigned char>(
name)[size]();
if (ptr == nullptr) {
errno = ENOMEM;
}

void *metall_malloc(const uint64_t nbytes) {
return g_manager->allocate(nbytes);
return ptr;
}

void metall_free(void *const ptr) { g_manager->deallocate(ptr); }
void *metall_find(metall_manager *manager, char const *name) {
auto *ptr = reinterpret_cast<metall_manager_t *>(manager)
->find<unsigned char>(name)
.first;
if (ptr == nullptr) {
errno = ENOENT;
}

void *metall_named_malloc(const char *name, const uint64_t nbytes) {
return g_manager->construct<char>(name)[nbytes]();
return ptr;
}

void *metall_find(char *name) { return g_manager->find<char>(name).first; }
bool metall_named_free(metall_manager *manager, char const *name) {
auto const res =
reinterpret_cast<metall_manager_t *>(manager)->destroy<unsigned char>(
name);
if (!res) {
errno = ENOENT;
}

void metall_named_free(const char *name) { g_manager->destroy<char>(name); }
return res;
}

int snapshot(const char *destination_path) {
if (g_manager->snapshot(destination_path)) return 0;
return -1; // Error
void *metall_malloc(metall_manager *manager, size_t size) {
auto *ptr = reinterpret_cast<metall_manager_t *>(manager)->allocate(size);
if (ptr == nullptr) {
errno = ENOMEM;
}

return ptr;
}

int copy(const char *source_path, const char *destination_path) {
if (dice::metall::manager::copy(source_path, destination_path)) return 0;
return -1; // Error
void metall_free(metall_manager *manager, void *addr) {
reinterpret_cast<metall_manager_t *>(manager)->deallocate(addr);
}

int consistent(const char *path) {
if (dice::metall::manager::consistent(path)) return 1;
return 0;
}
void metall_flush(metall_manager *manager) {
reinterpret_cast<metall_manager_t *>(manager)->flush();
}
Loading

0 comments on commit de06c5f

Please sign in to comment.