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 ®istry) { 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