From aa17d584b3dc6e22c96fb07ed5eaf387b417c3b8 Mon Sep 17 00:00:00 2001 From: H1ghBre4k3r Date: Sun, 25 Apr 2021 21:59:12 +0200 Subject: [PATCH] Implement ens_records_iterator_init_timerange via binary search --- src/covid.h | 2 ++ src/covid_types.h | 1 + src/ens/ens_fs.h | 15 ++++----- src/ens/records.c | 82 ++++++++++++++++++++++++++++++++++++++++++++--- src/ens/storage.h | 1 + src/io.h | 6 +++- 6 files changed, 93 insertions(+), 14 deletions(-) diff --git a/src/covid.h b/src/covid.h index 4b169e7..69ae240 100644 --- a/src/covid.h +++ b/src/covid.h @@ -7,6 +7,8 @@ #ifndef COVID_H #define COVID_H +#include + #include "exposure-notification.h" typedef struct period{ diff --git a/src/covid_types.h b/src/covid_types.h index 43e28ce..c2f5ebb 100644 --- a/src/covid_types.h +++ b/src/covid_types.h @@ -7,6 +7,7 @@ #ifndef COVID_TYPES_H #define COVID_TYPES_H +#include #include #define COVID_ROLLING_PROXIMITY_IDENTIFIER_LEN 16 diff --git a/src/ens/ens_fs.h b/src/ens/ens_fs.h index 567f580..9bfb10a 100644 --- a/src/ens/ens_fs.h +++ b/src/ens/ens_fs.h @@ -2,21 +2,20 @@ #define ENS_FS_H #include +#include #include +#include #include -#include "fs/fs.h" -#include "stdint.h" - typedef struct ens_fs { /** * Flash area for this file system. */ const struct flash_area* area; /** - * Size of each individual entry. The last byte will be used by - * ens_fs to store metadata about each individual entry. - * + * Size of each individual entry. The last byte will be used by + * ens_fs to store metadata about each individual entry. + * * @attention has to be multiple of drivers write size */ size_t entry_size; @@ -36,7 +35,7 @@ typedef struct ens_fs { /** * Initialize the file system. - * + * * @param fs file system * @param id id of the partition * @param size of each entry in the file-system. Has to power of 2 @@ -83,7 +82,7 @@ int ens_fs_delete(ens_fs_t* fs, uint64_t id); * @param fs file system * @param offset offset to start erasing * @param sector_count count of sectors to erase - * + * * @return 0 on success, -errno otherwise */ int ens_fs_page_erase(ens_fs_t* fs, uint64_t offset, uint64_t sector_count); diff --git a/src/ens/records.c b/src/ens/records.c index 20b6eb9..a6a79c8 100644 --- a/src/ens/records.c +++ b/src/ens/records.c @@ -1,8 +1,9 @@ #include +#include "../covid_types.h" #include "records.h" -#include "covid_types.h" - +#include "sequencenumber.h" +#include "storage.h" int ens_records_iterator_init_range(record_iterator_t* iterator, record_sequence_number_t* opt_start, @@ -15,6 +16,75 @@ int ens_records_iterator_init_range(record_iterator_t* iterator, return 0; } +/** + * Find an entry via binary search for the timestamp. + * + * @param record pointer to the location, where the loaded record shall be stored + * @param target timestamp for which to find the nearest entry for + * @param start lower bound for the binary search + * @param end upper bound for the binary search + */ +int find_record_via_binary_search(record_t* record, + uint32_t target, + record_sequence_number_t start, + record_sequence_number_t end) { + record_t start_record; + record_t end_record; + + // load the initial start and end record + int rc = load_contact(&start_record, start); + if (rc) { + return rc; + } + rc = load_contact(&end_record, end); + if (rc) { + return rc; + } + + do { + // calculate the contact in the middle between start and end and load it + record_sequence_number_t middle = (start_record.sn + end_record.sn) / 2; + int rc = load_contact(record, middle); + if (rc) { + return rc; + } + + // determine the new start and end + if (record->timestamp > target) { + memcpy(&start_record, record, sizeof(record_t)); + } else { + memcpy(&end_record, record, sizeof(record_t)); + } + + // break, if we are at the exact timestamp or our start and end are next to each other + } while (record->timestamp != target && (end_record.sn - start_record.sn) > 1); + + return 0; +} + +int ens_records_iterator_init_timerange(record_iterator_t* iterator, uint32_t* ts_start, uint32_t* ts_end) { + record_sequence_number_t oldest_sn = get_oldest_sequence_number(); + record_sequence_number_t latest_sn = get_latest_sequence_number(); + + record_t start_rec; + int rc = load_contact(&start_rec, oldest_sn); + if(rc) { + return rc; + } + + record_t end_rec; + rc = load_contact(&end_rec, latest_sn); + if(rc) { + return rc; + } + + iterator->finished = false; + iterator->sn_next = start_rec.sn; + iterator->sn_end = end_rec.sn; + + return 0; +} + record_t* ens_records_iterator_next(record_iterator_t* iter) { if (iter->finished) { return NULL; @@ -30,8 +100,10 @@ record_t* ens_records_iterator_next(record_iterator_t* iter) { if (!res) { next = &iter->current; - memcpy(&next->associated_encrypted_metadata, &contact.associated_encrypted_metadata, sizeof(associated_encrypted_metadata_t)); - memcpy(&next->rolling_proximity_identifier, &contact.rolling_proximity_identifier, sizeof(rolling_proximity_identifier_t)); + memcpy(&next->associated_encrypted_metadata, &contact.associated_encrypted_metadata, + sizeof(associated_encrypted_metadata_t)); + memcpy(&next->rolling_proximity_identifier, &contact.rolling_proximity_identifier, + sizeof(rolling_proximity_identifier_t)); memcpy(&next->rssi, &contact.rssi, sizeof(rssi_t)); memcpy(&next->sn, &iter->sn_next, sizeof(record_sequence_number_t)); @@ -51,7 +123,7 @@ record_t* ens_records_iterator_next(record_iterator_t* iter) { int ens_record_iterator_clear(record_iterator_t* iter) { // TODO: memclear iter->current ? - // + // iter->finished = true; return 0; } diff --git a/src/ens/storage.h b/src/ens/storage.h index 73b2584..8d7a37e 100644 --- a/src/ens/storage.h +++ b/src/ens/storage.h @@ -3,6 +3,7 @@ #include "../contacts.h" // Requires contact_t in contacts.h! #include "sequencenumber.h" +#include "../covid_types.h" typedef uint16_t storage_id_t; diff --git a/src/io.h b/src/io.h index b4a7c3b..f2499a8 100644 --- a/src/io.h +++ b/src/io.h @@ -6,5 +6,9 @@ * SPDX-License-Identifier: Apache-2.0 */ +#ifndef IO_H +#define IO_H -int init_io(); \ No newline at end of file +int init_io(); + +#endif \ No newline at end of file