Updates from google3; adding safe_btree comments, container (in)equality operators
parent
89a0af9086
commit
eaf6eb103d
|
@ -106,6 +106,23 @@ class btree_container {
|
||||||
double fullness() const { return tree_.fullness(); }
|
double fullness() const { return tree_.fullness(); }
|
||||||
double overhead() const { return tree_.overhead(); }
|
double overhead() const { return tree_.overhead(); }
|
||||||
|
|
||||||
|
bool operator==(const self_type& x) const {
|
||||||
|
if (size() != x.size()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for (const_iterator i = begin(), xi = x.begin(); i != end(); ++i, ++xi) {
|
||||||
|
if (*i != *xi) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator!=(const self_type& other) const {
|
||||||
|
return !operator==(other);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Tree tree_;
|
Tree tree_;
|
||||||
};
|
};
|
||||||
|
|
|
@ -188,6 +188,60 @@ TEST(Btree, IteratorIncrementBy) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(Btree, Comparison) {
|
||||||
|
const int kSetSize = 1201;
|
||||||
|
btree_set<int64> my_set;
|
||||||
|
for (int i = 0; i < kSetSize; ++i) {
|
||||||
|
my_set.insert(i);
|
||||||
|
}
|
||||||
|
btree_set<int64> my_set_copy(my_set);
|
||||||
|
EXPECT_TRUE(my_set_copy == my_set);
|
||||||
|
EXPECT_TRUE(my_set == my_set_copy);
|
||||||
|
EXPECT_FALSE(my_set_copy != my_set);
|
||||||
|
EXPECT_FALSE(my_set != my_set_copy);
|
||||||
|
|
||||||
|
my_set.insert(kSetSize);
|
||||||
|
EXPECT_FALSE(my_set_copy == my_set);
|
||||||
|
EXPECT_FALSE(my_set == my_set_copy);
|
||||||
|
EXPECT_TRUE(my_set_copy != my_set);
|
||||||
|
EXPECT_TRUE(my_set != my_set_copy);
|
||||||
|
|
||||||
|
my_set.erase(kSetSize - 1);
|
||||||
|
EXPECT_FALSE(my_set_copy == my_set);
|
||||||
|
EXPECT_FALSE(my_set == my_set_copy);
|
||||||
|
EXPECT_TRUE(my_set_copy != my_set);
|
||||||
|
EXPECT_TRUE(my_set != my_set_copy);
|
||||||
|
|
||||||
|
btree_map<string, int64> my_map;
|
||||||
|
for (int i = 0; i < kSetSize; ++i) {
|
||||||
|
my_map[string(i, 'a')] = i;
|
||||||
|
}
|
||||||
|
btree_map<string, int64> my_map_copy(my_map);
|
||||||
|
EXPECT_TRUE(my_map_copy == my_map);
|
||||||
|
EXPECT_TRUE(my_map == my_map_copy);
|
||||||
|
EXPECT_FALSE(my_map_copy != my_map);
|
||||||
|
EXPECT_FALSE(my_map != my_map_copy);
|
||||||
|
|
||||||
|
++my_map_copy[string(7, 'a')];
|
||||||
|
EXPECT_FALSE(my_map_copy == my_map);
|
||||||
|
EXPECT_FALSE(my_map == my_map_copy);
|
||||||
|
EXPECT_TRUE(my_map_copy != my_map);
|
||||||
|
EXPECT_TRUE(my_map != my_map_copy);
|
||||||
|
|
||||||
|
my_map_copy = my_map;
|
||||||
|
my_map["hello"] = kSetSize;
|
||||||
|
EXPECT_FALSE(my_map_copy == my_map);
|
||||||
|
EXPECT_FALSE(my_map == my_map_copy);
|
||||||
|
EXPECT_TRUE(my_map_copy != my_map);
|
||||||
|
EXPECT_TRUE(my_map != my_map_copy);
|
||||||
|
|
||||||
|
my_map.erase(string(kSetSize - 1, 'a'));
|
||||||
|
EXPECT_FALSE(my_map_copy == my_map);
|
||||||
|
EXPECT_FALSE(my_map == my_map_copy);
|
||||||
|
EXPECT_TRUE(my_map_copy != my_map);
|
||||||
|
EXPECT_TRUE(my_map != my_map_copy);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
} // namespace btree
|
} // namespace btree
|
||||||
} // namespace util
|
} // namespace util
|
||||||
|
|
11
safe_btree.h
11
safe_btree.h
|
@ -1,4 +1,4 @@
|
||||||
// Copyright 2007 Google Inc. All Rights Reserved.
|
// Copyright 2007, 2012 Google Inc. All Rights Reserved.
|
||||||
// Author: pmattis@google.com (Peter Mattis)
|
// Author: pmattis@google.com (Peter Mattis)
|
||||||
//
|
//
|
||||||
// A safe_btree<> wraps around a btree<> and removes the caveat that insertion
|
// A safe_btree<> wraps around a btree<> and removes the caveat that insertion
|
||||||
|
@ -8,6 +8,11 @@
|
||||||
// it was last validated and the key the underlying btree<>::iterator points
|
// it was last validated and the key the underlying btree<>::iterator points
|
||||||
// to. If an iterator is accessed and its generation differs from the tree
|
// to. If an iterator is accessed and its generation differs from the tree
|
||||||
// generation it is revalidated.
|
// generation it is revalidated.
|
||||||
|
//
|
||||||
|
// References and pointers returned by safe_btree iterators are not safe.
|
||||||
|
//
|
||||||
|
// See the incorrect usage examples mentioned in safe_btree_set.h and
|
||||||
|
// safe_btree_map.h.
|
||||||
|
|
||||||
#ifndef UTIL_BTREE_SAFE_BTREE_H__
|
#ifndef UTIL_BTREE_SAFE_BTREE_H__
|
||||||
#define UTIL_BTREE_SAFE_BTREE_H__
|
#define UTIL_BTREE_SAFE_BTREE_H__
|
||||||
|
@ -106,10 +111,14 @@ class safe_btree_iterator {
|
||||||
const key_type& key() const {
|
const key_type& key() const {
|
||||||
return key_;
|
return key_;
|
||||||
}
|
}
|
||||||
|
// This reference value is potentially invalidated by any non-const
|
||||||
|
// method on the tree; it is NOT safe.
|
||||||
reference operator*() const {
|
reference operator*() const {
|
||||||
DCHECK_GT(generation_, 0);
|
DCHECK_GT(generation_, 0);
|
||||||
return iter().operator*();
|
return iter().operator*();
|
||||||
}
|
}
|
||||||
|
// This pointer value is potentially invalidated by any non-const
|
||||||
|
// method on the tree; it is NOT safe.
|
||||||
pointer operator->() const {
|
pointer operator->() const {
|
||||||
DCHECK_GT(generation_, 0);
|
DCHECK_GT(generation_, 0);
|
||||||
return iter().operator->();
|
return iter().operator->();
|
||||||
|
|
|
@ -1,10 +1,20 @@
|
||||||
// Copyright 2007 Google Inc. All Rights Reserved.
|
// Copyright 2007, 2012 Google Inc. All Rights Reserved.
|
||||||
// Author: pmattis@google.com (Peter Mattis)
|
// Author: pmattis@google.com (Peter Mattis)
|
||||||
//
|
//
|
||||||
// The safe_btree_map<> is like btree_map<> except that it removes the caveat
|
// The safe_btree_map<> is like btree_map<> except that it removes the caveat
|
||||||
// about insertion and deletion invalidating existing iterators at a small cost
|
// about insertion and deletion invalidating existing iterators at a small cost
|
||||||
// in making iterators larger and slower.
|
// in making iterators larger and slower.
|
||||||
|
//
|
||||||
|
// Revalidation occurs whenever an iterator is accessed. References
|
||||||
|
// and pointers returned by safe_btree_map<> iterators are not stable,
|
||||||
|
// they are potentially invalidated by any non-const method on the map.
|
||||||
|
//
|
||||||
|
// BEGIN INCORRECT EXAMPLE
|
||||||
|
// for (auto i = safe_map->begin(); i != safe_map->end(); ++i) {
|
||||||
|
// const T *value = &i->second; // DO NOT DO THIS
|
||||||
|
// [code that modifies safe_map and uses value];
|
||||||
|
// }
|
||||||
|
// END INCORRECT EXAMPLE
|
||||||
#ifndef UTIL_BTREE_SAFE_BTREE_MAP_H__
|
#ifndef UTIL_BTREE_SAFE_BTREE_MAP_H__
|
||||||
#define UTIL_BTREE_SAFE_BTREE_MAP_H__
|
#define UTIL_BTREE_SAFE_BTREE_MAP_H__
|
||||||
|
|
||||||
|
@ -19,7 +29,7 @@
|
||||||
namespace util {
|
namespace util {
|
||||||
namespace btree {
|
namespace btree {
|
||||||
|
|
||||||
// The safe_btree_map class is needed mainly for it's constructors.
|
// The safe_btree_map class is needed mainly for its constructors.
|
||||||
template <typename Key, typename Value,
|
template <typename Key, typename Value,
|
||||||
typename Compare = less<Key>,
|
typename Compare = less<Key>,
|
||||||
typename Alloc = std::allocator<pair<const Key, Value> >,
|
typename Alloc = std::allocator<pair<const Key, Value> >,
|
||||||
|
|
|
@ -1,9 +1,20 @@
|
||||||
// Copyright 2007 Google Inc. All Rights Reserved.
|
// Copyright 2007, 2012 Google Inc. All Rights Reserved.
|
||||||
// Author: pmattis@google.com (Peter Mattis)
|
// Author: pmattis@google.com (Peter Mattis)
|
||||||
//
|
//
|
||||||
// The safe_btree_set<> is like btree_set<> except that it removes the caveat
|
// The safe_btree_set<> is like btree_set<> except that it removes the caveat
|
||||||
// about insertion and deletion invalidating existing iterators at a small cost
|
// about insertion and deletion invalidating existing iterators at a small cost
|
||||||
// in making iterators larger and slower.
|
// in making iterators larger and slower.
|
||||||
|
//
|
||||||
|
// Revalidation occurs whenever an iterator is accessed. References
|
||||||
|
// and pointers returned by safe_btree_map<> iterators are not stable,
|
||||||
|
// they are potentially invalidated by any non-const method on the set.
|
||||||
|
//
|
||||||
|
// BEGIN INCORRECT EXAMPLE
|
||||||
|
// for (auto i = safe_set->begin(); i != safe_set->end(); ++i) {
|
||||||
|
// const T &value = *i; // DO NOT DO THIS
|
||||||
|
// [code that modifies safe_set and uses value];
|
||||||
|
// }
|
||||||
|
// END INCORRECT EXAMPLE
|
||||||
|
|
||||||
#ifndef UTIL_BTREE_SAFE_BTREE_SET_H__
|
#ifndef UTIL_BTREE_SAFE_BTREE_SET_H__
|
||||||
#define UTIL_BTREE_SAFE_BTREE_SET_H__
|
#define UTIL_BTREE_SAFE_BTREE_SET_H__
|
||||||
|
@ -18,7 +29,7 @@
|
||||||
namespace util {
|
namespace util {
|
||||||
namespace btree {
|
namespace btree {
|
||||||
|
|
||||||
// The safe_btree_set class is needed mainly for it's constructors.
|
// The safe_btree_set class is needed mainly for its constructors.
|
||||||
template <typename Key,
|
template <typename Key,
|
||||||
typename Compare = less<Key>,
|
typename Compare = less<Key>,
|
||||||
typename Alloc = std::allocator<Key>,
|
typename Alloc = std::allocator<Key>,
|
||||||
|
|
|
@ -56,6 +56,60 @@ TEST(SafeBtree, map_string_256) { MapTest<string, 256>(); }
|
||||||
TEST(SafeBtree, map_cord_256) { MapTest<Cord, 256>(); }
|
TEST(SafeBtree, map_cord_256) { MapTest<Cord, 256>(); }
|
||||||
TEST(SafeBtree, map_pair_256) { MapTest<pair<int, int>, 256>(); }
|
TEST(SafeBtree, map_pair_256) { MapTest<pair<int, int>, 256>(); }
|
||||||
|
|
||||||
|
TEST(SafeBtree, Comparison) {
|
||||||
|
const int kSetSize = 1201;
|
||||||
|
safe_btree_set<int64> my_set;
|
||||||
|
for (int i = 0; i < kSetSize; ++i) {
|
||||||
|
my_set.insert(i);
|
||||||
|
}
|
||||||
|
safe_btree_set<int64> my_set_copy(my_set);
|
||||||
|
EXPECT_TRUE(my_set_copy == my_set);
|
||||||
|
EXPECT_TRUE(my_set == my_set_copy);
|
||||||
|
EXPECT_FALSE(my_set_copy != my_set);
|
||||||
|
EXPECT_FALSE(my_set != my_set_copy);
|
||||||
|
|
||||||
|
my_set.insert(kSetSize);
|
||||||
|
EXPECT_FALSE(my_set_copy == my_set);
|
||||||
|
EXPECT_FALSE(my_set == my_set_copy);
|
||||||
|
EXPECT_TRUE(my_set_copy != my_set);
|
||||||
|
EXPECT_TRUE(my_set != my_set_copy);
|
||||||
|
|
||||||
|
my_set.erase(kSetSize - 1);
|
||||||
|
EXPECT_FALSE(my_set_copy == my_set);
|
||||||
|
EXPECT_FALSE(my_set == my_set_copy);
|
||||||
|
EXPECT_TRUE(my_set_copy != my_set);
|
||||||
|
EXPECT_TRUE(my_set != my_set_copy);
|
||||||
|
|
||||||
|
safe_btree_map<string, int64> my_map;
|
||||||
|
for (int i = 0; i < kSetSize; ++i) {
|
||||||
|
my_map[string(i, 'a')] = i;
|
||||||
|
}
|
||||||
|
safe_btree_map<string, int64> my_map_copy(my_map);
|
||||||
|
EXPECT_TRUE(my_map_copy == my_map);
|
||||||
|
EXPECT_TRUE(my_map == my_map_copy);
|
||||||
|
EXPECT_FALSE(my_map_copy != my_map);
|
||||||
|
EXPECT_FALSE(my_map != my_map_copy);
|
||||||
|
|
||||||
|
++my_map_copy[string(7, 'a')];
|
||||||
|
EXPECT_FALSE(my_map_copy == my_map);
|
||||||
|
EXPECT_FALSE(my_map == my_map_copy);
|
||||||
|
EXPECT_TRUE(my_map_copy != my_map);
|
||||||
|
EXPECT_TRUE(my_map != my_map_copy);
|
||||||
|
|
||||||
|
my_map_copy = my_map;
|
||||||
|
my_map["hello"] = kSetSize;
|
||||||
|
EXPECT_FALSE(my_map_copy == my_map);
|
||||||
|
EXPECT_FALSE(my_map == my_map_copy);
|
||||||
|
EXPECT_TRUE(my_map_copy != my_map);
|
||||||
|
EXPECT_TRUE(my_map != my_map_copy);
|
||||||
|
|
||||||
|
my_map.erase(string(kSetSize - 1, 'a'));
|
||||||
|
EXPECT_FALSE(my_map_copy == my_map);
|
||||||
|
EXPECT_FALSE(my_map == my_map_copy);
|
||||||
|
EXPECT_TRUE(my_map_copy != my_map);
|
||||||
|
EXPECT_TRUE(my_map != my_map_copy);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
} // namespace btree
|
} // namespace btree
|
||||||
} // namespace util
|
} // namespace util
|
||||||
|
|
Loading…
Reference in New Issue