blob: 186f3d3d7cc7bfb3bc33dbbe5f1af13fb0ca2408 [file] [log] [blame]
// Copyright 2020 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/query_tiles/internal/tile_group.h"
#include <set>
#include <sstream>
#include <utility>
#include "components/query_tiles/internal/tile_iterator.h"
#include "components/query_tiles/internal/tile_utils.h"
namespace query_tiles {
namespace {
// Score to be received by a tile when it is clicked.
constexpr double kTileClickScore = 1.0;
void DeepCopyGroup(const TileGroup& input, TileGroup* output) {
DCHECK(output);
output->id = input.id;
output->locale = input.locale;
output->last_updated_ts = input.last_updated_ts;
output->tiles.clear();
for (const auto& tile : input.tiles)
output->tiles.emplace_back(std::make_unique<Tile>(*tile.get()));
output->tile_stats = input.tile_stats;
}
// Removes |id| from |id_set|. Returns true if |id| is found, or false
// otherwise.
bool RemoveIdFromSet(std::set<std::string>* id_set, const std::string& id) {
const auto it = id_set->find(id);
if (it != id_set->end()) {
id_set->erase(it);
return true;
}
return false;
}
} // namespace
TileGroup::TileGroup() = default;
TileGroup::~TileGroup() = default;
bool TileGroup::operator==(const TileGroup& other) const {
return id == other.id && locale == other.locale &&
last_updated_ts == other.last_updated_ts &&
tiles.size() == other.tiles.size();
}
bool TileGroup::operator!=(const TileGroup& other) const {
return !(*this == other);
}
void TileGroup::OnTileClicked(const std::string& tile_id) {
base::Time now_time = base::Time::Now();
auto iter = tile_stats.find(tile_id);
double score =
(iter == tile_stats.end())
? kTileClickScore
: kTileClickScore + CalculateTileScore(iter->second, now_time);
tile_stats[tile_id] = TileStats(now_time, score);
}
TileGroup::TileGroup(const TileGroup& other) {
DeepCopyGroup(other, this);
}
TileGroup::TileGroup(TileGroup&& other) = default;
TileGroup& TileGroup::operator=(const TileGroup& other) {
DeepCopyGroup(other, this);
return *this;
}
TileGroup& TileGroup::operator=(TileGroup&& other) = default;
std::string TileGroup::DebugString() {
std::stringstream out;
out << "Group detail: \n";
out << "id: " << this->id << " | locale: " << this->locale
<< " | last_updated_ts: " << this->last_updated_ts << " \n";
for (const auto& tile : this->tiles)
out << tile->DebugString();
return out.str();
}
void TileGroup::RemoveTiles(const std::vector<std::string>& tile_ids) {
std::set<std::string> id_set(tile_ids.begin(), tile_ids.end());
std::queue<Tile*> tile_queue;
// Check if there are top level tiles to be removed.
for (auto iter = tiles.begin(); iter != tiles.end();) {
if (RemoveIdFromSet(&id_set, (*iter)->id)) {
iter = tiles.erase(iter);
if (id_set.empty())
return;
} else {
tile_queue.push(iter->get());
++iter;
}
}
// Recursively check if there are sub tiles to be removed.
while (!tile_queue.empty()) {
Tile* tile = tile_queue.front();
tile_queue.pop();
for (auto it = tile->sub_tiles.begin(); it != tile->sub_tiles.end();) {
if (RemoveIdFromSet(&id_set, (*it)->id)) {
it = tile->sub_tiles.erase(it);
if (id_set.empty())
return;
} else {
tile_queue.push(it->get());
++it;
}
}
}
}
} // namespace query_tiles