GraphLab: Distributed Graph-Parallel API  2.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
small_map.hpp
1 /**
2  * Copyright (c) 2009 Carnegie Mellon University.
3  * All rights reserved.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing,
12  * software distributed under the License is distributed on an "AS
13  * IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
14  * express or implied. See the License for the specific language
15  * governing permissions and limitations under the License.
16  *
17  * For more about this software visit:
18  *
19  * http://www.graphlab.ml.cmu.edu
20  *
21  */
22 
23 
24 #ifndef GRAPHLAB_SMALL_MAP_HPP
25 #define GRAPHLAB_SMALL_MAP_HPP
26 
27 
28 #include <iostream>
29 #include <set>
30 #include <iterator>
31 #include <algorithm>
32 
33 #include <graphlab/serialization/iarchive.hpp>
34 #include <graphlab/serialization/oarchive.hpp>
35 
36 #include <graphlab/util/small_set.hpp>
37 
38 #include <graphlab/macros_def.hpp>
39 namespace graphlab {
40 
41  template<size_t MAX_DIM, typename KeyT, typename ValueT>
42  class small_map {
43  template< size_t T1, size_t T2 >
44  struct max_type { enum max_value { value = T1 < T2? T2 : T1 }; };
45  struct less {
46  bool operator()(const std::pair<KeyT, ValueT>& a,
47  const std::pair<KeyT, ValueT>& b) const {
48  return a.first < b.first;
49  }
50  };
51 
52 
53 
54  public:
55 
56  typedef small_set< MAX_DIM, std::pair<KeyT, ValueT>, less >
57  small_set_type;
58  typedef typename small_set_type::value_type value_type;
59  typedef typename small_set_type::iterator iterator;
60  typedef typename small_set_type::const_iterator const_iterator;
61  typedef KeyT key_type;
62  typedef ValueT mapped_type;
63 
64 
65  public:
66  //! construct an empty map
67  small_map() { }
68 
69  //! Construct a map with a single element
70  small_map(const key_type& key, const mapped_type& value) :
71  set(std::make_pair(key, value)) { }
72 
73 
74  //! Get the begin iterator
75  inline iterator begin() { return set.begin(); }
76 
77  //! get the end iterator
78  inline iterator end() { return set.end(); }
79 
80 
81  //! Get the begin iterator
82  inline const_iterator begin() const { return set.begin(); }
83 
84  //! Get the end iterator
85  inline const_iterator end() const { return set.end(); }
86 
87  //! get the size of the set
88  inline size_t size() const { return set.size(); }
89 
90  //! determine if there are any elements in the set
91  inline bool empty() const { return set.empty(); }
92 
93 
94  //! test whether the set contains the given element
95  bool contains(const value_type& pair) const {
96  return set.contains(pair);
97  }
98 
99  //! test whether the set contains the given element
100  bool contains(const key_type& key) const {
101  const_iterator iter =
102  std::lower_bound(set.begin(),
103  set.end(),
104  std::make_pair(key, mapped_type()));
105  return (iter != set.end()) && (iter->first == key);
106  }
107 
108  //! test whether the set has the given key
109  inline bool has_key(const key_type& key) {
110  return contains(key);
111  }
112 
113 
114  //! test whether the set contains the given set of element
115  template<size_t OtherDim>
116  bool contains(const small_map<OtherDim, KeyT, ValueT>& other) const {
117  return set.contains(other.set);
118  }
119 
120  template<size_t OtherDim>
121  bool operator==(const small_map<OtherDim, KeyT, ValueT>& other) const {
122  return set == other.set;
123  }
124 
125  //! Lookup an element in the map
126  inline const mapped_type& operator[](const key_type& key) const {
127  value_type* const ptr =
128  std::lower_bound(set.begin(), set.end(),
129  std::make_pair(key, mapped_type()),
130  less());
131  ASSERT_NE(ptr, set.end());
132  ASSERT_TURE(ptr->first == key);
133  return ptr->second;
134  }
135 
136  //! Lookup an element in the map
137  inline mapped_type& operator[](const key_type& key) {
138  value_type* ptr =
139  std::lower_bound(set.begin(), set.end(),
140  std::make_pair(key, mapped_type()),
141  less());
142  if(ptr != end() && (key == ptr->first) ) { return ptr->second; }
143  // Add the entry to the map
144  set += std::make_pair(key, ValueT());
145  ptr =
146  std::lower_bound(set.begin(), set.end(),
147  std::make_pair(key, mapped_type()),
148  less());
149  ASSERT_NE(ptr, set.end());
150  ASSERT_TRUE(ptr->first == key);
151  return ptr->second;
152  }
153 
154  inline mapped_type& safe_find(const key_type& key) {
155  value_type* const ptr =
156  std::lower_bound(set.begin(), set.end(),
157  std::make_pair(key, mapped_type()),
158  less());
159  ASSERT_NE(ptr, set.end());
160  ASSERT_TRUE(ptr->first == key);
161  return ptr->second;
162  }
163 
164  //! Take the union of two maps
165  template<size_t OtherDim>
166  inline small_map<max_type<OtherDim, MAX_DIM>::value, KeyT, ValueT>
167  operator+(const small_map<OtherDim, KeyT, ValueT>& other) const {
168  typedef small_map<max_type<OtherDim, MAX_DIM>::value, KeyT, ValueT >
169  result_type;
170  result_type result;
171  result.set = set + other.set;
172  return result;
173  }
174 
175 
176 
177  private:
178  small_set_type set;
179 
180 
181 
182  }; // end of small map
183 
184 
185  template<size_t MAX_DIM, typename KeyT, typename ValueT>
186  std::ostream&
187  operator<<(std::ostream& out,
188  const graphlab::small_map<MAX_DIM, KeyT, ValueT>& map) {
189  typedef std::pair<KeyT, ValueT> pair_type;
190  size_t index = 0;
191  out << '{';
192  foreach(const pair_type& pair, map) {
193  out << pair.first << "->" << pair.second;
194  if(++index < map.size()) out << ", ";
195  }
196  return out << '}';
197  }
198 
199 }; // end graphlab
200 
201 #include <graphlab/macros_undef.hpp>
202 #endif
203