Commit 22ba5b23 authored by Loic Hausammann's avatar Loic Hausammann
Browse files

Add a few structures

parent 42e7eb44
......@@ -42,10 +42,12 @@ lib_LTLIBRARIES = liblogger.la
# endif
# List required headers
include_HEADERS = logger_header.h logger_io.h logger_particle.h logger_time.h logger_tools.h logger_reader.h
include_HEADERS = logger_header.h logger_io.h logger_particle.h logger_time.h logger_tools.h logger_reader.h \
logger_index.h logger_dump.h
# Common source files
AM_SOURCES = logger_header.c logger_io.c logger_particle.c logger_time.c logger_tools.c logger_reader.c
AM_SOURCES = logger_header.c logger_io.c logger_particle.c logger_time.c logger_tools.c logger_reader.c \
logger_dump.c
if HAVEPYTHON
AM_SOURCES += logger_python_wrapper.c
endif
......
/*******************************************************************************
* This file is part of SWIFT.
* Copyright (c) 2019 Loic Hausammann (loic.hausammann@epfl.ch)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
******************************************************************************/
#include "logger_dump.h"
#include "logger_reader.h"
#include "logger_io.h"
/**
* @brief Initialize the #logger_dump.
*
* If required this function will also reverse the offsets.
* @param dump The #logger_dump.
* @param filename the dump's filename.
* @param reader The #logger_reader.
*/
void logger_dump_init(
struct logger_dump *dump, char *filename,
struct logger_reader *reader) {
/* Set the pointer to the reader. */
dump->reader = reader;
/* Open file, map it and get its size. */
if (reader->verbose > 1)
message("Mapping the dump file.");
dump->dump.map = io_mmap_file(filename, &dump->dump.file_size);
/* Read header. */
if (reader->verbose > 1)
message("Reading the header.");
header_read(&dump->header, dump);
/* Print the header. */
if (reader->verbose > 0) {
header_print(&dump->header);
}
/* Check if the offset are corrupted */
if (header_are_offset_corrupted(&dump->header)) {
error("The offsets have been corrupted");
}
/* Reverse offset direction */
if (reader->verbose > 1)
message("Checking if offsets need to be reversed.");
if (header_are_offset_backward(&dump->header)) {
logger_dump_reverse_offset(dump);
}
/* Initialize the time array */
if (reader->verbose > 1)
message("Reading the time stamps.");
time_array_init(&dump->times, dump);
if (reader->verbose > 0) {
time_array_print(&dump->times);
}
}
/**
* @brief Free the allocated memory and unmap the file.
*
* @param dump The #logger_dump.
*/
void logger_dump_free(struct logger_dump *dump) {
io_munmap_file(dump->dump.map, dump->dump.file_size);
}
/**
* @brief Reverse offset in dump file
*
* @param dump The #logger_dump
*/
void logger_dump_reverse_offset(struct logger_dump *dump) {
struct header *header = &dump->header;
const struct logger_reader *reader = dump->reader;
if (!header_are_offset_backward(header)) {
error("The offset are already reversed.");
}
#ifdef SWIFT_DEBUG_CHECKS
/* check offset */
if (reader->verbose > 0) {
message("Check offsets...\n");
}
size_t offset_debug = header->offset_first;
while (offset_debug < dump->dump.file_size) {
tools_check_offset(header, dump->dump.map, &offset_debug);
}
if (reader->verbose > 0) {
message("Check done\n");
}
#endif
/* reverse header offset */
header_change_offset_direction(header, logger_offset_corrupted);
size_t offset = header->offset_first;
/* reverse chunks */
if (reader->verbose > 0) {
message("Reversing offsets...\n");
}
while (offset < dump->dump.file_size) {
tools_reverse_offset(header, dump->dump.map, &offset);
}
if (reader->verbose > 0) {
message("Reversing done\n");
}
/* reverse header offset */
header_change_offset_direction(header, logger_offset_forward);
#ifdef SWIFT_DEBUG_CHECKS
/* check offset */
if (reader->verbose > 0) {
message("Check offsets...\n");
}
offset_debug = header->offset_first;
while (offset_debug < dump->dump.file_size) {
tools_check_offset(header, dump->dump.map, &offset_debug);
}
if (reader->verbose > 0) {
message("Check done\n");
}
#endif
}
/*******************************************************************************
* This file is part of SWIFT.
* Copyright (c) 2019 Loic Hausammann (loic.hausammann@epfl.ch)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
******************************************************************************/
/**
* @brief This file contains the high level function for the dump.
*/
#ifndef __LOGGER_LOGGER_DUMP_H__
#define __LOGGER_LOGGER_DUMP_H__
#include "logger_header.h"
#include "logger_time.h"
struct logger_reader;
/**
* @brief This structure deals with the dump file.
*/
struct logger_dump {
/* Information contained in the header. */
struct header header;
/* The reader that is using this dump. */
struct logger_reader *reader;
/* Information about the time chunks */
struct time_array times;
/* Dump's filename */
char *filename;
/* The dump's variables. */
struct {
/* Mapped data */
void *map;
/* File size */
size_t file_size;
} dump;
};
void logger_dump_init(struct logger_dump *dump, char *filename, struct logger_reader *reader);
void logger_dump_reverse_offset(struct logger_dump *dump);
void logger_dump_free(struct logger_dump *dump);
#endif // __LOGGER_LOGGER_DUMP_H__
......@@ -20,11 +20,19 @@
#include "logger_io.h"
#include "logger_tools.h"
#include "logger_dump.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* Task type names. */
const char *logger_offset_name[logger_offset_count] = {
"Forward", "Backward", "Corrupted",
};
/**
* @brief Print the properties of the header to stdout.
*
......@@ -32,23 +40,18 @@
*/
void header_print(const struct header *h) {
#ifdef SWIFT_DEBUG_CHECKS
message("Debug checks enabled\n");
message("Debug checks enabled");
#endif
message("Version: %s\n", h->version);
message("First Offset: %lu\n", h->offset_first);
char direction[20];
if (h->forward_offset)
strcpy(direction, "Forward");
else
strcpy(direction, "Backward");
message("Offset direction: %s\n", direction);
message("Number masks: %lu\n", h->number_mask);
message("Version: %s", h->version);
message("First Offset: %lu", h->offset_first);
message("Offset direction: %s", logger_offset_name[h->offset_direction]);
message("Number masks: %lu", h->number_mask);
for (size_t i = 0; i < h->number_mask; i++) {
message("\tMask: %s\n", h->masks[i].name);
message("\tValue: %u\n", h->masks[i].mask);
message("\tSize: %i\n", h->masks[i].size);
message("\n");
message("\tMask: %s", h->masks[i].name);
message("\tValue: %u", h->masks[i].mask);
message("\tSize: %i", h->masks[i].size);
message("");
}
};
......@@ -80,14 +83,14 @@ int header_get_field_index(const struct header *h, const char *field) {
* @brief Inverse the offset direction
*
* @param h #header file structure
* @param map file mapping
* @param new_value The new value to write
*
*/
void header_change_offset_direction(struct header *h, void *map) {
h->forward_offset = !h->forward_offset;
void header_change_offset_direction(struct header *h, int new_value) {
h->offset_direction = new_value;
size_t offset = LOGGER_VERSION_SIZE;
io_write_data(map, LOGGER_NUMBER_SIZE, &h->forward_offset, &offset);
io_write_data(h->dump->dump.map, LOGGER_NUMBER_SIZE, &new_value, &offset);
}
/**
......@@ -96,18 +99,23 @@ void header_change_offset_direction(struct header *h, void *map) {
* @param h out: header
* @param map file mapping
*/
void header_read(struct header *h, void *map) {
void header_read(struct header *h, struct logger_dump *dump) {
size_t offset = 0;
void *map = dump->dump.map;
/* Set pointer to dump */
h->dump = dump;
/* read version */
io_read_data(map, LOGGER_VERSION_SIZE, &h->version, &offset);
/* read offset direction */
h->forward_offset = 0;
io_read_data(map, LOGGER_NUMBER_SIZE, &h->forward_offset, &offset);
h->offset_direction = -1;
io_read_data(map, LOGGER_NUMBER_SIZE, &h->offset_direction, &offset);
if (h->forward_offset != 0 && h->forward_offset != 1)
error("Non boolean value for the offset direction (%i)", h->forward_offset);
if (!header_are_offset_forward(h) && !header_are_offset_backward(h) &&
!header_are_offset_corrupted(h))
error("Wrong offset value in the header (%i)", h->offset_direction);
/* read offset to first data */
h->offset_first = 0;
......
......@@ -29,6 +29,22 @@
#define LOGGER_OFFSET_SIZE 7
#define LOGGER_MASK_SIZE 1
enum logger_offset_direction {
logger_offset_backward = 0,
logger_offset_forward,
logger_offset_corrupted,
/* Number of offset type */
logger_offset_count,
};
/**
* @brief Names of the offset directions.
*/
extern const char *logger_offset_name[];
struct logger_dump;
/**
* @brief This structure contains everything from the file header.
*
......@@ -41,30 +57,61 @@
* The only function that modify the file is @header_change_offset_direction.
*/
struct header {
/* Logger version */
/* Logger version. */
char version[STRING_SIZE];
/* offset of the first header */
/* Offset of the first header. */
size_t offset_first;
/* Number of bytes for names */
/* Number of bytes for names. */
size_t name_length;
/* number of masks */
/* Number of masks. */
size_t number_mask;
/* list of masks */
/* List of masks. */
struct mask_data *masks;
/* offset direction */
int forward_offset;
/* Direction of the offset in the chunks. */
int offset_direction;
/* The corresponding dump */
struct logger_dump *dump;
};
void header_print(const struct header *h);
void header_free(struct header *h);
int header_get_field_index(const struct header *h, const char *field);
void header_read(struct header *h, void *map);
void header_read(struct header *h, struct logger_dump *dump);
size_t header_get_mask_size(const struct header *h, const size_t mask);
void header_change_offset_direction(struct header *h, void *map);
void header_change_offset_direction(struct header *h, int new_value);
/**
* @brief Check if the offset are forward.
* @param h The #header.
*/
__attribute__((always_inline)) INLINE static int header_are_offset_forward(
const struct header *h) {
return h->offset_direction == logger_offset_forward;
}
/**
* @brief Check if the offset are backward.
* @param h The #header.
*/
__attribute__((always_inline)) INLINE static int header_are_offset_backward(
const struct header *h) {
return h->offset_direction == logger_offset_backward;
}
/**
* @brief Check if the offset are corrupted.
* @param h The #header.
*/
__attribute__((always_inline)) INLINE static int header_are_offset_corrupted(
const struct header *h) {
return h->offset_direction == logger_offset_corrupted;
}
#endif // __LOGGER_LOGGER_HEADER_H__
/*******************************************************************************
* This file is part of SWIFT.
* Copyright (c) 2019 Loic Hausammann (loic.hausammann@epfl.ch)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
******************************************************************************/
/**
* @brief This file deals with the index files.
*/
#ifndef __LOGGER_LOGGER_INDEX_H__
#define __LOGGER_LOGGER_INDEX_H__
/**
* @brief This structure will contain the data related to
* the index file.
*/
struct logger_index {};
#endif // __LOGGER_LOGGER_INDEX_H__
......@@ -40,46 +40,46 @@ void io_get_file_size(int fd, size_t *size) {
}
/**
* @brief Open a file and map it
* @brief Map a file.
*
* @param filename file to read
* @param fd out: file id
* @param map out: file mapping
* @io_munmap_file should be called to unmap the file.
*
* @param filename file to read.
* @param file_size (out) size of the file.
*
*/
void io_open_file(char *filename, int *fd, void **map) {
void *io_mmap_file(char *filename, size_t *file_size) {
/* open file */
*fd = open(filename, O_RDWR);
if (*fd == -1)
int fd = open(filename, O_RDWR);
if (fd == -1)
error("Unable to open file %s (%s)", filename, strerror(errno));
/* get file size */
size_t size = 0;
io_get_file_size(*fd, &size);
*file_size = 0;
io_get_file_size(fd, file_size);
/* map memory */
*map = mmap(NULL, size, PROT_WRITE | PROT_READ, MAP_SHARED, *fd, 0);
void *map = mmap(NULL, *file_size, PROT_WRITE | PROT_READ, MAP_SHARED, fd, 0);
if (map == MAP_FAILED)
error("Failed to allocate map of size %zi bytes. (%s)", size,
error("Failed to allocate map of size %zi bytes. (%s)", *file_size,
strerror(errno));
close(fd);
return map;
}
/**
* @brief Close a file and unmap it
* @brief Unmap a file
*
* @param fd file id
* @param map file mapping
* @param file_size The file size.
*
*/
void io_close_file(int *fd, void **map) {
/* get file size */
size_t size = 0;
io_get_file_size(*fd, &size);
void io_munmap_file(void *map, size_t file_size) {
/* unmap */
if (munmap(*map, size) != 0) {
if (munmap(map, file_size) != 0) {
error("Unable to unmap the file (%s)", strerror(errno));
}
close(*fd);
}
......@@ -29,8 +29,8 @@
#include <stdlib.h>
void io_get_file_size(int fd, size_t *size);
void io_open_file(char *filename, int *fd, void **map);
void io_close_file(int *fd, void **map);
void *io_mmap_file(char *filename, size_t *file_size);
void io_munmap_file(void *map, size_t file_size);
/**
* @brief read a mask with its offset
......
......@@ -152,7 +152,9 @@ void logger_particle_read(struct logger_particle *part, const struct header *h,
/* read next particle */
struct logger_particle part_next;
if (!h->forward_offset) error("TODO");
if (!header_are_offset_forward(h)) {
error("Cannot read a particle with non forward offsets.");
}
if (h_offset == 0) return;
/* get absolute offset of next particle */
......
......@@ -41,8 +41,6 @@
static PyObject *loadFromIndex(__attribute__((unused)) PyObject *self,
PyObject *args) {
struct header h;
/* input */
PyArrayObject *offset = NULL;
char *filename = NULL;
......@@ -76,87 +74,64 @@ static PyObject *loadFromIndex(__attribute__((unused)) PyObject *self,
error("Offset does not contain unsigned int");
}
/* open file */
int fd;
void *map;
io_open_file(filename, &fd, &map);
/* read header */
header_read(&h, map);
/* reverse offset if needed */
if (!h.forward_offset) {
io_close_file(&fd, &map);
reverse_offset(filename, verbose);
io_open_file(filename, &fd, &map);
/* Reset header */
header_free(&h);
header_read(&h, map);
}
/* read timestamps */
struct time_array times;
time_array_init(&times, &h, map, fd);
if (verbose > 0) {
time_array_print(&times);
}
/* get required time */
double time = time_array_get_time(&times, time_offset);
/* initialize the reader */
verbose = 2;
struct logger_reader reader;
logger_reader_init(&reader, filename, verbose);
struct header *h = &reader.dump.header;
/* init array */
npy_intp dim[2];
dim[0] = PyArray_DIMS(offset)[0];
dim[1] = DIM;
/* Get required time. */
double time = time_array_get_time(&reader.dump.times, time_offset);
/* init output */
if (header_get_field_index(&h, "positions") != -1) {
if (header_get_field_index(h, "positions") != -1) {
pos = (PyArrayObject *)PyArray_SimpleNew(2, dim, NPY_DOUBLE);
}
if (header_get_field_index(&h, "velocities") != -1) {
if (header_get_field_index(h, "velocities") != -1) {
vel = (PyArrayObject *)PyArray_SimpleNew(2, dim, NPY_FLOAT);
}
if (header_get_field_index(&h, "accelerations") != -1) {
if (header_get_field_index(h, "accelerations") != -1) {
acc = (PyArrayObject *)PyArray_SimpleNew(2, dim, NPY_FLOAT);
}