This source file includes following definitions.
- sorted
- KnockoutSubs
- RemoveMatchingPrefixes
- RemoveDeleted
- SBProcessSubs
#include "chrome/browser/safe_browsing/safe_browsing_store.h"
#include <algorithm>
#include "base/logging.h"
namespace {
template <typename CTI, typename LESS>
bool sorted(CTI beg, CTI end, LESS less) {
while ((end - beg) > 2) {
CTI n = beg++;
if (less(*beg, *n))
return false;
}
return true;
}
template <typename SubsT, typename AddsT,
typename PredAddSubT, typename PredSubAddT>
void KnockoutSubs(SubsT* subs, AddsT* adds,
PredAddSubT predAddSub, PredSubAddT predSubAdd,
AddsT* adds_removed) {
typename AddsT::iterator add_out = adds->begin();
typename SubsT::iterator sub_out = subs->begin();
typename AddsT::iterator add_iter = adds->begin();
typename SubsT::iterator sub_iter = subs->begin();
while (add_iter != adds->end() && sub_iter != subs->end()) {
if (predSubAdd(*sub_iter, *add_iter)) {
*sub_out = *sub_iter;
++sub_out;
++sub_iter;
} else if (predAddSub(*add_iter, *sub_iter)) {
*add_out = *add_iter;
++add_out;
++add_iter;
} else {
adds_removed->push_back(*add_iter);
++add_iter;
++sub_iter;
}
}
adds->erase(add_out, add_iter);
subs->erase(sub_out, sub_iter);
}
template <typename HashesT, typename AddsT>
void RemoveMatchingPrefixes(const AddsT& removes, HashesT* full_hashes) {
typename HashesT::iterator out = full_hashes->begin();
typename HashesT::iterator hash_iter = full_hashes->begin();
typename AddsT::const_iterator remove_iter = removes.begin();
while (hash_iter != full_hashes->end() && remove_iter != removes.end()) {
if (SBAddPrefixLess(*hash_iter, *remove_iter)) {
*out = *hash_iter;
++out;
++hash_iter;
} else if (SBAddPrefixLess(*remove_iter, *hash_iter)) {
++remove_iter;
} else {
do {
++hash_iter;
} while (hash_iter != full_hashes->end() &&
!SBAddPrefixLess(*remove_iter, *hash_iter));
++remove_iter;
}
}
full_hashes->erase(out, hash_iter);
}
template <typename ItemsT>
void RemoveDeleted(ItemsT* items, const base::hash_set<int32>& del_set) {
DCHECK(items);
typename ItemsT::iterator end_iter = items->begin();
for (typename ItemsT::iterator iter = end_iter;
iter != items->end(); ++iter) {
if (del_set.count(iter->chunk_id) == 0) {
*end_iter = *iter;
++end_iter;
}
}
items->erase(end_iter, items->end());
}
}
void SBProcessSubs(SBAddPrefixes* add_prefixes,
SBSubPrefixes* sub_prefixes,
std::vector<SBAddFullHash>* add_full_hashes,
std::vector<SBSubFullHash>* sub_full_hashes,
const base::hash_set<int32>& add_chunks_deleted,
const base::hash_set<int32>& sub_chunks_deleted) {
DCHECK(sorted(add_prefixes->begin(), add_prefixes->end(),
SBAddPrefixLess<SBAddPrefix,SBAddPrefix>));
DCHECK(sorted(sub_prefixes->begin(), sub_prefixes->end(),
SBAddPrefixLess<SBSubPrefix,SBSubPrefix>));
DCHECK(sorted(add_full_hashes->begin(), add_full_hashes->end(),
SBAddPrefixHashLess<SBAddFullHash,SBAddFullHash>));
DCHECK(sorted(sub_full_hashes->begin(), sub_full_hashes->end(),
SBAddPrefixHashLess<SBSubFullHash,SBSubFullHash>));
SBAddPrefixes removed_adds;
KnockoutSubs(sub_prefixes, add_prefixes,
SBAddPrefixLess<SBAddPrefix,SBSubPrefix>,
SBAddPrefixLess<SBSubPrefix,SBAddPrefix>,
&removed_adds);
RemoveMatchingPrefixes(removed_adds, add_full_hashes);
RemoveMatchingPrefixes(removed_adds, sub_full_hashes);
std::vector<SBAddFullHash> removed_full_adds;
KnockoutSubs(sub_full_hashes, add_full_hashes,
SBAddPrefixHashLess<SBAddFullHash,SBSubFullHash>,
SBAddPrefixHashLess<SBSubFullHash,SBAddFullHash>,
&removed_full_adds);
RemoveDeleted(add_prefixes, add_chunks_deleted);
RemoveDeleted(sub_prefixes, sub_chunks_deleted);
RemoveDeleted(add_full_hashes, add_chunks_deleted);
RemoveDeleted(sub_full_hashes, sub_chunks_deleted);
}