1 /* Copyright 2016 Google Inc. All Rights Reserved.
2 
3 Licensed under the Apache License, Version 2.0 (the "License");
4 you may not use this file except in compliance with the License.
5 You may obtain a copy of the License at
6 
7     http://www.apache.org/licenses/LICENSE-2.0
8 
9 Unless required by applicable law or agreed to in writing, software
10 distributed under the License is distributed on an "AS IS" BASIS,
11 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 See the License for the specific language governing permissions and
13 limitations under the License.
14 ==============================================================================*/
15 
16 // Notes on thread-safety: All of the classes here are thread-compatible.  More
17 // specifically, the registry machinery is thread-safe, as long as each thread
18 // performs feature extraction on a different Sentence object.
19 
20 #ifndef WORKSPACE_H_
21 #define WORKSPACE_H_
22 
23 #include <stddef.h>
24 #include <string>
25 #include <typeindex>
26 #include <unordered_map>
27 #include <utility>
28 #include <vector>
29 
30 #include "base.h"
31 
32 namespace chrome_lang_id {
33 
34 // A base class for shared workspaces. Derived classes implement a static member
35 // function TypeName() which returns a human readable string name for the class.
36 class Workspace {
37  public:
38   // Polymorphic destructor.
~Workspace()39   virtual ~Workspace() {}
40 
41  protected:
42   // Create an empty workspace.
Workspace()43   Workspace() {}
44 
45  private:
46   CLD3_DISALLOW_COPY_AND_ASSIGN(Workspace);
47 };
48 
49 // A registry that keeps track of workspaces.
50 class WorkspaceRegistry {
51  public:
52   // Create an empty registry.
53   WorkspaceRegistry();
54   ~WorkspaceRegistry();
55 
56   const std::unordered_map<std::type_index, std::vector<std::string>>
WorkspaceNames()57       &WorkspaceNames() const {
58     return workspace_names_;
59   }
60 
61   // Returns a string describing the registered workspaces.
62   string DebugString() const;
63 
64  private:
65   // Workspace type names, indexed as workspace_types_[typeid].
66   std::unordered_map<std::type_index, string> workspace_types_;
67 
68   // Workspace names, indexed as workspace_names_[typeid][workspace].
69   std::unordered_map<std::type_index, std::vector<string>> workspace_names_;
70 
71   CLD3_DISALLOW_COPY_AND_ASSIGN(WorkspaceRegistry);
72 };
73 
74 // A typed collected of workspaces. The workspaces are indexed according to an
75 // external WorkspaceRegistry. If the WorkspaceSet is const, the contents are
76 // also immutable.
77 class WorkspaceSet {
78  public:
79   WorkspaceSet();
80   ~WorkspaceSet();
81 
Reset(const WorkspaceRegistry & registry)82   void Reset(const WorkspaceRegistry &registry) {
83     // Deallocate current workspaces.
84     for (auto &it : workspaces_) {
85       for (size_t index = 0; index < it.second.size(); ++index) {
86         delete it.second[index];
87       }
88     }
89     workspaces_.clear();
90 
91     // Allocate space for new workspaces.
92     for (auto &it : registry.WorkspaceNames()) {
93       workspaces_[it.first].resize(it.second.size());
94     }
95   }
96 
97  private:
98   // The set of workspaces, indexed as workspaces_[typeid][index].
99   std::unordered_map<std::type_index, std::vector<Workspace *>> workspaces_;
100 };
101 
102 // A workspace that wraps around a single int.
103 class SingletonIntWorkspace : public Workspace {
104  public:
105   // Default-initializes the int value.
SingletonIntWorkspace()106   SingletonIntWorkspace() {}
107 
108   // Initializes the int with the given value.
SingletonIntWorkspace(int value)109   explicit SingletonIntWorkspace(int value) : value_(value) {}
110 
111   // Returns the name of this type of workspace.
TypeName()112   static string TypeName() { return "SingletonInt"; }
113 
114   // Returns the int value.
get()115   int get() const { return value_; }
116 
117   // Sets the int value.
set(int value)118   void set(int value) { value_ = value; }
119 
120  private:
121   // The enclosed int.
122   int value_ = 0;
123 };
124 
125 // A workspace that wraps around a vector of int.
126 class VectorIntWorkspace : public Workspace {
127  public:
128   // Creates a vector of the given size.
129   explicit VectorIntWorkspace(int size);
130 
131   // Creates a vector initialized with the given array.
132   explicit VectorIntWorkspace(const std::vector<int> &elements);
133 
134   // Creates a vector of the given size, with each element initialized to the
135   // given value.
136   VectorIntWorkspace(int size, int value);
137 
138   ~VectorIntWorkspace() override;
139 
140   // Returns the name of this type of workspace.
141   static string TypeName();
142 
143   // Returns the i'th element.
element(int i)144   int element(int i) const { return elements_[i]; }
145 
146   // Sets the i'th element.
set_element(int i,int value)147   void set_element(int i, int value) { elements_[i] = value; }
148 
149  private:
150   // The enclosed vector.
151   std::vector<int> elements_;
152 };
153 
154 // A workspace that wraps around a vector of vector of int.
155 class VectorVectorIntWorkspace : public Workspace {
156  public:
157   // Creates a vector of empty vectors of the given size.
158   explicit VectorVectorIntWorkspace(int size);
159   ~VectorVectorIntWorkspace() override;
160 
161   // Returns the name of this type of workspace.
162   static string TypeName();
163 
164   // Returns the i'th vector of elements.
elements(int i)165   const std::vector<int> &elements(int i) const { return elements_[i]; }
166 
167   // Mutable access to the i'th vector of elements.
mutable_elements(int i)168   std::vector<int> *mutable_elements(int i) { return &(elements_[i]); }
169 
170  private:
171   // The enclosed vector of vector of elements.
172   std::vector<std::vector<int>> elements_;
173 };
174 
175 }  // namespace chrome_lang_id
176 
177 #endif  // WORKSPACE_H_
178