record cache keeps only the variants of the current contig
@@ -47,7 +47,7 @@ namespace ebi
* @param capacity: maximum amount of RecordCores that this instance can hold at any time.
* A value of 0 disables the limit, thus storing every RecordCore received. Use with caution.
*/
- RecordCache(size_t capacity) : capacity{capacity}, unlimited{capacity == 0} { }
+ explicit RecordCache(size_t capacity) : capacity{capacity}, unlimited{capacity == 0} { }
/**
* Getter function which returns a vector of Errors.
@@ -105,6 +105,25 @@ namespace ebi
list_duplicates.clear();
list_symbolic_duplicates.clear();
+ if (current_chromosome != record.chromosome) {
+ // EVA-1950: the cache removes "lexicographically lower" chromosomes when the cache is full, but with
+ // that sorting, "chr10" is lower than "chr2", so new variants in "chr10" get deleted to keep the ones
+ // in "chr2", and duplicates in "chr10" will go undetected. Possible solutions (better first):
+ // 1. The chosen simple solution is to keep in the cache variants from only one chromosome.
+ // 2. Another solution could be using the line number (Record::line) as sorting criteria, but that can
+ // get very surprising and unintuitive if used for other purposes outside of this class, so a custom
+ // comparator could be provided to the cache multiset constructor.
+ // 3. A third solution could be making a Least Recently Used cache, but will require using esoteric data
+ // structures and/or dependencies, or keeping several simpler structures in sync, like a map and a
+ // queue that point to each other's contents.
+ // 4. A poor solution could be changing the ordering to "numerically lower", but that will be very tricky
+ // to get right with weird chrs like (versioned) accessions. e.g.: NC_01.1 is a chr, which is likely to
+ // appear before a contig GK_01.1, and we would need a sorting method that evaluates NC_01.1 < GK_01.1.
+ cache_duplicates.clear();
+ cache_symbolic_duplicates.clear();
+ current_chromosome = record.chromosome;
+ }
+
for (RecordCore &record_core: record_cores) {
// create references to the appropriate data structures for th alternate allele type
@@ -162,6 +181,7 @@ namespace ebi
std::multiset<RecordCore> cache_symbolic_duplicates;
std::vector<std::unique_ptr<Error>> list_duplicates;
std::vector<std::unique_ptr<Error>> list_symbolic_duplicates;
+ std::string current_chromosome;
size_t capacity; ///< max amount of RecordCores that the cache can hold
bool unlimited; ///< if true, the set is not capped and will not erase any RecordCore
};
