1 //
2 // Copyright RIME Developers
3 // Distributed under the BSD License
4 //
5 // 2011-10-30 GONG Chen <chen.sst@gmail.com>
6 //
7 #ifndef RIME_USER_DICTIONARY_H_
8 #define RIME_USER_DICTIONARY_H_
9 
10 #include <time.h>
11 #include <rime/common.h>
12 #include <rime/component.h>
13 #include <rime/dict/user_db.h>
14 #include <rime/dict/vocabulary.h>
15 
16 namespace rime {
17 
18 class UserDictEntryIterator : public DictEntryFilterBinder {
19  public:
20   UserDictEntryIterator() = default;
21 
22   void Add(an<DictEntry>&& entry);
23   void SetEntries(DictEntryList&& entries);
24   void SortRange(size_t start, size_t count);
25 
26   void AddFilter(DictEntryFilter filter) override;
27   an<DictEntry> Peek();
28   bool Next();
exhausted()29   bool exhausted() const {
30     return index_ >= cache_.size();
31   }
cache_size()32   size_t cache_size() const {
33     return cache_.size();
34   }
35 
36  protected:
37   bool FindNextEntry();
38 
39   DictEntryList cache_;
40   size_t index_ = 0;
41 };
42 
43 using UserDictEntryCollector = map<size_t, UserDictEntryIterator>;
44 
45 class Schema;
46 class Table;
47 class Prism;
48 class Db;
49 struct SyllableGraph;
50 struct DfsState;
51 struct Ticket;
52 
53 class UserDictionary : public Class<UserDictionary, const Ticket&> {
54  public:
55   UserDictionary(const string& name, an<Db> db);
56   virtual ~UserDictionary();
57 
58   void Attach(const an<Table>& table, const an<Prism>& prism);
59   bool Load();
60   bool loaded() const;
61   bool readonly() const;
62 
63   an<UserDictEntryCollector> Lookup(const SyllableGraph& syllable_graph,
64                                     size_t start_pos,
65                                     size_t depth_limit = 0,
66                                     double initial_credibility = 0.0);
67   size_t LookupWords(UserDictEntryIterator* result,
68                      const string& input,
69                      bool predictive,
70                      size_t limit = 0,
71                      string* resume_key = NULL);
72   bool UpdateEntry(const DictEntry& entry, int commits);
73   bool UpdateEntry(const DictEntry& entry, int commits,
74                    const string& new_entry_prefix);
75   bool UpdateTickCount(TickCount increment);
76 
77   bool NewTransaction();
78   bool RevertRecentTransaction();
79   bool CommitPendingTransaction();
80 
name()81   const string& name() const { return name_; }
tick()82   TickCount tick() const { return tick_; }
83 
84   static an<DictEntry> CreateDictEntry(const string& key,
85                                        const string& value,
86                                        TickCount present_tick,
87                                        double credibility = 0.0,
88                                        string* full_code = NULL);
89 
90  protected:
91   bool Initialize();
92   bool FetchTickCount();
93   bool TranslateCodeToString(const Code& code, string* result);
94   void DfsLookup(const SyllableGraph& syll_graph, size_t current_pos,
95                  const string& current_prefix,
96                  DfsState* state);
97 
98  private:
99   string name_;
100   an<Db> db_;
101   an<Table> table_;
102   an<Prism> prism_;
103   TickCount tick_ = 0;
104   time_t transaction_time_ = 0;
105 };
106 
107 class UserDictionaryComponent : public UserDictionary::Component {
108  public:
109   UserDictionaryComponent();
110   UserDictionary* Create(const Ticket& ticket);
111  private:
112   map<string, weak<Db>> db_pool_;
113 };
114 
115 }  // namespace rime
116 
117 #endif  // RIME_USER_DICTIONARY_H_
118