mirror of
https://github.com/subsurface/subsurface.git
synced 2025-02-19 22:16:15 +00:00
core: turn C dive-table into an owning table
This is a humongous commit, because it touches all parts of the code. It removes the last user of our horrible TABLE macros, which simulate std::vector<> in a very clumsy way. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This commit is contained in:
parent
f00c30ad4a
commit
b95ac3f79c
73 changed files with 1030 additions and 1230 deletions
|
@ -190,9 +190,9 @@ static std::unique_ptr<dive> uemis_start_dive(uint32_t deviceid)
|
|||
|
||||
static struct dive *get_dive_by_uemis_diveid(device_data_t *devdata, uint32_t object_id)
|
||||
{
|
||||
for (int i = 0; i < devdata->log->dives->nr; i++) {
|
||||
if (object_id == devdata->log->dives->dives[i]->dcs[0].diveid)
|
||||
return devdata->log->dives->dives[i];
|
||||
for (auto &d: devdata->log->dives) {
|
||||
if (object_id == d->dcs[0].diveid)
|
||||
return d.get();
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
@ -767,27 +767,13 @@ static void parse_tag(struct dive *dive, std::string_view tag, std::string_view
|
|||
|
||||
static bool uemis_delete_dive(device_data_t *devdata, uint32_t diveid)
|
||||
{
|
||||
struct dive *dive = NULL;
|
||||
auto it = std::find_if(devdata->log->dives.begin(), devdata->log->dives.end(),
|
||||
[diveid] (auto &d) { return d->dcs[0].diveid == diveid; });
|
||||
if (it == devdata->log->dives.end())
|
||||
return false;
|
||||
|
||||
if (devdata->log->dives->dives[devdata->log->dives->nr - 1]->dcs[0].diveid == diveid) {
|
||||
/* we hit the last one in the array */
|
||||
dive = devdata->log->dives->dives[devdata->log->dives->nr - 1];
|
||||
} else {
|
||||
for (int i = 0; i < devdata->log->dives->nr - 1; i++) {
|
||||
if (devdata->log->dives->dives[i]->dcs[0].diveid == diveid) {
|
||||
dive = devdata->log->dives->dives[i];
|
||||
for (int x = i; x < devdata->log->dives->nr - 1; x++)
|
||||
devdata->log->dives->dives[i] = devdata->log->dives->dives[x + 1];
|
||||
}
|
||||
}
|
||||
}
|
||||
if (dive) {
|
||||
devdata->log->dives->dives[--devdata->log->dives->nr] = NULL;
|
||||
delete dive;
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
devdata->log->dives.erase(it);
|
||||
return true;
|
||||
}
|
||||
|
||||
/* This function is called for both dive log and dive information that we get
|
||||
|
@ -914,7 +900,7 @@ static bool process_raw_buffer(device_data_t *devdata, uint32_t deviceid, std::s
|
|||
bp = bp.substr(1);
|
||||
if (bp[0] != '{' && bp.find("{{") != std::string::npos) {
|
||||
done = false;
|
||||
record_dive_to_table(owned_dive.release(), devdata->log->dives.get());
|
||||
devdata->log->dives.record_dive(std::move(owned_dive));
|
||||
owned_dive = uemis_start_dive(deviceid);
|
||||
}
|
||||
}
|
||||
|
@ -947,7 +933,7 @@ static bool process_raw_buffer(device_data_t *devdata, uint32_t deviceid, std::s
|
|||
}
|
||||
if (is_log) {
|
||||
if (owned_dive->dcs[0].diveid)
|
||||
record_dive_to_table(owned_dive.release(), devdata->log->dives.get());
|
||||
devdata->log->dives.record_dive(std::move(owned_dive));
|
||||
else /* partial dive */
|
||||
return false;
|
||||
}
|
||||
|
@ -959,7 +945,6 @@ static std::pair<uint32_t, uint32_t> uemis_get_divenr(uint32_t deviceid, struct
|
|||
{
|
||||
uint32_t maxdiveid = 0;
|
||||
uint32_t mindiveid = 0xFFFFFFFF;
|
||||
int i;
|
||||
|
||||
/*
|
||||
* If we are are retrying after a disconnect/reconnect, we
|
||||
|
@ -971,11 +956,10 @@ static std::pair<uint32_t, uint32_t> uemis_get_divenr(uint32_t deviceid, struct
|
|||
*
|
||||
* Otherwise, use the global dive table.
|
||||
*/
|
||||
if (!force && !table->nr)
|
||||
table = divelog.dives.get();
|
||||
if (!force && table->empty())
|
||||
table = &divelog.dives;
|
||||
|
||||
for (i = 0; i < table->nr; i++) {
|
||||
struct dive *d = table->dives[i];
|
||||
for (auto &d: *table) {
|
||||
if (!d)
|
||||
continue;
|
||||
for (auto &dc: d->dcs) {
|
||||
|
@ -1037,19 +1021,19 @@ static bool do_dump_buffer_to_file(std::string_view buf, const char *prefix)
|
|||
* return : ok if there is enough memory for a full round
|
||||
* full if the memory is exhausted
|
||||
*/
|
||||
static uemis_mem_status get_memory(struct dive_table *td, uemis_checkpoint checkpoint)
|
||||
static uemis_mem_status get_memory(struct dive_table &td, uemis_checkpoint checkpoint)
|
||||
{
|
||||
if (td->nr <= 0)
|
||||
if (td.empty())
|
||||
return uemis_mem_status::ok;
|
||||
|
||||
switch (checkpoint) {
|
||||
case uemis_checkpoint::log:
|
||||
if (filenr / td->nr > max_mem_used)
|
||||
max_mem_used = filenr / td->nr;
|
||||
if (filenr / static_cast<int>(td.size()) > max_mem_used)
|
||||
max_mem_used = filenr / static_cast<int>(td.size());
|
||||
|
||||
/* check if a full block of dive logs + dive details and dive spot fit into the UEMIS buffer */
|
||||
#if UEMIS_DEBUG & 4
|
||||
report_info("max_mem_used %d (from td->nr %d) * block_size %d > max_files %d - filenr %d?\n", max_mem_used, td->nr, uemis_log_block_size, uemis_max_files, filenr);
|
||||
report_info("max_mem_used %d (from td.size() %d) * block_size %d > max_files %d - filenr %d?\n", max_mem_used, static_cast<int>(td.size()), uemis_log_block_size, uemis_max_files, filenr);
|
||||
#endif
|
||||
if (max_mem_used * uemis_log_block_size > uemis_max_files - filenr)
|
||||
return uemis_mem_status::full;
|
||||
|
@ -1069,10 +1053,10 @@ static uemis_mem_status get_memory(struct dive_table *td, uemis_checkpoint check
|
|||
|
||||
/* we misuse the hidden_by_filter flag to mark a dive as deleted.
|
||||
* this will be picked up by some cleaning statement later. */
|
||||
static void do_delete_dives(struct dive_table *td, int idx)
|
||||
static void do_delete_dives(struct dive_table &td, size_t idx)
|
||||
{
|
||||
for (int x = idx; x < td->nr; x++)
|
||||
td->dives[x]->hidden_by_filter = true;
|
||||
for (auto it = td.begin() + idx; it != td.end(); ++it)
|
||||
(*it)->hidden_by_filter = true;
|
||||
}
|
||||
|
||||
static bool load_uemis_divespot(const std::string &mountpath, int divespot_id)
|
||||
|
@ -1128,9 +1112,9 @@ static void get_uemis_divespot(device_data_t *devdata, const std::string &mountp
|
|||
}
|
||||
}
|
||||
|
||||
static bool get_matching_dive(int idx, int &newmax, uemis_mem_status &mem_status, device_data_t *data, const std::string &mountpath, const char deviceidnr)
|
||||
static bool get_matching_dive(size_t idx, int &newmax, uemis_mem_status &mem_status, device_data_t *data, const std::string &mountpath, const char deviceidnr)
|
||||
{
|
||||
struct dive *dive = data->log->dives->dives[idx];
|
||||
auto &dive = data->log->dives[idx];
|
||||
char log_file_no_to_find[20];
|
||||
bool found = false;
|
||||
bool found_below = false;
|
||||
|
@ -1151,7 +1135,7 @@ static bool get_matching_dive(int idx, int &newmax, uemis_mem_status &mem_status
|
|||
#if UEMIS_DEBUG & 16
|
||||
do_dump_buffer_to_file(mbuf, "Dive");
|
||||
#endif
|
||||
mem_status = get_memory(data->log->dives.get(), uemis_checkpoint::single_dive);
|
||||
mem_status = get_memory(data->log->dives, uemis_checkpoint::single_dive);
|
||||
if (mem_status == uemis_mem_status::ok) {
|
||||
/* if the memory isn's completely full we can try to read more dive log vs. dive details
|
||||
* and the dive spots should fit into the UEMIS memory
|
||||
|
@ -1174,7 +1158,7 @@ static bool get_matching_dive(int idx, int &newmax, uemis_mem_status &mem_status
|
|||
#endif
|
||||
int divespot_id = uemis_obj.get_divespot_id_by_diveid(dive->dcs[0].diveid);
|
||||
if (divespot_id >= 0)
|
||||
get_uemis_divespot(data, mountpath, divespot_id, dive);
|
||||
get_uemis_divespot(data, mountpath, divespot_id, dive.get());
|
||||
|
||||
} else {
|
||||
/* in this case we found a deleted file, so let's increment */
|
||||
|
@ -1215,7 +1199,7 @@ static bool get_matching_dive(int idx, int &newmax, uemis_mem_status &mem_status
|
|||
} else {
|
||||
/* At this point the memory of the UEMIS is full, let's cleanup all dive log files were
|
||||
* we could not match the details to. */
|
||||
do_delete_dives(data->log->dives.get(), idx);
|
||||
do_delete_dives(data->log->dives, idx);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -1236,7 +1220,6 @@ std::string do_uemis_import(device_data_t *data)
|
|||
std::string deviceid;
|
||||
std::string result;
|
||||
bool once = true;
|
||||
int match_dive_and_log = 0;
|
||||
int dive_offset = 0;
|
||||
uemis_mem_status mem_status = uemis_mem_status::ok;
|
||||
|
||||
|
@ -1274,7 +1257,7 @@ std::string do_uemis_import(device_data_t *data)
|
|||
|
||||
param_buff[1] = "notempty";
|
||||
{
|
||||
auto [mindiveid, maxdiveid] = uemis_get_divenr(deviceidnr, data->log->dives.get(), force_download);
|
||||
auto [mindiveid, maxdiveid] = uemis_get_divenr(deviceidnr, &data->log->dives, force_download);
|
||||
newmax = maxdiveid;
|
||||
if (verbose)
|
||||
report_info("Uemis downloader: start looking at dive nr %d", newmax);
|
||||
|
@ -1292,13 +1275,13 @@ std::string do_uemis_import(device_data_t *data)
|
|||
report_info("d_u_i inner loop start %d end %d newmax %d\n", start, end, newmax);
|
||||
#endif
|
||||
/* start at the last filled download table index */
|
||||
match_dive_and_log = data->log->dives->nr;
|
||||
size_t match_dive_and_log = data->log->dives.size();
|
||||
newmax = start;
|
||||
std::string newmax_str = std::to_string(newmax);
|
||||
param_buff[2] = newmax_str.c_str();
|
||||
param_buff[3].clear();
|
||||
std::string mbuf = uemis_get_answer(mountpath, "getDivelogs", 3, 0, result);
|
||||
mem_status = get_memory(data->log->dives.get(), uemis_checkpoint::details);
|
||||
mem_status = get_memory(data->log->dives, uemis_checkpoint::details);
|
||||
/* first, remove any leading garbage... this needs to start with a '{' */
|
||||
std::string_view realmbuf = mbuf;
|
||||
size_t pos = realmbuf.find('{');
|
||||
|
@ -1341,7 +1324,7 @@ std::string do_uemis_import(device_data_t *data)
|
|||
* What the following part does is to optimize the mapping by using
|
||||
* dive_to_read = the dive details entry that need to be read using the object_id
|
||||
* logFileNoToFind = map the logfilenr of the dive details with the object_id = diveid from the get dive logs */
|
||||
for (int i = match_dive_and_log; i < data->log->dives->nr; i++) {
|
||||
for (size_t i = match_dive_and_log; i < data->log->dives.size(); i++) {
|
||||
if (!get_matching_dive(i, newmax, mem_status, data, mountpath, deviceidnr))
|
||||
break;
|
||||
if (import_thread_cancelled)
|
||||
|
@ -1351,7 +1334,7 @@ std::string do_uemis_import(device_data_t *data)
|
|||
start = end;
|
||||
|
||||
/* Do some memory checking here */
|
||||
mem_status = get_memory(data->log->dives.get(), uemis_checkpoint::log);
|
||||
mem_status = get_memory(data->log->dives, uemis_checkpoint::log);
|
||||
if (mem_status != uemis_mem_status::ok) {
|
||||
#if UEMIS_DEBUG & 4
|
||||
report_info("d_u_i out of memory, bailing\n");
|
||||
|
@ -1365,7 +1348,7 @@ std::string do_uemis_import(device_data_t *data)
|
|||
// Resetting to original state
|
||||
filenr = 0;
|
||||
max_mem_used = -1;
|
||||
mem_status = get_memory(data->log->dives.get(), uemis_checkpoint::details);
|
||||
mem_status = get_memory(data->log->dives, uemis_checkpoint::details);
|
||||
if (uemis_get_answer(mountpath, "getDeviceId", 0, 1, result).empty())
|
||||
goto bail;
|
||||
if (deviceid != param_buff[0]) {
|
||||
|
@ -1408,7 +1391,7 @@ std::string do_uemis_import(device_data_t *data)
|
|||
* be deleted from the download_table.
|
||||
*/
|
||||
if (mem_status == uemis_mem_status::full)
|
||||
do_delete_dives(data->log->dives.get(), match_dive_and_log);
|
||||
do_delete_dives(data->log->dives, match_dive_and_log);
|
||||
#if UEMIS_DEBUG & 4
|
||||
report_info("d_u_i out of memory, bailing instead of processing\n");
|
||||
#endif
|
||||
|
@ -1425,9 +1408,9 @@ std::string do_uemis_import(device_data_t *data)
|
|||
|
||||
/* Regardless on where we are with the memory situation, it's time now
|
||||
* to see if we have to clean some dead bodies from our download table */
|
||||
for (int next_table_index = 0; next_table_index < data->log->dives->nr; ) {
|
||||
if (data->log->dives->dives[next_table_index]->hidden_by_filter)
|
||||
uemis_delete_dive(data, data->log->dives->dives[next_table_index]->dcs[0].diveid);
|
||||
for (size_t next_table_index = 0; next_table_index < data->log->dives.size(); ) {
|
||||
if (data->log->dives[next_table_index]->hidden_by_filter)
|
||||
uemis_delete_dive(data, data->log->dives[next_table_index]->dcs[0].diveid);
|
||||
else
|
||||
next_table_index++;
|
||||
}
|
||||
|
@ -1446,7 +1429,7 @@ bail:
|
|||
else
|
||||
result = param_buff[2];
|
||||
}
|
||||
if (!data->log->dives->nr)
|
||||
if (data->log->dives.empty())
|
||||
result = translate("gettextFromC", ERR_NO_FILES);
|
||||
return result;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue