1 //
2 // Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2021
3 //
4 // Distributed under the Boost Software License, Version 1.0. (See accompanying
5 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 //
7 #pragma once
8 
9 #include "td/utils/common.h"
10 #include "td/utils/Slice.h"
11 
12 #include <map>
13 #include <unordered_map>
14 #include <utility>
15 
16 namespace td {
17 
18 // TODO template KeyT
19 class Hints {
20   using KeyT = int64;
21   using RatingT = int64;
22 
23  public:
24   void add(KeyT key, Slice name);
25 
remove(KeyT key)26   void remove(KeyT key) {
27     add(key, "");
28   }
29 
30   void set_rating(KeyT key, RatingT rating);
31 
32   std::pair<size_t, vector<KeyT>> search(
33       Slice query, int32 limit,
34       bool return_all_for_empty_query = false) const;  // TODO sort by name instead of sort by rating
35 
36   bool has_key(KeyT key) const;
37 
38   string key_to_string(KeyT key) const;
39 
40   std::pair<size_t, vector<KeyT>> search_empty(int32 limit) const;  // == search("", limit, true)
41 
42   size_t size() const;
43 
44  private:
45   std::map<string, vector<KeyT>> word_to_keys_;
46   std::map<string, vector<KeyT>> translit_word_to_keys_;
47   std::unordered_map<KeyT, string> key_to_name_;
48   std::unordered_map<KeyT, RatingT> key_to_rating_;
49 
50   static void add_word(const string &word, KeyT key, std::map<string, vector<KeyT>> &word_to_keys);
51   static void delete_word(const string &word, KeyT key, std::map<string, vector<KeyT>> &word_to_keys);
52 
53   static vector<string> fix_words(vector<string> words);
54 
55   static vector<string> get_words(Slice name, bool is_search);
56 
57   static void add_search_results(vector<KeyT> &results, const string &word,
58                                  const std::map<string, vector<KeyT>> &word_to_keys);
59 
60   vector<KeyT> search_word(const string &word) const;
61 
62   class CompareByRating {
63     const std::unordered_map<KeyT, RatingT> &key_to_rating_;
64 
get_rating(const KeyT & key)65     RatingT get_rating(const KeyT &key) const {
66       auto it = key_to_rating_.find(key);
67       if (it == key_to_rating_.end()) {
68         return RatingT();
69       }
70       return it->second;
71     }
72 
73    public:
CompareByRating(const std::unordered_map<KeyT,RatingT> & key_to_rating)74     explicit CompareByRating(const std::unordered_map<KeyT, RatingT> &key_to_rating) : key_to_rating_(key_to_rating) {
75     }
76 
operator()77     bool operator()(const KeyT &lhs, const KeyT &rhs) const {
78       auto lhs_rating = get_rating(lhs);
79       auto rhs_rating = get_rating(rhs);
80       return lhs_rating < rhs_rating || (lhs_rating == rhs_rating && lhs < rhs);
81     }
82   };
83 };
84 
85 }  // namespace td
86