jubatus_core  0.1.2
Jubatus: Online machine learning framework for distributed environment
lru_unlearner.cpp
Go to the documentation of this file.
1 // Jubatus: Online machine learning framework for distributed environment
2 // Copyright (C) 2013 Preferred Networks and Nippon Telegraph and Telephone Corporation.
3 //
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License version 2.1 as published by the Free Software Foundation.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16 
17 #include "lru_unlearner.hpp"
18 
19 #include <string>
20 #include "jubatus/util/data/unordered_set.h"
21 
22 // TODO(kmaehashi) move key_matcher to common
23 #include "../fv_converter/key_matcher.hpp"
24 #include "../fv_converter/key_matcher_factory.hpp"
25 #include "../common/exception.hpp"
26 
27 using jubatus::util::data::unordered_set;
29 
30 namespace jubatus {
31 namespace core {
32 namespace unlearner {
33 
35  : max_size_(conf.max_size) {
36  if (conf.max_size <= 0) {
37  throw JUBATUS_EXCEPTION(
39  "max_size must be a positive integer"));
40  }
41  entry_map_.reserve(max_size_);
42 
43  if (conf.sticky_pattern) {
46  }
47 }
48 
49 bool lru_unlearner::can_touch(const std::string& id) {
50  return (exists_in_memory(id) || sticky_ids_.size() < max_size_);
51 }
52 
53 bool lru_unlearner::touch(const std::string& id) {
54  // When sticky pattern is specified, unlearner excludes IDs matching
55  // the pattern from unlearning.
56  bool is_sticky = sticky_matcher_ && sticky_matcher_->match(id);
57 
58  if (is_sticky) {
59  unordered_set<std::string>::const_iterator it = sticky_ids_.find(id);
60  if (it != sticky_ids_.end()) {
61  // Sticky ID that is already on memory; nothing to do.
62  return true;
63  }
64  } else {
65  entry_map::iterator it = entry_map_.find(id);
66  if (it != entry_map_.end()) {
67  // Non-sticky ID that is already on memory; mark the ID
68  // as most recently used.
69  lru_.push_front(id);
70  lru_.erase(it->second);
71  it->second = lru_.begin();
72  return true;
73  }
74  }
75 
76  // Touched ID is not on memory; need to secure a space for it.
77  if ((entry_map_.size() + sticky_ids_.size()) >= max_size_) {
78  // No more space; sticky_ids_ is the list of IDs that cannot be
79  // unlearned, so try to unlearn from entry_map_.
80  if (entry_map_.size() == 0) {
81  // entry_map_ is empty; nothing can be unlearned.
82  return false;
83  }
84 
85  // Unlearn the least recently used entry.
86  unlearn(lru_.back());
87  entry_map_.erase(lru_.back());
88  lru_.pop_back();
89  }
90 
91  // Register the new ID.
92  if (is_sticky) {
93  sticky_ids_.insert(id);
94  } else {
95  lru_.push_front(id);
96  entry_map_[id] = lru_.begin();
97  }
98 
99  return true;
100 }
101 
102 bool lru_unlearner::remove(const std::string& id) {
103  // Try to erase from non-sticky ID.
104  {
105  entry_map::iterator it = entry_map_.find(id);
106  if (it != entry_map_.end()) {
107  lru_.erase(it->second);
108  entry_map_.erase(it);
109  return true;
110  }
111  }
112 
113  // Try to erase from sticky ID.
114  {
115  unordered_set<std::string>::iterator it = sticky_ids_.find(id);
116  if (it != sticky_ids_.end()) {
117  sticky_ids_.erase(it);
118  return true;
119  }
120  }
121 
122  return false;
123 }
124 
125 bool lru_unlearner::exists_in_memory(const std::string& id) const {
126  return entry_map_.count(id) > 0 || sticky_ids_.count(id) > 0;
127 }
128 
129 // private
130 
132  entry_map_.clear();
133  for (lru::iterator it = lru_.begin(); it != lru_.end(); ++it) {
134  entry_map_[*it] = it;
135  }
136 }
137 
138 } // namespace unlearner
139 } // namespace core
140 } // namespace jubatus
bool can_touch(const std::string &id)
bool exists_in_memory(const std::string &id) const
bool touch(const std::string &id)
void unlearn(const std::string &id) const
#define JUBATUS_EXCEPTION(e)
Definition: exception.hpp:79
jubatus::util::data::optional< std::string > unlearner
jubatus::util::lang::shared_ptr< jubatus::core::fv_converter::key_matcher > sticky_matcher_
bool remove(const std::string &id)
jubatus::util::data::unordered_set< std::string > sticky_ids_
jubatus::util::data::optional< std::string > sticky_pattern
jubatus::util::lang::shared_ptr< key_matcher > create_matcher(const std::string &matcher)