diff --git a/src/index_file.cpp b/src/index_file.cpp index 61f071398db03a210f7361d54411cbc2d27a94b1..47d9957624896b799951aafc0b223ffd664e8691 100644 --- a/src/index_file.cpp +++ b/src/index_file.cpp @@ -28,27 +28,6 @@ /* Include local headers */ #include "mapped_file.hpp" -/* Define the place and size of each element in the header. */ -/* The time in double precision. */ -#define csds_index_time_offset 0 -#define csds_index_time_size sizeof(double) -/* The time on the integer timeline. */ -#define csds_index_integer_time_offset \ - csds_index_time_offset + csds_index_time_size -#define csds_index_integer_time_size sizeof(integertime_t) -/* The number of particle (for each type). */ -#define csds_index_npart_offset \ - csds_index_integer_time_offset + csds_index_integer_time_size -#define csds_index_npart_size sizeof(uint64_t) * csds_type_count -/* The flag used for checking if the file is sorted or not. */ -#define csds_index_is_sorted_offset \ - csds_index_npart_offset + csds_index_npart_size -#define csds_index_is_sorted_size sizeof(char) -/* The array containing the offset and ids. Rounding to a multiplier of 8 in - * order to align the memory */ -#define csds_index_data_offset \ - ((csds_index_is_sorted_offset + csds_index_is_sorted_size + 7) & ~7) - /** * @brief Read the index file header. * @@ -121,75 +100,6 @@ void IndexFile::WriteSorted() { mIsSorted = true; } -/** - * @brief Get the #index_data of a particle type. - * - * This function should be used when looking for the last known particles. - * - * @param type The particle type. - */ -struct index_data *IndexFile::GetData(enum part_type type) const { - /* Get the offset of particles of this type by skipping entries of lower - * types. */ - size_t count = 0; - for (int i = 0; i < type; i++) { - count += mNParts[i]; - } - const size_t type_offset = count * sizeof(struct index_data); - - const char *ret = pmIndex->GetMap() + csds_index_data_offset + type_offset; - return (struct index_data *)ret; -} - -/** - * @brief Get the #index_data for the particles created. - * - * This function should be used when looking for the particles created. - * - * @param type The particle type. - */ -struct index_data *IndexFile::GetCreatedHistory(enum part_type type) const { - - /* Get the position after the previous array. */ - char *ret = (char *)GetData(csds_type_count); - - /* Get the offset of particles of this type by skipping entries of lower - * types. */ - size_t count = 0; - for (int i = 0; i < type; i++) { - count += mNPartsCreated[i]; - } - const size_t type_offset = count * sizeof(struct index_data); - - ret += type_offset + csds_index_npart_size; - return (struct index_data *)ret; -} - -/** - * @brief Get the #index_data for the particles removed. - * - * The #index_data contains the ids and offset of the particle. - * This function should be used when looking for the particles removed. - * - * @param type The particle type. - */ -struct index_data *IndexFile::GetRemovedHistory(enum part_type type) const { - - /* Get the position after the previous array. */ - char *ret = (char *)GetCreatedHistory(csds_type_count); - - /* Get the offset of particles of this type by skipping entries of lower - * types. */ - size_t count = 0; - for (int i = 0; i < type; i++) { - count += mNPartsRemoved[i]; - } - const size_t type_offset = count * sizeof(struct index_data); - - ret += type_offset + csds_index_npart_size; - return (struct index_data *)ret; -} - /** * @brief Check if a time array is written at the end. */ @@ -267,54 +177,3 @@ IndexFile::~IndexFile() { pmIndex = NULL; } } - -/** - * @brief Give the offset of a particle given its id. - * - * @param id The ID of the particle. - * @param type The type of particles. - * @param offset (output) The offset of the particle. - * - * @return Did we find the particle? - */ -bool IndexFile::GetOffset(int64_t id, enum part_type type, - uint64_t &offset) const { - -#ifdef CSDS_DEBUG_CHECKS - /* Ensure that the file is sorted according to the ids. */ - if (!mIsSorted) { - csds_error("The index file should be already sorted."); - } - /* Ensure that we have some particles */ - if (mNParts[type] == 0) { - csds_error("Trying to find a particle in an empty index."); - } -#endif - - /* Get the data structure. */ - struct index_data *data = GetData(type); - - /* Search for the value (binary search) */ - struct index_data value = {.id = id, .offset = 0}; - struct index_data *it = - std::lower_bound(data, data + mNParts[type], value, CompareIndexDataId); - - /* Check if we found the particle */ - if (it->id == id) { - offset = it->offset; - return true; - } - - /* Try to find it in the history */ - // TODO Improve this with a sort? - data = GetCreatedHistory(type); - for (uint64_t i = 0; i < mNPartsCreated[type]; i++) { - if (data[i].id == id) { - offset = data[i].offset; - return true; - } - } - - /* The particle was not found */ - return false; -} diff --git a/src/index_file.hpp b/src/index_file.hpp index 0e7d966fb36edf127a3fb06507249ca92bdf1d8e..4447ddf8012be93eb253ba0f4b8545c56e2c3984 100644 --- a/src/index_file.hpp +++ b/src/index_file.hpp @@ -23,6 +23,28 @@ #include "mapped_file.hpp" #include "tools.hpp" +/* Define the place and size of each element in the header. */ +// TODO could cleanup a bit this +/* The time in double precision. */ +#define csds_index_time_offset 0 +#define csds_index_time_size sizeof(double) +/* The time on the integer timeline. */ +#define csds_index_integer_time_offset \ + csds_index_time_offset + csds_index_time_size +#define csds_index_integer_time_size sizeof(integertime_t) +/* The number of particle (for each type). */ +#define csds_index_npart_offset \ + csds_index_integer_time_offset + csds_index_integer_time_size +#define csds_index_npart_size sizeof(uint64_t) * csds_type_count +/* The flag used for checking if the file is sorted or not. */ +#define csds_index_is_sorted_offset \ + csds_index_npart_offset + csds_index_npart_size +#define csds_index_is_sorted_size sizeof(char) +/* The array containing the offset and ids. Rounding to a multiplier of 8 in + * order to align the memory */ +#define csds_index_data_offset \ + ((csds_index_is_sorted_offset + csds_index_is_sorted_size + 7) & ~7) + /** * @brief Class dealing with the index files. * @@ -42,12 +64,127 @@ class IndexFile { bool ContainsTimeArray(); void MapFile(const std::string filename, int sorted, int verbose); - bool GetOffset(int64_t id, enum part_type type, uint64_t &offset) const; + /** + * @brief Give the offset of a particle given its id. + * + * @param id The ID of the particle. + * @param type The type of particles. + * @param offset (output) The offset of the particle. + * + * @return Did we find the particle? + */ + INLINE bool GetOffset(int64_t id, enum part_type type, + uint64_t &offset) const { + +#ifdef CSDS_DEBUG_CHECKS + /* Ensure that the file is sorted according to the ids. */ + if (!mIsSorted) { + csds_error("The index file should be already sorted."); + } + /* Ensure that we have some particles */ + if (mNParts[type] == 0) { + csds_error("Trying to find a particle in an empty index."); + } +#endif + + /* Get the data structure. */ + struct index_data *data = GetData(type); + + /* Search for the value (binary search) */ + struct index_data value = {.id = id, .offset = 0}; + struct index_data *it = + std::lower_bound(data, data + mNParts[type], value, CompareIndexDataId); + + /* Check if we found the particle */ + if (it->id == id) { + offset = it->offset; + return true; + } + + /* Try to find it in the history */ + // TODO Improve this with a sort? + data = GetCreatedHistory(type); + for (uint64_t i = 0; i < mNPartsCreated[type]; i++) { + if (data[i].id == id) { + offset = data[i].offset; + return true; + } + } + + /* The particle was not found */ + return false; + } + + /** + * @brief Get the #index_data of a particle type. + * + * This function should be used when looking for the last known particles. + * + * @param type The particle type. + */ // TODO convert the 3 functions into particle accessor (e.g. return const&) - struct index_data *GetData(enum part_type type) const; - struct index_data *GetCreatedHistory(enum part_type type) const; - struct index_data *GetRemovedHistory(enum part_type type) const; + INLINE struct index_data *GetData(enum part_type type) const { + /* Get the offset of particles of this type by skipping entries of lower + * types. */ + size_t count = 0; + for (int i = 0; i < type; i++) { + count += mNParts[i]; + } + const size_t type_offset = count * sizeof(struct index_data); + + const char *ret = pmIndex->GetMap() + csds_index_data_offset + type_offset; + return (struct index_data *)ret; + } + + /** + * @brief Get the #index_data for the particles created. + * + * This function should be used when looking for the particles created. + * + * @param type The particle type. + */ + INLINE struct index_data *GetCreatedHistory(enum part_type type) const { + + /* Get the position after the previous array. */ + char *ret = (char *)GetData(csds_type_count); + + /* Get the offset of particles of this type by skipping entries of lower + * types. */ + size_t count = 0; + for (int i = 0; i < type; i++) { + count += mNPartsCreated[i]; + } + const size_t type_offset = count * sizeof(struct index_data); + + ret += type_offset + csds_index_npart_size; + return (struct index_data *)ret; + } + + /** + * @brief Get the #index_data for the particles removed. + * + * The #index_data contains the ids and offset of the particle. + * This function should be used when looking for the particles removed. + * + * @param type The particle type. + */ + INLINE struct index_data *GetRemovedHistory(enum part_type type) const { + + /* Get the position after the previous array. */ + char *ret = (char *)GetCreatedHistory(csds_type_count); + + /* Get the offset of particles of this type by skipping entries of lower + * types. */ + size_t count = 0; + for (int i = 0; i < type; i++) { + count += mNPartsRemoved[i]; + } + const size_t type_offset = count * sizeof(struct index_data); + + ret += type_offset + csds_index_npart_size; + return (struct index_data *)ret; + } double GetTime() const { return mTime; } integertime_t GetIntegerTime() const { return mIntegerTime; }