diff --git a/src/csds_error.hpp b/src/csds_error.hpp index 78d27f94b2b614061f180baa940c8da34527e404..c04771b3de442caa292b5f9370e264b692d6e007 100644 --- a/src/csds_error.hpp +++ b/src/csds_error.hpp @@ -53,6 +53,23 @@ INLINE static int GetDeltaTime(const high_resolution_clock::time_point init, return span.count(); } +#ifdef CSDS_DEBUG_CHECKS +/** + * @brief Error macro. Prints the message given in argument and aborts. + */ +#define csds_error(input) \ + { \ + float delta_time_error = GetDeltaTime(INITIAL_TIME); \ + delta_time_error /= 1000; /* into seconds */ \ + \ + std::cout << std::flush; \ + std::cerr << "[" << std::setfill('0') << std::setw(6) \ + << std::setprecision(1) << delta_time_error << "] " << __FILE__ \ + << ":" << __FUNCTION__ << ":" << __LINE__ << ": " << input \ + << std::endl; \ + csds_abort(1); \ + } +#else /** * @brief Error macro. Prints the message given in argument and aborts. */ @@ -71,6 +88,7 @@ INLINE static int GetDeltaTime(const high_resolution_clock::time_point init, else \ throw std::runtime_error("See above for the description"); \ } +#endif /** * @brief Macro to print a localized message with variable arguments. diff --git a/src/csds_header.cpp b/src/csds_header.cpp index 162f4c79514b21988d9d17bdcd310e687c9d928e..560d98e5a9c1ef7a7d995869538ba4c865e76693 100644 --- a/src/csds_header.cpp +++ b/src/csds_header.cpp @@ -102,8 +102,7 @@ void header_change_offset_direction(struct header *h, /* Skip file format and version numbers. */ size_t offset = CSDS_STRING_SIZE + 2 * sizeof(int); - csds_mapped_file_write_data(h->log->log, offset, sizeof(unsigned int), - &new_value); + h->log->log->WriteData(offset, sizeof(unsigned int), &new_value); } /** @@ -113,7 +112,7 @@ void header_change_offset_direction(struct header *h, * @param log The #csds_logfile. * @param verbose The verbose level */ -void header_read(struct header *h, struct csds_logfile *log, int verbose) { +void header_read(struct header *h, LogFile *log, int verbose) { /* Set pointer to log. */ h->log = log; @@ -123,18 +122,15 @@ void header_read(struct header *h, struct csds_logfile *log, int verbose) { /* read the file format. */ char file_format[CSDS_STRING_SIZE]; - offset = csds_mapped_file_read_data(log->log, offset, CSDS_STRING_SIZE, - &file_format); + offset = log->log->ReadData(offset, CSDS_STRING_SIZE, &file_format); if (strcmp(file_format, CSDS_FORMAT_STRING)) csds_error("Wrong file format: " << file_format); /* Read the major version number. */ - offset = csds_mapped_file_read_data(log->log, offset, sizeof(int), - &h->major_version); + offset = log->log->ReadData(offset, sizeof(int), &h->major_version); /* Read the minor version number. */ - offset = csds_mapped_file_read_data(log->log, offset, sizeof(int), - &h->minor_version); + offset = log->log->ReadData(offset, sizeof(int), &h->minor_version); /* Check the mask size */ if (sizeof(mask_type) != CSDS_MASK_SIZE) @@ -145,8 +141,7 @@ void header_read(struct header *h, struct csds_logfile *log, int verbose) { message("File version " << h->major_version << "." << h->minor_version); /* Read the offset directions. */ - offset = csds_mapped_file_read_data(log->log, offset, sizeof(int), - &h->offset_direction); + offset = log->log->ReadData(offset, sizeof(int), &h->offset_direction); if (!header_is_forward(h) && !header_is_backward(h) && !header_is_corrupted(h)) @@ -154,13 +149,12 @@ void header_read(struct header *h, struct csds_logfile *log, int verbose) { /* Read offset to first record. */ h->offset_first_record = 0; - offset = csds_mapped_file_read_data(log->log, offset, CSDS_OFFSET_SIZE, - &h->offset_first_record); + offset = + log->log->ReadData(offset, CSDS_OFFSET_SIZE, &h->offset_first_record); /* Read the size of the strings. */ unsigned int string_length = 0; - offset = csds_mapped_file_read_data(log->log, offset, sizeof(unsigned int), - &string_length); + offset = log->log->ReadData(offset, sizeof(unsigned int), &string_length); /* Check if value defined in this file is large enough. */ if (CSDS_STRING_SIZE < string_length) { @@ -169,8 +163,7 @@ void header_read(struct header *h, struct csds_logfile *log, int verbose) { /* Read the number of masks. */ unsigned int masks_count = 0; - offset = csds_mapped_file_read_data(log->log, offset, sizeof(unsigned int), - &masks_count); + offset = log->log->ReadData(offset, sizeof(unsigned int), &masks_count); /* Allocate the masks memory. */ struct mask_data *masks = @@ -182,15 +175,13 @@ void header_read(struct header *h, struct csds_logfile *log, int verbose) { /* Loop over all masks. */ for (unsigned int i = 0; i < masks_count; i++) { /* Read the mask name. */ - offset = csds_mapped_file_read_data(log->log, offset, string_length, - masks[i].name); + offset = log->log->ReadData(offset, string_length, masks[i].name); /* Set the mask value. */ masks[i].mask = 1 << i; /* Read the mask data size. */ - offset = csds_mapped_file_read_data(log->log, offset, sizeof(unsigned int), - &masks[i].size); + offset = log->log->ReadData(offset, sizeof(unsigned int), &masks[i].size); /* Print the information. */ if (verbose > 1) { @@ -235,8 +226,8 @@ void header_read(struct header *h, struct csds_logfile *log, int verbose) { } /* Read the number of fields per particle */ - offset = csds_mapped_file_read_data( - log->log, offset, sizeof(h->number_fields), h->number_fields); + offset = + log->log->ReadData(offset, sizeof(h->number_fields), h->number_fields); /* Read the order of the fields */ for (int type = 0; type < csds_type_count; type++) { @@ -248,7 +239,7 @@ void header_read(struct header *h, struct csds_logfile *log, int verbose) { /* Allocate and read the order */ size_t size = h->number_fields[type] * sizeof(int); int *order = (int *)malloc(size); - offset = csds_mapped_file_read_data(log->log, offset, size, order); + offset = log->log->ReadData(offset, size, order); /* Add the special flag */ size = (h->number_fields[type] + 1) * sizeof(struct field_information); diff --git a/src/csds_header.hpp b/src/csds_header.hpp index bde9e1f769c54bea3b49a47f5944823864b7e9cf..95ffbe295edae2dd984060b4ee7c91411a27c1e8 100644 --- a/src/csds_header.hpp +++ b/src/csds_header.hpp @@ -31,8 +31,6 @@ */ extern const char *csds_offset_name[]; -struct csds_logfile; - /** * @brief This structure contains everything from the file header. * @@ -58,7 +56,8 @@ struct header { enum csds_offset_direction offset_direction; /* The corresponding log. */ - struct csds_logfile *log; + // TODO Remove this dependency + LogFile *log; /* Number of mask per particle type */ int number_fields[csds_type_count]; @@ -70,7 +69,7 @@ struct header { void header_print(const struct header *h); void header_free(struct header *h); -void header_read(struct header *h, struct csds_logfile *log, int verbose); +void header_read(struct header *h, LogFile *log, int verbose); size_t header_get_record_size_from_mask(const struct header *h, mask_type mask); void header_change_offset_direction(struct header *h, enum csds_offset_direction new_value); diff --git a/src/csds_index.cpp b/src/csds_index.cpp index 881b62b0613ac6d301586c47f6134615c2fe9b3e..2f9c5c3a8ae101c9c62fcd9f4797354fbf87e842 100644 --- a/src/csds_index.cpp +++ b/src/csds_index.cpp @@ -56,57 +56,58 @@ * @param filename The filename of the index file. * @param verbose The verbose level */ -void csds_index_read_header(struct csds_index *index, - const std::string filename, int verbose) { +IndexFile::IndexFile(const std::string filename, int verbose) { + this->index = NULL; /* Open the file */ if (verbose > 1) { message("Reading " << filename); } - csds_index_map_file(index, filename, 0, verbose); + csds_index_map_file(this, filename, 0, verbose); /* Read times */ - memcpy(&index->time, index->index.map + csds_index_time_offset, + memcpy(&this->time, this->index->mMap + csds_index_time_offset, csds_index_time_size); - memcpy(&index->integer_time, - index->index.map + csds_index_integer_time_offset, + memcpy(&this->integer_time, + this->index->mMap + csds_index_integer_time_offset, csds_index_integer_time_size); /* Read the number of particles. */ - memcpy(index->nparts, index->index.map + csds_index_npart_offset, + memcpy(this->nparts, this->index->mMap + csds_index_npart_offset, csds_index_npart_size); /* Read whether the file is sorted. */ - memcpy(&index->is_sorted, index->index.map + csds_index_is_sorted_offset, + memcpy(&this->is_sorted, this->index->mMap + csds_index_is_sorted_offset, csds_index_is_sorted_size); /* Compute the position of the history of new particles. */ size_t count = 0; for (int i = 0; i < csds_type_count; i++) { - count += index->nparts[i]; + count += this->nparts[i]; } count *= sizeof(struct index_data); /* Read the number of new particles. */ - memcpy(index->nparts_created, - index->index.map + csds_index_data_offset + count, + memcpy(this->nparts_created, + this->index->mMap + csds_index_data_offset + count, csds_index_npart_size); /* Compute the position of the history of particles removed. */ size_t count_new = 0; for (int i = 0; i < csds_type_count; i++) { - count_new += index->nparts_created[i]; + count_new += this->nparts_created[i]; } count_new *= sizeof(struct index_data); /* Read the number of particles removed. */ - memcpy(index->nparts_removed, - index->index.map + csds_index_data_offset + count + + memcpy(this->nparts_removed, + this->index->mMap + csds_index_data_offset + count + csds_index_npart_size + count_new, csds_index_npart_size); /* Close the file */ - csds_index_free(index); + delete this->index; + this->index = NULL; } /** @@ -116,12 +117,15 @@ void csds_index_read_header(struct csds_index *index, * * @param index The #csds_index. */ -void csds_index_write_sorted(struct csds_index *index) { +void csds_index_write_sorted(IndexFile *index) { + if (index->index == NULL) { + csds_error("File is not mapped"); + } /* Set the value */ const char is_sorted = 1; /* Write the value */ - memcpy(index->index.map + csds_index_is_sorted_offset, &is_sorted, + memcpy(index->index->mMap + csds_index_is_sorted_offset, &is_sorted, csds_index_is_sorted_size); } @@ -134,7 +138,7 @@ void csds_index_write_sorted(struct csds_index *index) { * @param index The #csds_index. * @param type The particle type. */ -struct index_data *csds_index_get_data(struct csds_index *index, int type) { +struct index_data *csds_index_get_data(IndexFile *index, int type) { /* Get the offset of particles of this type by skipping entries of lower * types. */ size_t count = 0; @@ -143,7 +147,7 @@ struct index_data *csds_index_get_data(struct csds_index *index, int type) { } const size_t type_offset = count * sizeof(struct index_data); - const char *ret = index->index.map + csds_index_data_offset + type_offset; + const char *ret = index->index->mMap + csds_index_data_offset + type_offset; return (struct index_data *)ret; } @@ -156,8 +160,7 @@ struct index_data *csds_index_get_data(struct csds_index *index, int type) { * @param index The #csds_index. * @param type The particle type. */ -struct index_data *csds_index_get_created_history(struct csds_index *index, - int type) { +struct index_data *csds_index_get_created_history(IndexFile *index, int type) { /* Get the position after the previous array. */ char *ret = (char *)csds_index_get_data(index, csds_type_count); @@ -183,8 +186,7 @@ struct index_data *csds_index_get_created_history(struct csds_index *index, * @param index The #csds_index. * @param type The particle type. */ -struct index_data *csds_index_get_removed_history(struct csds_index *index, - int type) { +struct index_data *csds_index_get_removed_history(IndexFile *index, int type) { /* Get the position after the previous array. */ char *ret = (char *)csds_index_get_created_history(index, csds_type_count); @@ -206,18 +208,18 @@ struct index_data *csds_index_get_removed_history(struct csds_index *index, * * @param index The #csds_index. */ -int csds_index_contains_time_array(struct csds_index *index) { +int csds_index_contains_time_array(IndexFile *index) { /* Only the first index file should have a time array */ if (index->integer_time != 0) { csds_error("Only the first index file can have a time array."); } /* Get the file size */ - const size_t file_size = index->index.mmap_size; + const size_t file_size = index->index->mMapSize; /* Get the position after the previous array. */ char *ret = (char *)csds_index_get_removed_history(index, csds_type_count); - const size_t before_time_array = ret - index->index.map; + const size_t before_time_array = ret - index->index->mMap; return file_size != before_time_array; } @@ -230,10 +232,10 @@ int csds_index_contains_time_array(struct csds_index *index) { * @param sorted Does the file needs to be sorted? * @param verbose the verbose level */ -void csds_index_map_file(struct csds_index *index, const std::string filename, +void csds_index_map_file(IndexFile *index, const std::string filename, int sorted, int verbose) { /* Un-map previous file */ - if (index->index.map != NULL) { + if (index->index != NULL) { csds_error("Trying to remap."); } @@ -243,8 +245,9 @@ void csds_index_map_file(struct csds_index *index, const std::string filename, message("Sorting the index file."); } /* Map the index file */ - csds_mapped_file_mmap_file(index->index, filename, - /* read_only */ 0, /* track_mmap */ 0); + index->index = new MappedFile(filename, + /* read_only */ 0, + /* track_mmap */ 0); /* Sort the file */ for (int i = 0; i < csds_type_count; i++) { if (index->nparts[i] != 0) { @@ -257,7 +260,8 @@ void csds_index_map_file(struct csds_index *index, const std::string filename, csds_index_write_sorted(index); /* Free the index file before opening it again in read only */ - csds_index_free(index); + delete index->index; + index->index = NULL; if (verbose > 1) { message("Sorting done."); @@ -265,8 +269,8 @@ void csds_index_map_file(struct csds_index *index, const std::string filename, } /* Map the index file */ - csds_mapped_file_mmap_file(index->index, filename, - /* read_only */ 1, /* track_mmap */ 0); + index->index = new MappedFile(filename, /* read_only */ 1, + /* track_mmap */ 0); } /** @@ -274,11 +278,11 @@ void csds_index_map_file(struct csds_index *index, const std::string filename, * * @param index The #csds_index. */ -void csds_index_free(struct csds_index *index) { - if (index->index.map == NULL) { - csds_error("Trying to unmap an unexisting map"); +IndexFile::~IndexFile() { + if (this->index != NULL) { + delete this->index; + this->index = NULL; } - csds_mapped_file_munmap_file(index->index); } /** @@ -290,7 +294,7 @@ void csds_index_free(struct csds_index *index) { * * @return The offset of the particle or 0 if not found. */ -size_t csds_index_get_particle_offset(struct csds_index *index, long long id, +size_t csds_index_get_particle_offset(IndexFile *index, long long id, int type) { /* Define a few variables */ const struct index_data *data = csds_index_get_data(index, type); @@ -312,19 +316,6 @@ size_t csds_index_get_particle_offset(struct csds_index *index, long long id, return 0; } -/** - * @brief Initialize the #csds_index. - * - * @param index The #csds_index. - */ -void csds_index_init(struct csds_index *index) { - /* Set the mapped file to NULL */ - index->index.map = NULL; - - /* Set the time to its default value */ - index->time = -1; -} - /** * @brief Give the offset of a particle given its id. * @@ -335,7 +326,7 @@ void csds_index_init(struct csds_index *index) { * * @return Did we find the particle? */ -int csds_index_get_offset(struct csds_index *index, int64_t id, int type, +int csds_index_get_offset(IndexFile *index, int64_t id, int type, uint64_t *offset) { /* Ensure that the file is sorted according to the ids. */ diff --git a/src/csds_index.hpp b/src/csds_index.hpp index 394746f47bcbdd3a29e7edd21cbdfd60534c4251..7227e19ad666f1bf0f97bca3d13d8367b6f7b79b 100644 --- a/src/csds_index.hpp +++ b/src/csds_index.hpp @@ -25,10 +25,9 @@ #include "csds_tools.hpp" /** - * @brief Structure dealing with the index files. + * @brief Class dealing with the index files. * - * The structure is initialized with #csds_index_init and - * then a file can be read with #csds_index_read_header and + * A file can be read with #csds_index_read_header and * #csds_index_map_file. * * The functions #csds_index_get_particle_offset and @@ -37,7 +36,11 @@ * The first one access a particle through its ids and the second one * gives a pointer to the first element that can be looped through. */ -struct csds_index { +class IndexFile { + public: + IndexFile(const std::string filename, int verbose); + ~IndexFile(); + /* Time of the index file */ double time; @@ -51,7 +54,7 @@ struct csds_index { char is_sorted; /* The mapped file */ - struct mapped_file index; + MappedFile *index; /* Number of particles created. */ uint64_t nparts_created[csds_type_count]; @@ -60,23 +63,16 @@ struct csds_index { uint64_t nparts_removed[csds_type_count]; }; -int csds_index_contains_time_array(struct csds_index *index); -void csds_index_write_sorted(struct csds_index *index); -void csds_index_init(struct csds_index *index); -void csds_index_read_header(struct csds_index *index, - const std::string filename, int verbose); -void csds_index_map_file(struct csds_index *index, const std::string filename, +int csds_index_contains_time_array(IndexFile *index); +void csds_index_write_sorted(IndexFile *index); +void csds_index_map_file(IndexFile *index, const std::string filename, int sorted, int verbose); -size_t csds_index_get_particle_offset(struct csds_index *index, long long id, - int type); -void csds_index_free(struct csds_index *index); -void csds_index_sort_file(struct csds_index *index); -int csds_index_get_offset(struct csds_index *index, int64_t id, int type, +size_t csds_index_get_particle_offset(IndexFile *index, long long id, int type); +void csds_index_sort_file(IndexFile *index); +int csds_index_get_offset(IndexFile *index, int64_t id, int type, uint64_t *offset); -struct index_data *csds_index_get_data(struct csds_index *index, int type); -struct index_data *csds_index_get_created_history(struct csds_index *index, - int type); -struct index_data *csds_index_get_removed_history(struct csds_index *index, - int type); +struct index_data *csds_index_get_data(IndexFile *index, int type); +struct index_data *csds_index_get_created_history(IndexFile *index, int type); +struct index_data *csds_index_get_removed_history(IndexFile *index, int type); #endif // CSDS_INDEX_H diff --git a/src/csds_logfile.cpp b/src/csds_logfile.cpp index 6e5af7874f58cd21383b8b2bb358502c4037d2c1..44e19db37ae1870144b9ae78ed5dd712a1c973f6 100644 --- a/src/csds_logfile.cpp +++ b/src/csds_logfile.cpp @@ -27,33 +27,30 @@ using namespace std; * @brief Initialize the #csds_logfile. * * If required this function will also reverse the offsets. - * @param log The #csds_logfile. * @param basename The basename. * @param verbose The verbose level. * @param only_header Read only the header. */ -void csds_logfile_init_from_file(struct csds_logfile *log, - const string basename, int only_header, - int verbose) { +LogFile::LogFile(const string basename, int only_header, int verbose) { /* Set pointers to zero. */ - time_array_init(&log->times, CSDS_TIME_INIT_SIZE); + time_array_init(&this->times, CSDS_TIME_INIT_SIZE); /* Generate the logfile filename */ string logfile_name = basename + ".dump"; /* Open file, map it and get its size. */ if (verbose > 1) message("Mapping the log file."); - csds_mapped_file_mmap_file(log->log, logfile_name, - /* read_only */ 1, /* track_mmap */ 1); + this->log = + new MappedFile(logfile_name, /* read_only */ true, /* track_mmap */ true); /* Read the header. */ if (verbose > 1) message("Reading the header."); - header_read(&log->header, log, verbose); + header_read(&this->header, this, verbose); /* Print the header. */ if (verbose > 0) { - header_print(&log->header); + header_print(&this->header); } /* No need to continue if only the @@ -61,22 +58,22 @@ void csds_logfile_init_from_file(struct csds_logfile *log, if (only_header) return; /* Check if the offset are corrupted. */ - if (header_is_corrupted(&log->header)) { + if (header_is_corrupted(&this->header)) { csds_error("The offsets have been corrupted."); } /* Reverse the offsets direction. */ - if (header_is_backward(&log->header)) { - csds_logfile_reverse_offset(log, logfile_name, verbose); + if (header_is_backward(&this->header)) { + csds_logfile_reverse_offset(*this, logfile_name, verbose); } /* Initialize the time array. */ if (verbose > 1) message("Reading the timestamps."); - time_array_populate(&log->times, log, basename, verbose); + time_array_populate(&this->times, this, basename, verbose); /* Print the time array. */ if (verbose > 0) { - time_array_print(&log->times); + time_array_print(&this->times); } } @@ -85,12 +82,12 @@ void csds_logfile_init_from_file(struct csds_logfile *log, * * @param log The #csds_logfile. */ -void csds_logfile_free(struct csds_logfile *log) { - csds_mapped_file_munmap_file(log->log); +LogFile::~LogFile() { + delete this->log; - time_array_free(&log->times); + time_array_free(&this->times); - header_free(&log->header); + header_free(&this->header); } /** @@ -103,10 +100,10 @@ void csds_logfile_free(struct csds_logfile *log) { * @param log The #csds_logfile * @param verbose The verbose level */ -void csds_logfile_check_record_consistency(ATTR_UNUSED struct csds_logfile *log, +void csds_logfile_check_record_consistency(ATTR_UNUSED LogFile &log, ATTR_UNUSED int verbose) { #ifdef CSDS_DEBUG_CHECKS - struct header *header = &log->header; + struct header *header = &log.header; if (verbose > 0) { message("Check record's headers..."); @@ -119,11 +116,11 @@ void csds_logfile_check_record_consistency(ATTR_UNUSED struct csds_logfile *log, /* check that the record offset points to another record. */ for (size_t offset_debug = header->offset_first_record; - offset_debug < log->log.mmap_size; - offset_debug = tools_check_record_consistency(log, offset_debug)) { + offset_debug < log.log->mMapSize; + offset_debug = tools_check_record_consistency(&log, offset_debug)) { /* Check if we should update the progress bar. */ - float current = 100 * ((float)offset_debug) / log->log.mmap_size; + float current = 100 * ((float)offset_debug) / log.log->mMapSize; if (verbose > 0 && current > next_percentage) { /* Print the bar */ tools_print_progress(current, init, "Checking offsets"); @@ -151,16 +148,15 @@ void csds_logfile_check_record_consistency(ATTR_UNUSED struct csds_logfile *log, * @param log The #csds_logfile * @param filename The log's filename. */ -void csds_logfile_reverse_offset(struct csds_logfile *log, std::string filename, +void csds_logfile_reverse_offset(LogFile &log, std::string filename, int verbose) { /* Close and reopen the file in write mode. */ - csds_mapped_file_munmap_file(log->log); - csds_mapped_file_mmap_file(log->log, filename, - /* read_only */ 0, /* track_mmap */ 0); + delete log.log; + log.log = new MappedFile(filename, /* read_only */ 0, /* track_mmap */ 0); /* Get pointers */ - struct header *header = &log->header; + struct header *header = &log.header; /* Check if the offsets need to be reversed. */ if (!header_is_backward(header)) { @@ -186,10 +182,10 @@ void csds_logfile_reverse_offset(struct csds_logfile *log, std::string filename, const high_resolution_clock::time_point init = high_resolution_clock::now(); /* reverse the record's offset. */ - for (size_t offset = header->offset_first_record; offset < log->log.mmap_size; - offset = tools_reverse_offset(header, log->log, offset)) { + for (size_t offset = header->offset_first_record; offset < log.log->mMapSize; + offset = tools_reverse_offset(header, *log.log, offset)) { /* Check if we should update the progress. */ - float current = 100 * ((float)offset) / log->log.mmap_size; + float current = 100 * ((float)offset) / log.log->mMapSize; if (verbose > 0 && current > next_percentage) { /* Print the remaining time */ @@ -217,8 +213,8 @@ void csds_logfile_reverse_offset(struct csds_logfile *log, std::string filename, #endif /* Close and reopen the file in read mode. */ - csds_mapped_file_munmap_file(log->log); - csds_mapped_file_mmap_file(log->log, filename, - /* read_only */ 1, - /* track_mmap */ 1); + delete log.log; + log.log = new MappedFile(filename, + /* read_only */ 1, + /* track_mmap */ 1); } diff --git a/src/csds_logfile.hpp b/src/csds_logfile.hpp index 6191d0daed37a2d42d9f7f42ec5f70ebccee5648..f8c8f5d138a6464963f0f0d906353c57aa01c1fe 100644 --- a/src/csds_logfile.hpp +++ b/src/csds_logfile.hpp @@ -28,16 +28,12 @@ #include "csds_time.hpp" /** - * @brief This structure deals with the log file. - * - * This structure is initialized by the #csds_reader - * and deals with the log file. - * It maps it, reverse the offsets (if required) and unmap it. - * - * The structure is initialized with #csds_logfile_init_from_file and - * freed with #csds_logfile_free. + * @brief This class deals with the log file. */ -struct csds_logfile { +class LogFile { + public: + LogFile(const std::string basename, int only_header, int verbose); + ~LogFile(); /* Information contained in the file header. */ struct header header; @@ -46,14 +42,10 @@ struct csds_logfile { struct time_array times; /* The file. */ - struct mapped_file log; + MappedFile *log; }; -void csds_logfile_init_from_file(struct csds_logfile *log, - const std::string basename, int only_header, - int verbose); -void csds_logfile_reverse_offset(struct csds_logfile *log, std::string filename, +void csds_logfile_reverse_offset(LogFile &log, std::string filename, int verbose); -void csds_logfile_free(struct csds_logfile *log); #endif // CSDS_LOGFILE_H diff --git a/src/csds_mapped_file.cpp b/src/csds_mapped_file.cpp index 9aa067aab0d2c1ad51c5c9782487dfd4d9824a4d..a49ebbce50cf60bb952bd546095820ae66efd866 100644 --- a/src/csds_mapped_file.cpp +++ b/src/csds_mapped_file.cpp @@ -59,14 +59,13 @@ string strip_ext(string fname) { * * #csds_loader_io_munmap_file should be called to unmap the file. * - * @param map The #mapped_file. * @param filename file to read. * @param read_only Open the file in read only mode? * @param track_mmap Should we track the memory reading? * */ -void csds_mapped_file_mmap_file(struct mapped_file &map, const string filename, - int read_only, ATTR_UNUSED int track_mmap) { +MappedFile::MappedFile(const string filename, bool read_only, + ATTR_UNUSED bool track_mmap) { /* open the file. */ int fd; @@ -80,15 +79,15 @@ void csds_mapped_file_mmap_file(struct mapped_file &map, const string filename, << ")"); /* get the file size. */ - map.mmap_size = csds_loader_io_get_file_size(fd); + this->mMapSize = csds_loader_io_get_file_size(fd); /* map the memory. */ int mode = PROT_READ; if (!read_only) mode |= PROT_WRITE; - map.map = (char *)mmap(NULL, map.mmap_size, mode, MAP_SHARED, fd, 0); - if (map.map == MAP_FAILED) - csds_error("Failed to allocate map of size " << map.mmap_size << " bytes (" + this->mMap = (char *)mmap(NULL, this->mMapSize, mode, MAP_SHARED, fd, 0); + if (this->mMap == MAP_FAILED) + csds_error("Failed to allocate map of size " << this->mMapSize << " bytes (" << strerror(errno) << ")"); /* Close the file. */ @@ -96,9 +95,9 @@ void csds_mapped_file_mmap_file(struct mapped_file &map, const string filename, #ifdef CSDS_MMAP_TRACKING /* Now deal with the mmap tracking */ - map.tracking.f = NULL; - map.tracking.number_elements = 0; - map.tracking.size = 0; + this->mTracking.number_elements = 0; + this->mTracking.size = 0; + this->mTracking.use_tracking = track_mmap; /* Nothing to do without tracking */ if (!track_mmap) return; @@ -108,14 +107,12 @@ void csds_mapped_file_mmap_file(struct mapped_file &map, const string filename, tracking_filename = strip_ext(tracking_filename); tracking_filename += ".track"; - map.tracking.f = fopen(tracking_filename, "w"); - if (map.tracking.f == NULL) - csds_error("Unable to open file " << tracking_filename << " (" - << strerror(errno) << ")"); + this->mTracking.stream = std::ofstream( + tracking_filename, std::ofstream::out | std::ofstream::binary); /* Write the header */ - fprintf(map.tracking.f, "%20s", "CSDS_TRACK"); - fwrite(&map.tracking.number_elements, 1, sizeof(int64_t), map.tracking.f); + this->mTracking.stream << std::setw(20) << std::left << "CSDS_TRACK"; + this->mTracking.stream << this->mTracking.number_elements; #endif } @@ -123,25 +120,11 @@ void csds_mapped_file_mmap_file(struct mapped_file &map, const string filename, * @brief Unmap a file. * * @param map The #mapped_file. - * */ -void csds_mapped_file_munmap_file(struct mapped_file &map) { +MappedFile::~MappedFile() { /* unmap the file. */ - if (munmap(map.map, map.mmap_size) != 0) { - csds_error("Unable to unmap the file :" << strerror(errno)); + if (munmap(this->mMap, this->mMapSize) != 0) { + message("Unable to unmap the file :" << strerror(errno)); + csds_abort(186); } - - /* Reset values */ - map.map = NULL; - map.mmap_size = 0; - -#ifdef CSDS_MMAP_TRACKING - /* Now deal with tracking */ - if (map.tracking.f == NULL) return; - - fclose(map.tracking.f); - - /* Reset the values */ - map.tracking.f = NULL; -#endif } diff --git a/src/csds_mapped_file.hpp b/src/csds_mapped_file.hpp index dbc879174d4f9cec8e8fc99f9f9107408d7ce690..550ca03b0630fac570be13a8a896e4380220bc9f 100644 --- a/src/csds_mapped_file.hpp +++ b/src/csds_mapped_file.hpp @@ -28,6 +28,8 @@ #include "csds_tools.hpp" /* Standard headers */ +#include <fstream> +#include <iostream> #include <stdio.h> #include <stdlib.h> #include <sys/mman.h> @@ -36,207 +38,200 @@ #define CSDS_VERBOSE_TIMERS -1 #define CSDS_TRACKING_SIZE_BYTES (1024 * 1024 * 1024) -/* Structure for mapping a file. */ -struct mapped_file { - /* Mapped data. */ - char *map; - - /* File size. */ - size_t mmap_size; - -#ifdef CSDS_MMAP_TRACKING - struct { - /* File for the tracking (should not use mmap file) */ - FILE *f; - - /* Size of the file? */ - size_t size; +size_t csds_loader_io_get_file_size(int fd); - /* Current number of elements */ - int64_t number_elements; - } tracking; -#endif +/** @brief Structure for the record header */ +struct record_header { + mask_type mask; + size_t offset; }; #ifdef CSDS_MMAP_TRACKING /** - * @brief Structure written in the tracking file. + * @brief Class for tracking the mmap readings. */ -struct mmap_tracking_element { - /* Number of ticks for accessing the page */ - int64_t ticks; +class MMapTrackingElement { + + public: + MMapTrackingElement(size_t offset) : mOffset(offset) { + this->mChrono = high_resolution_clock::now(); + } + + friend std::ostream &operator<<(std::ostream &output, + const MMapTrackingElement &el) { + int64_t time = GetDeltaTime(el.mChrono); + output << time << el.mOffset; + return output; + } + + /* Chrono for measuring the data access */ + high_resolution_clock::time_point mChrono; /* Offset accessed */ - long long offset; + long long mOffset; }; +#endif -/** @brief Initialize a tracking element */ -INLINE static void mmap_tracking_element_init(struct mmap_tracking_element *el, - size_t offset) { - el->ticks = getticks(); - el->offset = offset; -} - -/** @brief Write a tracking element into the file */ -INLINE static void mmap_tracking_element_write(struct mmap_tracking_element *el, - struct mapped_file &file) { -#pragma omp critical - { - /* Stop when file becomes too huge */ - if (file.tracking.size < CSDS_TRACKING_SIZE_BYTES) { - - /* Write the element */ - fwrite(el, 1, sizeof(struct mmap_tracking_element), file.tracking.f); - - /* Update the counter */ - file.tracking.number_elements++; - - /* Write it back to the file */ - const long int pos = ftell(file.tracking.f); - /* See csds_mapped_file_mmap_file for the value */ - fseek(file.tracking.f, 20, SEEK_SET); - fwrite(&file.tracking.number_elements, 1, - sizeof(file.tracking.number_elements), file.tracking.f); - fseek(file.tracking.f, pos, SEEK_SET); - - /* Update the file size */ - file.tracking.size += sizeof(struct mmap_tracking_element); - } - } -} +/* Structure for mapping a file. */ +class MappedFile { + + public: + MappedFile(const std::string filename, bool read_only, bool track_mmap); + ~MappedFile(); + + /** + * @brief read a record header. + * + * @param offset The offset in the file + * @param header (output) header read from the file. + * + * @return The offset after the record header. + */ + size_t ReadRecordHeader(size_t offset, record_header &header) { +#ifdef CSDS_MMAP_TRACKING + MMapTrackingElement el(offset); #endif -size_t csds_loader_io_get_file_size(int fd); -void csds_mapped_file_mmap_file(struct mapped_file &map, - const std::string filename, int read_only, - int track_mmap); -void csds_mapped_file_munmap_file(struct mapped_file &map); + /* read mask */ + header.mask = 0; + memcpy(&header.mask, this->mMap + offset, CSDS_MASK_SIZE); + offset += CSDS_MASK_SIZE; + + /* read offset */ + header.offset = 0; + memcpy(&header.offset, this->mMap + offset, CSDS_OFFSET_SIZE); + offset += CSDS_OFFSET_SIZE; -/** - * @brief read a mask with its offset. - * - * @param mmap The #mapped_file. - * @param offset The offset in the file - * @param mask (output) mask read from the file. - * @param diff_offset (output) offset difference to previous/next corresponding - * record. - * - * @return The offset after the record header. - */ -INLINE static size_t csds_mapped_file_read_mask(struct mapped_file &mmap, - size_t offset, mask_type *mask, - size_t *diff_offset) { #ifdef CSDS_MMAP_TRACKING - struct mmap_tracking_element el; - mmap_tracking_element_init(&el, offset); + /* Write the result into the file */ + if (this->mTracking.use_tracking) { + this->WriteTracking(el); + } #endif - /* read mask */ - if (mask) { - *mask = 0; - memcpy(mask, mmap.map + offset, CSDS_MASK_SIZE); + return offset; } - offset += CSDS_MASK_SIZE; - /* read offset */ - if (diff_offset) { - *diff_offset = 0; - memcpy(diff_offset, mmap.map + offset, CSDS_OFFSET_SIZE); - } - offset += CSDS_OFFSET_SIZE; + /** + * @brief read a single value from a file. + * + * @param offset The offset in the file + * @param size size of the data to read. + * @param p pointer where to store the data. + * + * @return The offset after the data read. + */ + size_t ReadData(size_t offset, const size_t size, void *p) { +#ifdef CSDS_MMAP_TRACKING + MMapTrackingElement el(offset); +#endif + + memcpy(p, this->mMap + offset, size); #ifdef CSDS_MMAP_TRACKING - /* Write the result into the file */ - el.ticks = getticks() - el.ticks; - if (mmap.tracking.f) { - mmap_tracking_element_write(&el, mmap); - } + /* Write the result into the file */ + if (this->mTracking.use_tracking) { + this->WriteTracking(el); + } #endif - return offset; -} + return offset + size; + }; -/** - * @brief read a single value from a file. - * - * @param mmap The #mapped_file. - * @param offset The offset in the file - * @param size size of the data to read. - * @param p pointer where to store the data. + /** + * @brief write a single value in a file. + * + * @param offset The offset in the file + * @param size size of the data to write. + * @param p pointer to the data. + * + * @return memory after the data written. + */ + size_t WriteData(size_t offset, const size_t size, const void *p) { - * @return The offset after the data read. - */ -INLINE static size_t csds_mapped_file_read_data(struct mapped_file &mmap, - size_t offset, - const size_t size, void *p) { #ifdef CSDS_MMAP_TRACKING - struct mmap_tracking_element el; - mmap_tracking_element_init(&el, offset); + MMapTrackingElement el(offset); #endif - memcpy(p, mmap.map + offset, size); + memcpy(this->mMap + offset, p, size); #ifdef CSDS_MMAP_TRACKING - /* Write the result into the file */ - el.ticks = getticks() - el.ticks; - if (mmap.tracking.f) { - mmap_tracking_element_write(&el, mmap); - } + /* Write the result into the file */ + if (this->mTracking.use_tracking) { + this->WriteTracking(el); + } #endif - return offset + size; -}; + return offset + size; + }; -/** - * @brief write a single value in a file. - * - * @param mmap The #mapped_file. - * @param offset The offset in the file - * @param size size of the data to write. - * @param p pointer to the data. - * - * @return memory after the data written. - */ -INLINE static size_t csds_mapped_file_write_data(struct mapped_file &mmap, - size_t offset, - const size_t size, - const void *p) { + /* Mapped data. */ + char *mMap; + /* File size. */ + size_t mMapSize; + protected: #ifdef CSDS_MMAP_TRACKING - struct mmap_tracking_element el; - mmap_tracking_element_init(&el, offset); -#endif + struct { + /* File for the tracking (should not use mmap file) */ + std::ofstream stream; - memcpy(mmap.map + offset, p, size); + /* Size of the file? */ + size_t size; -#ifdef CSDS_MMAP_TRACKING - /* Write the result into the file */ - el.ticks = getticks() - el.ticks; - if (mmap.tracking.f) { - mmap_tracking_element_write(&el, mmap); + /* Current number of elements */ + int64_t number_elements; + + /* Are we tracking the reading? */ + bool use_tracking; + } mTracking; + + /** @brief Write a tracking element into the file */ + void WriteTracking(const MMapTrackingElement &el) { +#pragma omp critical + { + /* Stop when file becomes too huge */ + if (this->mTracking.size < CSDS_TRACKING_SIZE_BYTES) { + + /* Write the element */ + this->mTracking.stream << el; + + /* Update the counter */ + this->mTracking.number_elements++; + + /* Write it back to the file */ + const std::streampos pos = this->mTracking.stream.tellp(); + + /* See MappedFile constructor for the value */ + this->mTracking.stream.seekp(20); + this->mTracking.stream << this->mTracking.number_elements; + this->mTracking.stream.seekp(pos); + + /* Update the file size */ + this->mTracking.size += sizeof(MMapTrackingElement); + } + } } #endif - - return offset + size; }; /* Defines a few advice for the mmap */ -#define CSDS_ADVICE_SEQUENTIAL(log) \ - { \ - /* Warn the OS that we will read in a sequential way */ \ - int test_ret = madvise(log.map, log.mmap_size, MADV_SEQUENTIAL); \ - if (test_ret != 0) { \ - csds_error("Failed to advise the mmap"); \ - } \ +#define CSDS_ADVICE_SEQUENTIAL(log) \ + { \ + /* Warn the OS that we will read in a sequential way */ \ + int test_ret = madvise(log->mMap, log->mMapSize, MADV_SEQUENTIAL); \ + if (test_ret != 0) { \ + csds_error("Failed to advise the mmap"); \ + } \ } -#define CSDS_ADVICE_NORMAL(log) \ - { \ - /* Warn the OS that we will read in a normal way */ \ - int test_ret = madvise(log.map, log.mmap_size, MADV_NORMAL); \ - if (test_ret != 0) { \ - csds_error("Failed to advise the mmap"); \ - } \ +#define CSDS_ADVICE_NORMAL(log) \ + { \ + /* Warn the OS that we will read in a normal way */ \ + int test_ret = madvise(log->mMap, log->mMapSize, MADV_NORMAL); \ + if (test_ret != 0) { \ + csds_error("Failed to advise the mmap"); \ + } \ } #define CSDS_ADVICE_WILL_NEED(mmap, addr, length) \ diff --git a/src/csds_particle.hpp b/src/csds_particle.hpp index d757333da609dcc682984b539434ff0da5dcb192..00ac57817859c2c7367c4aade36dced79d6c85c7 100644 --- a/src/csds_particle.hpp +++ b/src/csds_particle.hpp @@ -40,8 +40,7 @@ * @param output Buffer for the requested field. * @param field_read The field to read. * @param derivative The derivative to read (0 for the field). - * @param mask (out) The mask of the record. - * @param h_offset (out) Difference of offset with the next record. + * @param header (out) The record header. * @param fields The list of available fields * @param number_fields The number of fields * @param log_map The mmap logfile. @@ -50,19 +49,16 @@ */ INLINE static size_t csds_particle_read_field( size_t offset, void *output, const struct field_information *field_read, - const int derivative, mask_type *mask, size_t *h_offset, + const int derivative, struct record_header &header, const struct field_information *fields, int number_fields, - struct mapped_file &log_map) { - - *mask = 0; - *h_offset = 0; + MappedFile &log_map) { /* Read the record's mask. */ - offset = csds_mapped_file_read_mask(log_map, offset, mask, h_offset); + offset = log_map.ReadRecordHeader(offset, header); #ifdef CSDS_DEBUG_CHECKS /* Check if it is not a time record. */ - if (*mask == CSDS_TIMESTAMP_MASK) { + if (header.mask == CSDS_TIMESTAMP_MASK) { csds_error("Cannot read a particle from timestep record."); } @@ -92,14 +88,13 @@ INLINE static size_t csds_particle_read_field( for (int i = 0; i < number_fields; i++) { /* Is the mask present? */ - if (!(*mask & fields[i].field.mask)) { + if (!(header.mask & fields[i].field.mask)) { continue; } if (position == i) { /* Read the data. */ - offset = csds_mapped_file_read_data(log_map, offset, fields[i].field.size, - output); + offset = log_map.ReadData(offset, fields[i].field.size, output); } else { /* Update the buffer's position. */ offset += fields[i].field.size; @@ -142,34 +137,29 @@ INLINE static enum csds_special_flags csds_unpack_flags_and_data( * @brief Read the special flag of a particle (of any type) in the log file. * * @param offset offset of the record to read. - * @param mask (out) The mask of the record. - * @param h_offset (out) Difference of offset with the next record. + * @param header (out) The header of the record. * @param data (out) The data of the flag. * @param part_type (out) The type of particle raising this flag. * * @return The special flag. */ INLINE static enum csds_special_flags csds_particle_read_special_flag( - size_t offset, mask_type *mask, size_t *h_offset, int *data, int *part_type, - struct mapped_file &map) { - - *mask = 0; - *h_offset = 0; + size_t offset, struct record_header &header, int *data, int *part_type, + MappedFile &map) { /* Read the record's mask. */ - offset = csds_mapped_file_read_mask(map, offset, mask, h_offset); + offset = map.ReadRecordHeader(offset, header); #ifdef CSDS_DEBUG_CHECKS /* Check if it is not a time record. */ - if (*mask == CSDS_TIMESTAMP_MASK) { + if (header.mask == CSDS_TIMESTAMP_MASK) { csds_error("Cannot read a particle from timestep record."); } #endif /* Read the special flag */ uint32_t packed_data = 0; - offset = csds_mapped_file_read_data(map, offset, CSDS_SPECIAL_FLAGS_SIZE, - &packed_data); + offset = map.ReadData(offset, CSDS_SPECIAL_FLAGS_SIZE, &packed_data); return csds_unpack_flags_and_data(packed_data, data, part_type); } diff --git a/src/csds_reader.cpp b/src/csds_reader.cpp index f70e8bb69031bf5190982ab02f9d1c879826012c..0a751ca942bcbb3d9cad6da5f303e7a8dd4d5fe2 100644 --- a/src/csds_reader.cpp +++ b/src/csds_reader.cpp @@ -51,7 +51,8 @@ Reader::Reader(const string basename, int verbose, int number_index, this->mTime.time_offset = 0; this->mUseCache = use_cache; this->mBasename = basename; - this->mLog = new struct csds_logfile; + this->mIndex.index_prev = NULL; + this->mIndex.index_next = NULL; /* Initialize the reader variables. */ this->mVerbose = verbose; @@ -64,8 +65,7 @@ Reader::Reader(const string basename, int verbose, int number_index, csds_parameters_init(&this->mParams, params_filename, this->mVerbose); /* Initialize the log file. */ - csds_logfile_init_from_file(this->mLog, basename, - /* only_header */ 0, this->mVerbose); + this->mLog = new LogFile(basename, /* only_header */ 0, this->mVerbose); /* Initialize the index files and creates them if needed */ this->InitIndex(number_index, restart_init); @@ -86,10 +86,6 @@ Reader::Reader(const string basename, int verbose, int number_index, * @param restart Are we restarting the generation of index files? */ void Reader::InitIndex(int number_index, int restart) { - /* Initialize the csds_index */ - csds_index_init(&this->mIndex.index_prev); - csds_index_init(&this->mIndex.index_next); - /* Count the number of files */ int count = 0; while (1) { @@ -139,23 +135,23 @@ void Reader::InitIndex(int number_index, int restart) { string filename = this->GetIndexName(i); /* Read the header */ - csds_index_read_header(&this->mIndex.index_prev, filename, this->mVerbose); + this->mIndex.index_prev = new IndexFile(filename, this->mVerbose); /* Save the required information */ - this->mIndex.times[i] = this->mIndex.index_prev.time; - this->mIndex.int_times[i] = this->mIndex.index_prev.integer_time; + this->mIndex.times[i] = this->mIndex.index_prev->time; + this->mIndex.int_times[i] = this->mIndex.index_prev->integer_time; } } /** @brief Free the reader. */ Reader::~Reader() { /* Free the log. */ - csds_logfile_free(this->mLog); delete this->mLog; /* Free the index */ if (this->mTime.time != -1.) { - csds_index_free(&this->mIndex.index_prev); + delete this->mIndex.index_prev; + delete this->mIndex.index_next; } free(this->mIndex.int_times); @@ -214,22 +210,22 @@ void Reader::SetTime(double time) { string filename_next = this->GetIndexName(left + 1); /* Check if the file is already mapped */ - if (this->mIndex.index_prev.index.map != NULL) { - csds_index_free(&this->mIndex.index_prev); + if (this->mIndex.index_prev != NULL) { + delete this->mIndex.index_prev; + this->mIndex.index_prev = NULL; } - if (this->mIndex.index_next.index.map != NULL) { - csds_index_free(&this->mIndex.index_next); + if (this->mIndex.index_next != NULL) { + delete this->mIndex.index_next; + this->mIndex.index_next = NULL; } /* Read the file */ - csds_index_read_header(&this->mIndex.index_prev, filename_prev, - this->mVerbose); - csds_index_map_file(&this->mIndex.index_prev, filename_prev, + this->mIndex.index_prev = new IndexFile(filename_prev, this->mVerbose); + csds_index_map_file(this->mIndex.index_prev, filename_prev, /* sorted */ 1, this->mVerbose); - csds_index_read_header(&this->mIndex.index_next, filename_next, - this->mVerbose); - csds_index_map_file(&this->mIndex.index_next, filename_next, + this->mIndex.index_next = new IndexFile(filename_next, this->mVerbose); + csds_index_map_file(this->mIndex.index_next, filename_next, /* sorted */ 1, this->mVerbose); /* Get the offset of the time chunk */ @@ -266,16 +262,16 @@ size_t Reader::CountNumberNewParticles(enum part_type part_type) { /* Get the history of created particles. */ struct index_data *data = - csds_index_get_created_history(&this->mIndex.index_next, part_type); + csds_index_get_created_history(this->mIndex.index_next, part_type); /* Do we have any new particle? */ - if (this->mIndex.index_next.nparts_created[part_type] == 0 || + if (this->mIndex.index_next->nparts_created[part_type] == 0 || threshold < data[0].offset) { return 0; } /* Perform a binary search */ - size_t right = this->mIndex.index_next.nparts_created[part_type] - 1; + size_t right = this->mIndex.index_next->nparts_created[part_type] - 1; size_t left = 0; while (left <= right) { size_t m = (left + right) / 2; @@ -315,16 +311,16 @@ size_t Reader::CountNumberRemovedParticles(enum part_type part_type) { /* Get the history of created particles. */ struct index_data *data = - csds_index_get_removed_history(&this->mIndex.index_next, part_type); + csds_index_get_removed_history(this->mIndex.index_next, part_type); /* Do we have any new particle? */ - if (this->mIndex.index_next.nparts_removed[part_type] == 0 || + if (this->mIndex.index_next->nparts_removed[part_type] == 0 || threshold < data[0].offset) { return 0; } /* Perform a binary search */ - size_t right = this->mIndex.index_next.nparts_removed[part_type] - 1; + size_t right = this->mIndex.index_next->nparts_removed[part_type] - 1; size_t left = 0; while (left <= right) { size_t m = (left + right) / 2; @@ -367,7 +363,7 @@ void Reader::GetNumberParticles( } /* Count the number of particles present in the last index file. */ - const uint64_t count_prev = this->mIndex.index_prev.nparts[i]; + const uint64_t count_prev = this->mIndex.index_prev->nparts[i]; /* Count the number of particles that have been created since last index. */ const uint64_t count_new = this->CountNumberNewParticles((enum part_type)i); /* Count the number of particles that have been removed since last index. */ @@ -449,8 +445,7 @@ int Reader::ReadParticle(double time, } /* Record's header information */ - mask_type mask = 0; - size_t h_offset; + struct record_header header; /* The offset used for all the manipulations */ size_t offset = offset_from_index; @@ -463,14 +458,14 @@ int Reader::ReadParticle(double time, while (offset < offset_time) { *number_jumps += 1; /* Read the particle. */ - csds_mapped_file_read_mask(this->mLog->log, offset, &mask, &h_offset); + this->mLog->log->ReadRecordHeader(offset, header); /* Is the particle removed from the logfile? */ - if (mask & CSDS_SPECIAL_FLAGS_MASK) { + if (header.mask & CSDS_SPECIAL_FLAGS_MASK) { int data = 0; int part_type = 0; enum csds_special_flags flag = csds_particle_read_special_flag( - offset, &mask, &h_offset, &data, &part_type, this->mLog->log); + offset, header, &data, &part_type, *this->mLog->log); #ifdef CSDS_DEBUG_CHECKS if (part_type != type) { @@ -485,18 +480,18 @@ int Reader::ReadParticle(double time, } /* Check if there is a next record (avoid infinite loop). */ - if (h_offset == 0) { + if (header.offset == 0) { csds_error("No next record found."); } /* Go to the next record. */ - offset += h_offset; + offset += header.offset; } /* Set the next record */ size_t offset_next = offset; /* Go back before offset_time */ - offset -= h_offset; + offset -= header.offset; /* Loop over each field. */ for (size_t field = 0; field < fields_wanted.size(); field++) { @@ -505,34 +500,31 @@ int Reader::ReadParticle(double time, /* Read the field */ csds_particle_read_field(offset, current_output, current_field, - /* derivative */ 0, &mask, &h_offset, - h->fields[type], h->number_fields[type], - this->mLog->log); + /* derivative */ 0, header, h->fields[type], + h->number_fields[type], *this->mLog->log); /* Deal with the first derivative. */ int first_found = current_field->first.field != field_enum_none && - mask & current_field->first.mask; + header.mask & current_field->first.mask; char first_deriv[current_field->first.size]; if (first_found) { /* Read the first derivative */ csds_particle_read_field(offset, first_deriv, current_field, - /* derivative */ 1, &mask, &h_offset, - h->fields[type], h->number_fields[type], - this->mLog->log); + /* derivative */ 1, header, h->fields[type], + h->number_fields[type], *this->mLog->log); } /* Deal with the second derivative. */ int second_found = current_field->second.field != field_enum_none && - mask & current_field->second.mask; + header.mask & current_field->second.mask; char second_deriv[current_field->second.size]; if (second_found) { /* Read the first derivative */ csds_particle_read_field(offset, second_deriv, current_field, - /* derivative */ 2, &mask, &h_offset, - h->fields[type], h->number_fields[type], - this->mLog->log); + /* derivative */ 2, header, h->fields[type], + h->number_fields[type], *this->mLog->log); } /* Get the time. */ @@ -540,29 +532,27 @@ int Reader::ReadParticle(double time, double time_before = time_array_get_time(&this->mLog->times, offset); /* Get the mask */ - csds_mapped_file_read_mask(this->mLog->log, offset_next, &mask, &h_offset); + this->mLog->log->ReadRecordHeader(offset_next, header); /* Output after the requested time. */ char output_after[current_field->field.size]; /* Read the field */ csds_particle_read_field(offset_next, output_after, current_field, - /* derivative */ 0, &mask, &h_offset, - h->fields[type], h->number_fields[type], - this->mLog->log); + /* derivative */ 0, header, h->fields[type], + h->number_fields[type], *this->mLog->log); /* Deal with the first derivative. */ char first_deriv_after[current_field->first.size]; /* Did we find the derivative before and in this record? */ first_found = current_field->first.field != field_enum_none && - first_found && mask & current_field->first.mask; + first_found && header.mask & current_field->first.mask; if (first_found) { /* Read the first derivative */ csds_particle_read_field(offset_next, first_deriv_after, current_field, - /*derivative*/ 1, &mask, &h_offset, - h->fields[type], h->number_fields[type], - this->mLog->log); + /*derivative*/ 1, header, h->fields[type], + h->number_fields[type], *this->mLog->log); } /* Deal with the second derivative. */ @@ -570,13 +560,12 @@ int Reader::ReadParticle(double time, /* Did we find the derivative before and in this record? */ second_found = current_field->second.field != field_enum_none && - second_found && mask & current_field->second.mask; + second_found && header.mask & current_field->second.mask; if (second_found) { /* Read the second derivative */ csds_particle_read_field(offset_next, second_deriv_after, current_field, - /* derivative */ 2, &mask, &h_offset, - h->fields[type], h->number_fields[type], - this->mLog->log); + /* derivative */ 2, header, h->fields[type], + h->number_fields[type], *this->mLog->log); } /* Get the time. */ @@ -636,12 +625,12 @@ void Reader::ReadAllParticlesSingleType( } /* Create some information from the index files */ - const size_t size_index = this->mIndex.index_prev.nparts[type]; + const size_t size_index = this->mIndex.index_prev->nparts[type]; const size_t size_history = this->CountNumberNewParticles(type); - struct index_data *data = csds_index_get_data(&this->mIndex.index_prev, type); + struct index_data *data = csds_index_get_data(this->mIndex.index_prev, type); struct index_data *data_created = - csds_index_get_created_history(&this->mIndex.index_next, type); + csds_index_get_created_history(this->mIndex.index_next, type); /* Current index to read */ size_t current_index = 0; @@ -793,7 +782,7 @@ void Reader::ReadParticlesFromIdsSingleType( /* Get the offset */ size_t offset = 0; - int found = csds_index_get_offset(&this->mIndex.index_prev, (int64_t)ids[i], + int found = csds_index_get_offset(this->mIndex.index_prev, (int64_t)ids[i], type, &offset); /* Deal with the particles not found */ @@ -924,21 +913,19 @@ size_t Reader::ReadRecord(void **output, double *time, int *is_particle, /* Get a few pointers. */ const struct header *h = &this->mLog->header; - mask_type mask = 0; - size_t h_offset = 0; - /* Read the record's mask. */ - csds_mapped_file_read_mask(this->mLog->log, offset, &mask, &h_offset); + struct record_header header; + this->mLog->log->ReadRecordHeader(offset, header); - *is_particle = !(mask & CSDS_TIMESTAMP_MASK); + *is_particle = !(header.mask & CSDS_TIMESTAMP_MASK); /* The record is a particle. */ if (*is_particle) { size_t offset_tmp = offset; for (int i = 0; i < h->number_fields[csds_type_gas]; i++) { offset = csds_particle_read_field( offset_tmp, output[i], &h->fields[csds_type_gas][i], - /* derivative */ 0, &mask, &h_offset, h->fields[csds_type_gas], - h->number_fields[csds_type_gas], this->mLog->log); + /* derivative */ 0, header, h->fields[csds_type_gas], + h->number_fields[csds_type_gas], *this->mLog->log); } } /* The record is a timestamp. */ @@ -982,21 +969,19 @@ int Reader::UpdateSingleParticle(size_t index, enum part_type type, double time, /* Update the cache if needed */ if (offset_next < offset_time) { - mask_type mask = 0; - size_t h_offset = 0; + struct record_header header; /* Get the new offset */ while (offset_next < offset_time) { /* Read the particle. */ - csds_mapped_file_read_mask(this->mLog->log, offset_next, &mask, - &h_offset); + this->mLog->log->ReadRecordHeader(offset_next, header); /* Is the particle removed? */ - if (mask & CSDS_SPECIAL_FLAGS_MASK) { + if (header.mask & CSDS_SPECIAL_FLAGS_MASK) { int data = 0; int part_type = 0; enum csds_special_flags flag = csds_particle_read_special_flag( - offset_next, &mask, &h_offset, &data, &part_type, this->mLog->log); + offset_next, header, &data, &part_type, *this->mLog->log); #ifdef CSDS_DEBUG_CHECKS if (part_type != type) { @@ -1011,15 +996,15 @@ int Reader::UpdateSingleParticle(size_t index, enum part_type type, double time, } /* Check if there is a next record (avoid infinite loop). */ - if (h_offset == 0) { + if (header.offset == 0) { csds_error("No next record found."); } - offset_next += h_offset; + offset_next += header.offset; } /* Get a few variables for later */ - size_t offset_before = offset_next - h_offset; + size_t offset_before = offset_next - header.offset; time_before = time_array_get_time(&this->mLog->times, offset_before); time_after = time_array_get_time(&this->mLog->times, offset_next); @@ -1041,26 +1026,23 @@ int Reader::UpdateSingleParticle(size_t index, enum part_type type, double time, cache->total_size * index + cache->offset[i]; csds_particle_read_field(offset_next, current_output, info, - /* derivative */ 0, &mask, &h_offset, - h->fields[type], h->number_fields[type], - this->mLog->log); + /* derivative */ 0, header, h->fields[type], + h->number_fields[type], *this->mLog->log); current_output += info->field.size; /* Read the first derivative */ if (info->first.field != field_enum_none) { csds_particle_read_field(offset_next, current_output, info, - /* derivative */ 1, &mask, &h_offset, - h->fields[type], h->number_fields[type], - this->mLog->log); + /* derivative */ 1, header, h->fields[type], + h->number_fields[type], *this->mLog->log); current_output += info->first.size; } /* Read the second derivative */ if (info->second.field != field_enum_none) { csds_particle_read_field(offset_next, current_output, info, - /* derivative */ 2, &mask, &h_offset, - h->fields[type], h->number_fields[type], - this->mLog->log); + /* derivative */ 2, header, h->fields[type], + h->number_fields[type], *this->mLog->log); } } } @@ -1173,26 +1155,26 @@ void Reader::UpdateParticlesSingleType( /* Check if the index files are compatible */ size_t offset_index = time_array_get_index_from_time( - &this->mLog->times, this->mIndex.index_prev.time); + &this->mLog->times, this->mIndex.index_prev->time); offset_index = this->mLog->times.records[offset_index].offset; if (offset_index > this->mCache.last_time_offset) { csds_error("Requesting an update over more than one index file"); } offset_index = time_array_get_index_from_time(&this->mLog->times, - this->mIndex.index_next.time); + this->mIndex.index_next->time); offset_index = this->mLog->times.records[offset_index].offset; const int do_previous = this->mCache.last_time_offset < offset_index; /* Get the histories */ struct index_data *prev_created = - csds_index_get_created_history(&this->mIndex.index_prev, type); + csds_index_get_created_history(this->mIndex.index_prev, type); struct index_data *next_created = - csds_index_get_created_history(&this->mIndex.index_next, type); + csds_index_get_created_history(this->mIndex.index_next, type); /* Go to the last particle created */ struct index_data *index_data = do_previous ? prev_created : next_created; - size_t size_max = do_previous ? this->mIndex.index_prev.nparts_created[type] - : this->mIndex.index_next.nparts_created[type]; + size_t size_max = do_previous ? this->mIndex.index_prev->nparts_created[type] + : this->mIndex.index_next->nparts_created[type]; // TODO use interpolation search size_t left = 0; @@ -1252,7 +1234,7 @@ void Reader::UpdateParticlesSingleType( /* Do the same for the next index file */ if (do_previous) { index_data = next_created; - size_max = this->mIndex.index_next.nparts_created[type]; + size_max = this->mIndex.index_next->nparts_created[type]; for (size_t i = 0; i < size_max; i++) { /* Stop as soon as we reach the required offset */ if (index_data[i].offset > offset_time) break; @@ -1296,6 +1278,8 @@ void Reader::UpdateParticles( csds_error("Cannot update the particles without cache"); } + // TODO Set time + /* Prepare the cache */ csds_cache_reset_current_index(&this->mCache); diff --git a/src/csds_reader.hpp b/src/csds_reader.hpp index 314b22daa355797a471f11fa01d80d2ca4b86044..2b0ccc03df5b75c4e49e50e2439c9fc08f8c9e45 100644 --- a/src/csds_reader.hpp +++ b/src/csds_reader.hpp @@ -107,10 +107,10 @@ class Reader { struct { /* Information contained in the previous index file. */ - struct csds_index index_prev; + IndexFile *index_prev; /* Information contained in the next index file. */ - struct csds_index index_next; + IndexFile *index_next; /* Number of index files */ int n_files; @@ -123,7 +123,7 @@ class Reader { } mIndex; /* Informations contained in the file header. */ - struct csds_logfile *mLog; + LogFile *mLog; /* Information about the current time */ struct { diff --git a/src/csds_reader_generate_index.cpp b/src/csds_reader_generate_index.cpp index 08cc2bace51dbb4bd55145cdc3af54f87db02308..5914a8447ec81e0b0b34b1cd4cf5035f9cafcba6 100644 --- a/src/csds_reader_generate_index.cpp +++ b/src/csds_reader_generate_index.cpp @@ -288,7 +288,7 @@ size_t Reader::GetInitialState(struct csds_hashmap **current_state, const high_resolution_clock::time_point init = high_resolution_clock::now(); /* Get a few variables. */ - struct csds_logfile *log = this->mLog; + LogFile *log = this->mLog; const struct header *h = &log->header; const int size_record_header = CSDS_MASK_SIZE + CSDS_OFFSET_SIZE; @@ -313,48 +313,38 @@ size_t Reader::GetInitialState(struct csds_hashmap **current_state, size_t offset_first = h->offset_first_record; /* Skip the time record */ - mask_type time_mask = 0; - csds_mapped_file_read_mask(log->log, offset_first, &time_mask, NULL); - const int time_size = header_get_record_size_from_mask(h, time_mask); + struct record_header header; + log->log->ReadRecordHeader(offset_first, header); + const int time_size = header_get_record_size_from_mask(h, header.mask); offset_first += time_size + size_record_header; /* Get the initial state */ float next_percent = 0; for (size_t offset = offset_first; offset < offset_max;) { /* Get the particle type */ - mask_type mask = 0; - size_t prev_offset = 0; int part_type = 0; int data = 0; enum csds_special_flags flag = csds_particle_read_special_flag( - offset, &mask, &prev_offset, &data, &part_type, log->log); + offset, header, &data, &part_type, *log->log); if (flag != csds_flag_create) { csds_error("Reading a particle from ICs without the created flag."); } - /* TODO Implement missing particle types */ - if (part_type == csds_type_neutrino || part_type == csds_type_sink || - part_type == csds_type_black_hole) { - csds_error( - "Particle type not implemented: " << part_type_names[part_type]); - } - /* Get the mask for the IDs */ const struct field_information *field_id = header_get_field_from_name(h, "ParticleIDs", (enum part_type)part_type); /* Get the particle ID */ - if (!(mask & field_id->field.mask)) { + if (!(header.mask & field_id->field.mask)) { csds_error("The particle ID is missing in the first log"); } /* Read the particle ID */ int64_t id = 0; csds_particle_read_field(offset, &id, field_id, - /* derivative */ 0, &mask, &prev_offset, - h->fields[part_type], h->number_fields[part_type], - this->mLog->log); + /* derivative */ 0, header, h->fields[part_type], + h->number_fields[part_type], *this->mLog->log); /* Log the particle */ struct index_data item = {id, offset}; @@ -364,7 +354,7 @@ size_t Reader::GetInitialState(struct csds_hashmap **current_state, } /* Increment the offset */ - const int record_size = header_get_record_size_from_mask(h, mask); + const int record_size = header_get_record_size_from_mask(h, header.mask); offset += record_size + size_record_header; /* Print the progress */ @@ -407,49 +397,47 @@ size_t Reader::GetLastOffsetBefore(const struct index_data *data, size_t offset_limit) { /* Get a the logfile */ - struct csds_logfile *log = this->mLog; + LogFile *log = this->mLog; size_t current_offset = data->offset; /* Get the full mask */ - mask_type full_mask = 0; - size_t h_offset = 0; - csds_mapped_file_read_mask(log->log, current_offset, &full_mask, &h_offset); + struct record_header last_header; + log->log->ReadRecordHeader(current_offset, last_header); /* Ensures that a special flag is present in the mask */ - full_mask |= CSDS_SPECIAL_FLAGS_MASK; + last_header.mask |= CSDS_SPECIAL_FLAGS_MASK; /* Now remove it */ - full_mask = full_mask ^ CSDS_SPECIAL_FLAGS_MASK; + last_header.mask = last_header.mask ^ CSDS_SPECIAL_FLAGS_MASK; /* Find the last offset before the current time */ size_t last_full_offset = current_offset; - current_offset += h_offset; + current_offset += last_header.offset; while (1) { /* Get the mask */ - mask_type mask = 0; - h_offset = 0; - csds_mapped_file_read_mask(log->log, current_offset, &mask, &h_offset); + struct record_header cur_header; + log->log->ReadRecordHeader(current_offset, cur_header); /* update the offset */ - current_offset += h_offset; + current_offset += cur_header.offset; if (current_offset > offset_limit) { break; } /* The particle should not have a special flag due to the previous loop */ - if (mask & CSDS_SPECIAL_FLAGS_MASK) { + if (cur_header.mask & CSDS_SPECIAL_FLAGS_MASK) { csds_error("Found a special flag when updating the particles"); } /* Update the last full offset */ - if (full_mask == mask) { + if (last_header.mask == cur_header.mask) { last_full_offset = current_offset; } /* Are we at the end of the file? */ - if (h_offset == 0) { + if (cur_header.offset == 0) { break; } } @@ -478,7 +466,7 @@ size_t Reader::UpdateStateToNextIndex(size_t init_offset, struct csds_hashmap **current_state, struct index_writer *parts_created, struct index_writer *parts_removed) { - struct csds_logfile *log = this->mLog; + LogFile *log = this->mLog; const struct header *h = &log->header; const int size_record_header = CSDS_MASK_SIZE + CSDS_OFFSET_SIZE; @@ -509,27 +497,27 @@ size_t Reader::UpdateStateToNextIndex(size_t init_offset, "Looking for new or removed particles"); } } - mask_type mask = 0; - size_t h_offset = 0; int part_type = -1; // only available if the record is flagged. int data = 0; /* Get the mask */ - csds_mapped_file_read_mask(log->log, offset, &mask, &h_offset); + struct record_header header; + log->log->ReadRecordHeader(offset, header); /* Go to the next record */ const size_t old_offset = offset; - offset += header_get_record_size_from_mask(h, mask); + offset += header_get_record_size_from_mask(h, header.mask); offset += size_record_header; /* Check if we have a particle with a flag */ - if (mask & CSDS_TIMESTAMP_MASK || !(mask & CSDS_SPECIAL_FLAGS_MASK)) { + if (header.mask & CSDS_TIMESTAMP_MASK || + !(header.mask & CSDS_SPECIAL_FLAGS_MASK)) { continue; } /* Get the special flag */ enum csds_special_flags flag = csds_particle_read_special_flag( - old_offset, &mask, &h_offset, &data, &part_type, log->log); + old_offset, header, &data, &part_type, *log->log); #ifdef CSDS_DEBUG_CHECKS if (flag == csds_flag_none) { @@ -550,9 +538,8 @@ size_t Reader::UpdateStateToNextIndex(size_t init_offset, /* Read the ID */ int64_t id = 0; csds_particle_read_field(old_offset, &id, field_id, - /* derivative */ 0, &mask, &h_offset, - h->fields[part_type], h->number_fields[part_type], - this->mLog->log); + /* derivative */ 0, header, h->fields[part_type], + h->number_fields[part_type], *this->mLog->log); /* Add the particle to the arrays */ if (flag == csds_flag_change_type || flag == csds_flag_mpi_exit || @@ -658,7 +645,7 @@ size_t Reader::UpdateStateToNextIndex(size_t init_offset, */ void Reader::GenerateIndexFiles(int number_index, int current_index) { /* Get a few pointers */ - struct csds_logfile *log = this->mLog; + LogFile *log = this->mLog; const struct header *h = &log->header; /* Write a quick message */ @@ -722,16 +709,11 @@ void Reader::GenerateIndexFiles(int number_index, int current_index) { } /* We are restarting => read state from file */ else { - - /* Initialize the index file */ - struct csds_index index; - csds_index_init(&index); - - /* Get its name */ + /* Get the index file name */ string filename = this->GetIndexName(current_index - 1); - /* Read it */ - csds_index_read_header(&index, filename, this->mVerbose); + /* Initialize the index file */ + IndexFile index(filename, this->mVerbose); csds_index_map_file(&index, filename, /* sorted */ 1, this->mVerbose); /* Loop over all the particle types */ @@ -771,9 +753,6 @@ void Reader::GenerateIndexFiles(int number_index, int current_index) { "The time in the index file and the expected one do not match"); } } - - /* Cleanup */ - csds_index_free(&index); } /* Compute the state of all the other files and write them. */ diff --git a/src/csds_time.cpp b/src/csds_time.cpp index 71f0521cb3e78ac0ed178a4485874f9d616cb37e..c269e17b241472e35f2382acca0c99c09dd50718 100644 --- a/src/csds_time.cpp +++ b/src/csds_time.cpp @@ -92,27 +92,25 @@ void time_array_append(struct time_array *t, const integertime_t int_time, * @return The offset after the time record */ size_t time_read(struct time_record *time_record, size_t offset, - struct csds_logfile *logfile) { + LogFile *logfile) { /* Initialize variables. */ - struct mapped_file &log = logfile->log; + MappedFile &log = *logfile->log; - mask_type mask = 0; - size_t prev_offset = 0; time_record->int_time = 0; time_record->time = 0; /* read record header. */ - offset = csds_mapped_file_read_mask(log, offset, &mask, &prev_offset); + struct record_header header; + offset = log.ReadRecordHeader(offset, header); /* check if reading a time record. */ - if (CSDS_TIMESTAMP_MASK != mask) csds_error("Not a time record."); + if (CSDS_TIMESTAMP_MASK != header.mask) csds_error("Not a time record."); /* read the record. */ - offset = csds_mapped_file_read_data( - log, offset, sizeof(unsigned long long int), &time_record->int_time); - offset = csds_mapped_file_read_data(log, offset, sizeof(double), - &time_record->time); + offset = log.ReadData(offset, sizeof(unsigned long long int), + &time_record->int_time); + offset = log.ReadData(offset, sizeof(double), &time_record->time); return offset; } @@ -128,12 +126,12 @@ size_t time_offset_first_record(const struct header *h) { /* Initialize a few variables. */ size_t offset = h->offset_first_record; - struct mapped_file &map = h->log->log; + MappedFile &map = *h->log->log; - mask_type mask = 0; - csds_mapped_file_read_mask(map, offset, &mask, NULL); + struct record_header header; + map.ReadRecordHeader(offset, header); - if (mask != CSDS_TIMESTAMP_MASK) + if (header.mask != CSDS_TIMESTAMP_MASK) csds_error("Log file should begin by timestep."); return h->offset_first_record; @@ -209,7 +207,7 @@ void time_array_save(struct time_array *t, string basename) { * @param t The #time_array. * @param index The #csds_index that contains the time array. */ -void time_array_load(struct time_array *t, struct csds_index *index) { +void time_array_load(struct time_array *t, IndexFile *index) { /* Ensure that the array is empty */ if (t->capacity != 0) time_array_free(t); @@ -247,9 +245,7 @@ int time_array_restore(struct time_array *t, const string basename, if (!savefile) return 0; /* Initialize the index file that might contain the time array */ - struct csds_index index; - csds_index_init(&index); - csds_index_read_header(&index, filename, verbose); + IndexFile index(filename, verbose); csds_index_map_file(&index, filename, /* sorted */ 1, verbose); /* Check if the index file contains the time array */ @@ -257,13 +253,9 @@ int time_array_restore(struct time_array *t, const string basename, /* Load the time array */ time_array_load(t, &index); - csds_index_free(&index); return 1; } - /* Free the memory. */ - csds_index_free(&index); - return 0; } @@ -275,7 +267,7 @@ int time_array_restore(struct time_array *t, const string basename, * @param basename The basename of the files * @param verbose The verbose level */ -void time_array_populate(struct time_array *t, struct csds_logfile *log, +void time_array_populate(struct time_array *t, LogFile *log, const string basename, int verbose) { /* Try restoring the time array */ @@ -287,7 +279,7 @@ void time_array_populate(struct time_array *t, struct csds_logfile *log, } /* get file size. */ - size_t file_size = log->log.mmap_size; + size_t file_size = log->log->mMapSize; /* get first timestamp. */ size_t offset = time_offset_first_record(&log->header); @@ -299,8 +291,8 @@ void time_array_populate(struct time_array *t, struct csds_logfile *log, time_array_append(t, time.int_time, time.time, offset); /* get next record. */ - int test = tools_get_next_record(&log->header, log->log, &offset, - log->log.mmap_size); + int test = tools_get_next_record(&log->header, *log->log, &offset, + log->log->mMapSize); if (test == -1) break; } } diff --git a/src/csds_time.hpp b/src/csds_time.hpp index 8a0fc2dcaaf6d507f0dbb7c11b68ca2dbbc1e117..4a7cf3425a919d2ea6ce74ad0b9bb38c8a073eaa 100644 --- a/src/csds_time.hpp +++ b/src/csds_time.hpp @@ -26,7 +26,6 @@ #include "csds_header.hpp" #include "csds_tools.hpp" -typedef int8_t timebin_t; typedef long long integertime_t; class Reader; @@ -75,11 +74,10 @@ struct time_array { void time_array_append(struct time_array *t, const integertime_t int_time, const double time, const size_t offset); -size_t time_read(struct time_record *time, size_t offset, - struct csds_logfile *logfile); +size_t time_read(struct time_record *time, size_t offset, LogFile *logfile); void time_array_init(struct time_array *t, size_t initial_size); -void time_array_populate(struct time_array *t, struct csds_logfile *log, +void time_array_populate(struct time_array *t, LogFile *log, const std::string basename, int verbose); integertime_t time_array_get_integertime(struct time_array *t, diff --git a/src/csds_tools.cpp b/src/csds_tools.cpp index a7c1de69330a0f1cf4ff2c87aab0b838d7b84692..6fd6932ad5ef629f7a42b5a00a57691ef24a7576 100644 --- a/src/csds_tools.cpp +++ b/src/csds_tools.cpp @@ -39,7 +39,7 @@ * * @return -1 if no next record, otherwise 0 */ -int tools_get_next_record(const struct header *h, struct mapped_file &map, +int tools_get_next_record(const struct header *h, MappedFile &map, size_t *offset, size_t file_size) { if (header_is_forward(h)) return _tools_get_next_record_forward(map, offset); if (header_is_backward(h)) @@ -57,16 +57,16 @@ int tools_get_next_record(const struct header *h, struct mapped_file &map, * * @return error code, -1 if no next record */ -int _tools_get_next_record_forward(struct mapped_file &map, size_t *offset) { - size_t diff_offset = 0; +int _tools_get_next_record_forward(MappedFile &map, size_t *offset) { /* Read the offset. */ - csds_mapped_file_read_mask(map, *offset, NULL, &diff_offset); + struct record_header header; + map.ReadRecordHeader(*offset, header); - if (diff_offset == 0) return -1; + if (header.offset == 0) return -1; /* Set the absolute offset. */ - *offset += diff_offset; + *offset += header.offset; return 0; } @@ -81,9 +81,8 @@ int _tools_get_next_record_forward(struct mapped_file &map, size_t *offset) { * * @return error code, -1 if no next record */ -int _tools_get_next_record_backward(const struct header *h, - struct mapped_file &map, size_t *offset, - size_t file_size) { +int _tools_get_next_record_backward(const struct header *h, MappedFile &map, + size_t *offset, size_t file_size) { #ifndef CSDS_DEBUG_CHECKS csds_error("Should not be used, method too slow"); #endif @@ -91,17 +90,16 @@ int _tools_get_next_record_backward(const struct header *h, size_t record_header = CSDS_MASK_SIZE + CSDS_OFFSET_SIZE; while (current_offset < file_size) { - mask_type mask = 0; - size_t prev_offset; - csds_mapped_file_read_mask(map, current_offset, &mask, &prev_offset); + struct record_header header; + map.ReadRecordHeader(current_offset, header); - prev_offset = current_offset - prev_offset - record_header; - if (*offset == prev_offset) { + header.offset = current_offset - header.offset - record_header; + if (*offset == header.offset) { *offset = current_offset - record_header; return 0; } - current_offset += header_get_record_size_from_mask(h, mask); + current_offset += header_get_record_size_from_mask(h, header.mask); } return -1; @@ -117,44 +115,45 @@ int _tools_get_next_record_backward(const struct header *h, * * @return position after the record. */ -size_t tools_reverse_offset(const struct header *h, struct mapped_file &map, +size_t tools_reverse_offset(const struct header *h, MappedFile &map, size_t offset) { - mask_type mask = 0; - size_t prev_offset = 0; const size_t cur_offset = offset; /* read mask + offset. */ - offset = csds_mapped_file_read_mask(map, offset, &mask, &prev_offset); + struct record_header header; + offset = map.ReadRecordHeader(offset, header); /* write offset of zero (in case it is the last record). */ const size_t zero = 0; offset -= CSDS_OFFSET_SIZE; - offset = csds_mapped_file_write_data(map, offset, CSDS_OFFSET_SIZE, &zero); + offset = map.WriteData(offset, CSDS_OFFSET_SIZE, &zero); /* set offset after current record. */ - offset += header_get_record_size_from_mask(h, mask); + offset += header_get_record_size_from_mask(h, header.mask); const size_t after_current_record = offset; /* first records do not have a previous partner. */ - if (prev_offset == cur_offset) return after_current_record; - if (prev_offset > cur_offset) - csds_error("Unexpected offset: header " << prev_offset << ", current " + if (header.offset == cur_offset) return after_current_record; + if (header.offset > cur_offset) + csds_error("Unexpected offset: header " << header.offset << ", current " << cur_offset); /* modify previous offset. */ - offset = cur_offset - prev_offset + CSDS_MASK_SIZE; - offset = - csds_mapped_file_write_data(map, offset, CSDS_OFFSET_SIZE, &prev_offset); + offset = cur_offset - header.offset + CSDS_MASK_SIZE; + offset = map.WriteData(offset, CSDS_OFFSET_SIZE, &header.offset); #ifdef CSDS_DEBUG_CHECKS - mask_type prev_mask = 0; + struct record_header prev_header; offset -= CSDS_MASK_SIZE + CSDS_OFFSET_SIZE; - csds_mapped_file_read_mask(map, offset, &prev_mask, NULL); + map.ReadRecordHeader(offset, prev_header); /* Check if we are not mixing timestamp and particles */ - if ((prev_mask != CSDS_TIMESTAMP_MASK && mask == CSDS_TIMESTAMP_MASK) || - (prev_mask == CSDS_TIMESTAMP_MASK && mask != CSDS_TIMESTAMP_MASK)) - csds_error("Unexpected mask: " << mask << " got " << prev_mask); + if ((prev_header.mask != CSDS_TIMESTAMP_MASK && + header.mask == CSDS_TIMESTAMP_MASK) || + (prev_header.mask == CSDS_TIMESTAMP_MASK && + header.mask != CSDS_TIMESTAMP_MASK)) + csds_error("Unexpected mask: " << header.mask << " got " + << prev_header.mask); #endif // CSDS_DEBUG_CHECKS @@ -172,51 +171,51 @@ size_t tools_reverse_offset(const struct header *h, struct mapped_file &map, * * @return position after the record. */ -size_t tools_check_record_consistency(struct csds_logfile *log, size_t offset) { +size_t tools_check_record_consistency(LogFile *log, size_t offset) { #ifndef CSDS_DEBUG_CHECKS csds_error("Should not check in non debug mode."); #endif const struct header *h = &log->header; - struct mapped_file &map = log->log; + MappedFile &map = *log->log; const size_t init_offset = offset; - mask_type mask; - size_t pointed_offset; - /* read mask + offset. */ - offset = csds_mapped_file_read_mask(map, offset, &mask, &pointed_offset); + struct record_header header; + offset = map.ReadRecordHeader(offset, header); /* set offset after current record. */ - offset += header_get_record_size_from_mask(h, mask); + offset += header_get_record_size_from_mask(h, header.mask); const size_t offset_ret = offset; /* If something happened, skip the check. */ - if (mask & CSDS_SPECIAL_FLAGS_MASK) { + if (header.mask & CSDS_SPECIAL_FLAGS_MASK) { return offset_ret; } /* get absolute offset. */ if (header_is_forward(h)) - pointed_offset += init_offset; + header.offset += init_offset; else if (header_is_backward(h)) { - if (init_offset < pointed_offset) - csds_error("Offset too large for mask: " << mask); - pointed_offset = init_offset - pointed_offset; + if (init_offset < header.offset) + csds_error("Offset too large for mask: " << header.mask); + header.offset = init_offset - header.offset; } else { csds_error("Offset are corrupted."); } - if (pointed_offset == init_offset || pointed_offset == 0) return offset_ret; + if (header.offset == init_offset || header.offset == 0) return offset_ret; /* read mask of the pointed record. */ - mask_type pointed_mask = 0; - csds_mapped_file_read_mask(map, pointed_offset, &pointed_mask, NULL); + struct record_header pointed_header; + map.ReadRecordHeader(header.offset, pointed_header); /* check if not mixing timestamp and particles. */ - if ((pointed_mask != CSDS_TIMESTAMP_MASK && mask == CSDS_TIMESTAMP_MASK) || - (pointed_mask == CSDS_TIMESTAMP_MASK && mask != CSDS_TIMESTAMP_MASK)) - csds_error("Error in the offset for mask: " << mask); + if ((pointed_header.mask != CSDS_TIMESTAMP_MASK && + header.mask == CSDS_TIMESTAMP_MASK) || + (pointed_header.mask == CSDS_TIMESTAMP_MASK && + header.mask != CSDS_TIMESTAMP_MASK)) + csds_error("Error in the offset for mask: " << header.mask); return offset_ret; } diff --git a/src/csds_tools.hpp b/src/csds_tools.hpp index 1b946fc33a2c15c10ddcb6f7089ab7b4649e9d5d..9e97a8abb76035b5c23c16cb8dc8dfebd6041df7 100644 --- a/src/csds_tools.hpp +++ b/src/csds_tools.hpp @@ -30,13 +30,12 @@ #include "csds_inline.hpp" #include "csds_logfile_writer.h" +class MappedFile; +class LogFile; + /* Define the size of all the fields. */ #define member_size(type, member) sizeof(((type *)0)->member) -struct header; -class Reader; -struct mapped_file; - /** * @brief Structure dealing with reading / interpolating a field. */ @@ -51,15 +50,14 @@ struct csds_reader_field { void *second_deriv; }; -int tools_get_next_record(const struct header *h, struct mapped_file &map, +int tools_get_next_record(const struct header *h, MappedFile &map, size_t *offset, size_t file_size); -int _tools_get_next_record_backward(const struct header *h, - struct mapped_file &map, size_t *offset, - size_t file_size); -int _tools_get_next_record_forward(struct mapped_file &map, size_t *offset); -size_t tools_reverse_offset(const struct header *h, struct mapped_file &map, +int _tools_get_next_record_backward(const struct header *h, MappedFile &map, + size_t *offset, size_t file_size); +int _tools_get_next_record_forward(MappedFile &map, size_t *offset); +size_t tools_reverse_offset(const struct header *h, MappedFile &map, size_t offset); -size_t tools_check_record_consistency(struct csds_logfile *log, size_t offset); +size_t tools_check_record_consistency(LogFile *log, size_t offset); void tools_print_progress( float percentage, const std::chrono::high_resolution_clock::time_point init, diff --git a/tests/testLogfileHeader.cpp b/tests/testLogfileHeader.cpp index b620f40149f8f3be9333117e1dd4d0218baf3835..74a0483cbf69484a1ce7feef3c77218683523da3 100644 --- a/tests/testLogfileHeader.cpp +++ b/tests/testLogfileHeader.cpp @@ -48,12 +48,9 @@ int main(void) { message("Reading the header."); /* Generate required structure for reading. */ - struct csds_logfile logfile; - - /* Read the header */ - csds_logfile_init_from_file(&logfile, basename, - /* only_header */ 1, - /* verbose */ 2); + LogFile logfile(basename, + /* only_header */ 1, + /* verbose */ 2); /* Finally check everything. */ @@ -77,8 +74,5 @@ int main(void) { message("Checking offset direction"); assert(h->offset_direction == csds_offset_backward); - /* Cleanup */ - csds_logfile_free(&logfile); - return 0; } diff --git a/tests/testLogfileReader.cpp b/tests/testLogfileReader.cpp index 21d27fee16d5a7c59a36e3f11f12da3f041eeb2a..bdc4a48f2df76043253a0fcb1c5a58b81a5baa02 100644 --- a/tests/testLogfileReader.cpp +++ b/tests/testLogfileReader.cpp @@ -49,7 +49,7 @@ void check_data(Reader &reader, struct csds_part *parts) { /* No need to check the header, this is already done in testHeader.c */ /* Get required structures. */ - struct csds_logfile *logfile = reader.mLog; + LogFile &logfile = *reader.mLog; struct header *h = &reader.mLog->header; /* Create a particle */ @@ -79,8 +79,8 @@ void check_data(Reader &reader, struct csds_part *parts) { /* Loop over each record. */ for (size_t offset = reader.ReadRecord(output, &time, &is_particle, - logfile->header.offset_first_record); - offset < logfile->log.mmap_size; + logfile.header.offset_first_record); + offset < logfile.log->mMapSize; offset = reader.ReadRecord(output, &time, &is_particle, offset)) { /* Do the particle case */ diff --git a/tests/testVirtualReality.cpp b/tests/testVirtualReality.cpp index 706b959dd883c78b829af4cd47c2918769d0c866..8cfab5a1441bba3e62a72d28b9f0c3294b27495e 100644 --- a/tests/testVirtualReality.cpp +++ b/tests/testVirtualReality.cpp @@ -100,9 +100,6 @@ int main(void) { output.emplace_back(n_tot, field_enum_coordinates); output.emplace_back(n_tot, field_enum_particles_ids); - /* Set the time of the next reading */ - reader.SetTime(begin); - /* Read the next time */ reader.ReadAllParticles(begin, required_fields, output, n_parts);