folly->set_sorted_vector
来源:互联网 发布:好用的日记本软件 编辑:程序博客网 时间:2024/06/01 10:38
* This header defines two classes that very nearly model * AssociativeContainer (but not quite). These implement set-like and * map-like behavior on top of a sorted vector, instead of using * rb-trees like std::set and std::map. * * This is potentially useful in cases where the number of elements in * the set or map is small, or when you want to avoid using more * memory than necessary and insertions/deletions are much more rare * than lookups (these classes have O(N) insertions/deletions). */*这个头文件定义了两个相近的类,相协调的类,但不相等,在已排好的vector,实现行为像set,map的行为,而不是红黑树,这潜在的好处就是当set和map的元素比较小的时候,当你想避免使用更多的内存,而这的重要性比你插入/删除更多,比查找更少,这些类拥有O(N)现行复杂度的插入删除如果你对最小化使用内存有兴趣,那么这些类应该支持增长政策参数,不论我们什么时候插入元素,他都会被调用,然后你可以调用reserve(),根据现有的内存使用情况来分配新的内存*/ * In the interest of using these in conditions where the goal is to * minimize memory usage, they support a GrowthPolicy parameter, which * is a class defining a single function called increase_capacity, * which will be called whenever we are about to insert something: you * can then decide to call reserve() based on the current capacity() * and size() of the passed in vector-esque Container type. An * example growth policy that grows one element at a time: * * struct OneAtATimePolicy { * template<class Container> * void increase_capacity(Container& c) { * if (c.size() == c.capacity()) { * c.reserve(c.size() + 1); * } * } * }; * * typedef sorted_vector_set<int, * std::less<int>, * std::allocator<int>, * OneAtATimePolicy> * OneAtATimeIntSet; * * Important differences from std::set and std::map: * - insert() and erase() invalidate iterators and references * - insert() and erase() are O(N) * - our iterators model RandomAccessIterator * - sorted_vector_map::value_type is pair<K,V>, not pair<const K,V>. * (This is basically because we want to store the value_type in * std::vector<>, which requires it to be Assignable.) */#pragma once#include <algorithm>#include <initializer_list>#include <iterator>#include <utility>#include <vector>#include <boost/operators.hpp>#include <boost/bind.hpp>//vs报错#include <boost/type_traits/is_same.hpp>namespace folly {//////////////////////////////////////////////////////////////////////namespace detail { // This wrapper goes around a GrowthPolicy and provides iterator // preservation(保存) semantics, but only if the growth policy is not the // default (i.e. nothing). template<class Policy> struct growth_policy_wrapper : private Policy { template<class Container, class Iterator> Iterator increase_capacity(Container& c, Iterator desired_insertion) { typedef typename Container::difference_type diff_t; diff_t d = desired_insertion - c.begin(); Policy::increase_capacity(c); return c.begin() + d; } };/*这个类用来封装增长分配的政策,明显政策这里是具有弹性的,针对上面的OneAtATimePolicy 有几点疑问:它用私有继承,我能理解毕竟一个容器是用来用的,不是开源让后人盖楼,从OneAtATimePolicy 用size()和capacity()我能推断出,这是以标准库容器作为参数, 未知:为什么参数是将要插入的位置;为什么没有插入动作(下面解答),却返回插入位置的指针*/ template<> struct growth_policy_wrapper<void> { template<class Container, class Iterator> Iterator increase_capacity(Container&, Iterator it) { return it; } }; /*这个全特化,看起来就像为空政策做的准备 */ /* * This helper returns the distance between two iterators if it is * possible to figure it out without messing up the range * (i.e. unless they are InputIterators). Otherwise this returns * -1. */ /*这个助手返回两个迭代器的距离,前提是没有把这两个的范围搞错,例如两个数相等*/ template<class Iterator> int distance_if_multipass(Iterator first, Iterator last) { typedef typename std::iterator_traits<Iterator>::iterator_category categ; if (boost::is_same<categ,std::input_iterator_tag>::value) return -1; return std::distance(first, last); } //这里把输入溜迭代器除外,应该不能进行减操作 template<class OurContainer, class Vector, class GrowthPolicy> typename OurContainer::iterator insert_with_hint(OurContainer& sorted, Vector& cont, typename OurContainer::iterator hint, typename OurContainer::value_type&& value, GrowthPolicy& po) { const typename OurContainer::value_compare& cmp(sorted.value_comp()); if (hint == cont.end() || cmp(value, *hint)) { if (hint == cont.begin()) { po.increase_capacity(cont, cont.begin()); //OneAtATimePolicy就是看看有地方没,下面才是真正的插入动作 return cont.insert(cont.begin(), std::move(value)); } /*这是一种特殊情况,所插位置所在值既比既比value大,且他还插在头部*/ if (cmp(*(hint - 1), value)) { hint = po.increase_capacity(cont, hint); return cont.insert(hint, std::move(value)); } /*他想插在末尾,且前面的值比他小 或者说他满足第二个条件,后面的值比它大,这时再满足这个条件 就又可以不用再调整顺序了 */ return sorted.insert(std::move(value)).first; //把上面的vector理解为data members就好 } if (cmp(*hint, value)) { if (hint + 1 == cont.end() || cmp(value, *(hint + 1))) { typename OurContainer::iterator it = po.increase_capacity(cont, hint + 1); return cont.insert(it, std::move(value)); } } //当插入的值比 将插入位置所在值大,又分了两种情况,最后一个,注意左闭右开 //或者正好将插入位置的后一个位置所在值比插入值大,这样也可以不用重新排序了 // Value and *hint did not compare, so they are equal keys. return hint;//如果都不符合了,就返回这个迭代器 }}///////////////////////////////////////////////////////////////////////** * A sorted_vector_set is a container similar to std::set<>, but * implemented as as a sorted array with std::vector<>. * * @param class T Data type to store * @param class Compare Comparison function that imposes a * strict weak ordering over instances of T * @param class Allocator allocation policy * @param class GrowthPolicy policy object to control growth * * @author Aditya Agarwal <aditya@fb.com> * @author Akhil Wable <akhil@fb.com> * @author Jordan DeLong <delong.j@fb.com> */template<class T, class Compare = std::less<T>, class Allocator = std::allocator<T>, class GrowthPolicy = void>class sorted_vector_set : boost::totally_ordered1< sorted_vector_set<T,Compare,Allocator,GrowthPolicy> , detail::growth_policy_wrapper<GrowthPolicy> >{ typedef std::vector<T,Allocator> ContainerT; detail::growth_policy_wrapper<GrowthPolicy>& get_growth_policy() { return *this; }public: typedef T value_type; typedef T key_type; typedef Compare key_compare; typedef Compare value_compare; typedef typename ContainerT::pointer pointer; typedef typename ContainerT::reference reference; typedef typename ContainerT::const_reference const_reference; /* * XXX: Our normal iterator ought to also be a constant iterator * (cf. Defect Report 103 for std::set), but this is a bit more of a * pain. */ typedef typename ContainerT::iterator iterator; typedef typename ContainerT::const_iterator const_iterator; typedef typename ContainerT::difference_type difference_type; typedef typename ContainerT::size_type size_type; typedef typename ContainerT::reverse_iterator reverse_iterator; typedef typename ContainerT::const_reverse_iterator const_reverse_iterator; explicit sorted_vector_set(const Compare& comp = Compare(), const Allocator& alloc = Allocator()) : m_(comp, alloc) {} template<class InputIterator> explicit sorted_vector_set( InputIterator first, InputIterator last, const Compare& comp = Compare(), const Allocator& alloc = Allocator()) : m_(comp, alloc) { // This is linear if [first, last) is already sorted (and if we // can figure out the distance between the two iterators). insert(first, last); } explicit sorted_vector_set( std::initializer_list<value_type> list, const Compare& comp = Compare(), const Allocator& alloc = Allocator()) : m_(comp, alloc) { insert(list.begin(), list.end()); } key_compare key_comp() const { return m_; } value_compare value_comp() const { return m_; } iterator begin() { return m_.cont_.begin(); } iterator end() { return m_.cont_.end(); } const_iterator begin() const { return m_.cont_.begin(); } const_iterator end() const { return m_.cont_.end(); } reverse_iterator rbegin() { return m_.cont_.rbegin(); } reverse_iterator rend() { return m_.cont_.rend(); } const_reverse_iterator rbegin() const { return m_.cont_.rbegin(); } const_reverse_iterator rend() const { return m_.cont_.rend(); } void clear() { return m_.cont_.clear(); } size_type size() const { return m_.cont_.size(); } size_type max_size() const { return m_.cont_.max_size(); } bool empty() const { return m_.cont_.empty(); } void reserve(size_type s) { return m_.cont_.reserve(s); } void shrink_to_fit() { m_.cont_.shrink_to_fit(); } size_type capacity() const { return m_.cont_.capacity(); } std::pair<iterator,bool> insert(const value_type& value) { return insert(value_type(value)); } std::pair<iterator,bool> insert(value_type&& value) { iterator it = lower_bound(value); if (it == end() || value_comp()(value, *it)) { it = get_growth_policy().increase_capacity(m_.cont_, it); return std::make_pair(m_.cont_.insert(it, std::move(value)), true); } return std::make_pair(it, false); } iterator insert(iterator hint, const value_type& value) { return insert(hint, value_type(value)); } iterator insert(iterator hint, value_type&& value) { return detail::insert_with_hint(*this, m_.cont_, hint, std::move(value), get_growth_policy()); }
到这里,最让我头疼的就是插入的判断条件。
0 0
- folly->set_sorted_vector
- folly学习心得
- ubuntu 编译folly库
- facebook folly 编译安装
- folly (facebook opensource library)
- Hyperpolyglots: Paragon or Folly?
- linux编译folly
- facebook C++ overview(Folly)
- centos65 folly的编译安装
- Facebook开源C++组件库Folly
- folly源码分析(1) - Conv.h
- folly源码分析(2)- ProducerConsumerQueue.h
- folly源码分析(3)- ThreadLocalPtr
- folly源码分析(4)- ConcurrentSkipList.h
- 揭秘Facebook官方底层C++函数Folly
- Facebook开源C++组件库Folly
- folly下AtomicHashArray和AtomicHashMap简介
- Facebook的c++开源库folly介绍
- STL算法_heap算法篇
- tableView的编辑删除插入操作和UIAlertController的使用
- MySQL索引原理及慢查询优化
- Java动态模型系统OSGi实战讲解
- leetcode之-题34
- folly->set_sorted_vector
- netty in action fifth chapter Summary
- Ubuntu 搭建PHP环境
- Android开发:相册读取、拍照、图片裁剪和图片上传服务器等功能的实现
- 大话设计模式java版--简单工厂模式
- 【BZOJ】4552 排序
- Mapreduce Patterns, Algorithms, and use cases
- [Modern OpenGL系列(一)]十步搞定OpenGL开发环境
- 系统调用与库函数