Commit 6821ef76 authored by Min Qin's avatar Min Qin Committed by Commit Bot

Add a min score for new front tiles

If the first tile is not frequently clicked, other tiles may be displayed
before it. And those tiles, even if they are not clicked for many days,
will stay before the first.
This may cause new front tiles, such as the trending tiles, to have a
lower score than those not clicked tiles. And will not show up in the
front. This CL fixes that issue

BUG=1136306

Change-Id: I2f5aa7d3a64450b23375b2df2647265ed9c70c22
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2459941
Commit-Queue: Min Qin <qinmin@chromium.org>
Reviewed-by: default avatarShakti Sahu <shaktisahu@chromium.org>
Reviewed-by: default avatarXing Liu <xingliu@chromium.org>
Cr-Commit-Position: refs/heads/master@{#815277}
parent d1b151a4
......@@ -50,6 +50,9 @@ constexpr char kBackoffMaxDelayInMsKey[] = "backoff_policy_max_delay_in_ms";
constexpr char kTileScoreDecayLambdaKey[] = "tile_score_decay_lambda";
constexpr char kMinimumScoreForNewFrontTilesKey[] =
"min_score_for_new_front_tiles";
// Default expire duration.
constexpr int kDefaultExpireDurationInSeconds = 48 * 60 * 60; // 2 days.
......@@ -72,6 +75,11 @@ constexpr int kDefaultBackoffMaxDelayInMs = 24 * 3600 * 1000; // 1 day.
// Default lambda value used for calculating tile score decay over time.
constexpr double kDefaultTileScoreDecayLambda = -0.099;
// Default minimum score for new tiles in front of others. 0.9 is chosen so
// that new tiles will have a higher score than tiles that have not been
// clicked for 2 days.
constexpr double kDefaultMinimumTileScoreForNewFrontTiles = 0.9;
namespace {
// For testing. Json string for single tier experiment tag.
......@@ -183,4 +191,11 @@ double TileConfig::GetTileScoreDecayLambda() {
kDefaultTileScoreDecayLambda);
}
// static
double TileConfig::GetMinimumScoreForNewFrontTiles() {
return base::GetFieldTrialParamByFeatureAsDouble(
features::kQueryTiles, kMinimumScoreForNewFrontTilesKey,
kDefaultMinimumTileScoreForNewFrontTiles);
}
} // namespace query_tiles
......@@ -50,6 +50,10 @@ extern const char kBackoffMaxDelayInMsKey[];
// Finch parameter key for lambda in tile score decay calculation.
extern const char kTileScoreDecayLambdaKey[];
// Finch parameter key representing the minimum scores for new tiles that are in
// front of others.
extern const char kMinimumScoreForNewFrontTilesKey[];
class TileConfig {
public:
// Gets the URL for the Query Tiles server.
......@@ -90,6 +94,9 @@ class TileConfig {
// Get the lambda value used for calculating the tile score decay over time.
static double GetTileScoreDecayLambda();
// Get the minimum scrore for newly showing tiles that are in front of others.
static double GetMinimumScoreForNewFrontTiles();
};
} // namespace query_tiles
......
......@@ -32,18 +32,6 @@ void SortTiles(std::vector<std::unique_ptr<Tile>>* tiles,
// Some tiles do not have scores, so the first step is to calculate scores
// for them.
// To calculate scores for new tiles, ordering from the server response will
// be taken into consideration. As the server has already ordered tiles
// according to their importance.
// For example, if the first tile returned by server never appeared before, we
// should set its score to at least the 2nd tile. so that it can show up in
// the first place if no other tiles in the back have a higher score. For
// a new tile at position x, its score should be the minimum of its neighbors
// at position x-1 and x+1. For new tiles showing up at the end, their score
// will be set to 0.
// For example, if the tile scores are (new_tile, 0.5, 0.7), then the adjusted
// score will be (0.5, 0.5, 0.7). Simularly, (0.5, new_tile1, 0.7, new_tile2)
// will result in (0.5, 0.5, 0.7, 0).
double last_score = std::numeric_limits<double>::max();
base::Time now_time = base::Time::Now();
TileStats last_tile_stats(now_time, last_score);
......@@ -65,6 +53,17 @@ void SortTiles(std::vector<std::unique_ptr<Tile>>* tiles,
double min_score = std::min(new_score, last_score);
TileStats new_stats =
new_score > last_score ? last_tile_stats : iter->second;
// For new tiles at the beginning, give them a score higher than the
// minimum score, so that they have a chance to show if the top ranked
// tiles have not been clicked recently.
if (new_tile_index == 0) {
double min_score_for_new_front_tiles =
TileConfig::GetMinimumScoreForNewFrontTiles();
if (min_score < min_score_for_new_front_tiles) {
min_score = min_score_for_new_front_tiles;
new_stats = TileStats(now_time, min_score);
}
}
for (size_t j = new_tile_index; j < i; ++j) {
tile_stats->emplace((*tiles)[j]->id, new_stats);
score_map.emplace((*tiles)[j]->id, min_score);
......
......@@ -16,6 +16,20 @@ namespace query_tiles {
// Function to sort a vector of tiles based on their score in |tile_stats|. If
// a tile ID doesn't exists in |tile_stats|, a new entry will be created and
// a score will be calculated.
// To calculate scores for new tiles, ordering from the server response will
// be taken into consideration. As the server has already ordered tiles
// according to their importance.
// For example, if the first tile returned by server never appeared before, we
// should set its score to at least the 2nd tile. so that it can show up in
// the first place if no other tiles in the back have a higher score. For
// a new tile at position x, its score should be the minimum of its neighbors
// at position x-1 and x+1. For new tiles showing up at the end, their score
// will be set to 0.
// For example, if the tile scores are (new_tile, 0.5, 0.7), then the adjusted
// score will be (0.5, 0.5, 0.7). Simularly, (0.5, new_tile1, 0.7, new_tile2)
// will result in (0.5, 0.5, 0.7, 0). And for new tiles at the front, they are
// guaranteed a minimum score. So that if all the other tiles haven't been
// clicked for a while, it will have a chance to be placed at the front.
void SortTiles(std::vector<std::unique_ptr<Tile>>* tiles,
std::map<std::string, TileStats>* tile_stats);
......
......@@ -4,6 +4,7 @@
#include "components/query_tiles/internal/tile_utils.h"
#include "components/query_tiles/internal/tile_config.h"
#include "components/query_tiles/internal/tile_group.h"
#include "components/query_tiles/test/test_utils.h"
#include "testing/gtest/include/gtest/gtest.h"
......@@ -56,9 +57,13 @@ TEST(TileUtilsTest, SortWithNewTilesAtTheFront) {
EXPECT_EQ(group.tiles[2]->id, "guid-1-3");
EXPECT_EQ(group.tiles[0]->sub_tiles[0]->id, "guid-2-1");
EXPECT_EQ(group.tiles[0]->sub_tiles[1]->id, "guid-2-2");
EXPECT_EQ(tile_stats["guid-1-1"].score, 0.7);
EXPECT_EQ(tile_stats["guid-1-2"].score, 0.7);
EXPECT_EQ(tile_stats["guid-2-1"].score, 0.6);
// Front tiles should have the minimum score.
EXPECT_EQ(tile_stats["guid-1-1"].score,
TileConfig::GetMinimumScoreForNewFrontTiles());
EXPECT_EQ(tile_stats["guid-1-2"].score,
TileConfig::GetMinimumScoreForNewFrontTiles());
EXPECT_EQ(tile_stats["guid-2-1"].score,
TileConfig::GetMinimumScoreForNewFrontTiles());
}
// If new tiles are at the end, tile ordering should be kept after
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment