github.com/igggame/nebulas-go@v2.1.0+incompatible/nbre/util/thread_safe_vector.h (about)

     1  // Copyright (C) 2018 go-nebulas authors
     2  //
     3  // This file is part of the go-nebulas library.
     4  //
     5  // the go-nebulas library is free software: you can redistribute it and/or
     6  // modify
     7  // it under the terms of the GNU General Public License as published by
     8  // the Free Software Foundation, either version 3 of the License, or // (at your
     9  // option) any later version.
    10  //
    11  // the go-nebulas library is distributed in the hope that it will be useful,
    12  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    13  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    14  // GNU General Public License for more details.
    15  //
    16  // You should have received a copy of the GNU General Public License
    17  // along with the go-nebulas library.  If not, see
    18  // <http://www.gnu.org/licenses/>.
    19  //
    20  #pragma once
    21  #include "common/common.h"
    22  
    23  namespace neb {
    24  template <typename T, typename Lock = boost::shared_mutex>
    25  class thread_safe_vector {
    26  public:
    27    typedef std::vector<T> vector_t;
    28    typedef Lock lock_t;
    29    using r_guard_t = boost::shared_lock<lock_t>;
    30    using w_guard_t = std::unique_lock<lock_t>;
    31  
    32    thread_safe_vector() = default;
    33  
    34    void push_back(const typename vector_t::value_type &op) {
    35      w_guard_t _l(m_mutex);
    36      m_vector.push_back(op);
    37    }
    38  
    39    std::pair<bool, typename vector_t::value_type> try_pop_back() {
    40      w_guard_t _l(m_mutex);
    41      if (m_vector.empty()) {
    42        return std::make_pair(false, typename vector_t::value_type());
    43      }
    44      auto ret = m_vector.back();
    45      m_vector.pop_back();
    46      return std::make_pair(true, ret);
    47    }
    48  
    49    typename vector_t::value_type front() {
    50      r_guard_t _l(m_mutex);
    51      auto ret = m_vector.front();
    52      return ret;
    53    }
    54  
    55    typename vector_t::value_type back() {
    56      r_guard_t _l(m_mutex);
    57      auto ret = m_vector.back();
    58      return ret;
    59    }
    60  
    61    template <typename Func>
    62    std::pair<bool, typename vector_t::value_type>
    63    try_lower_than(const typename vector_t::value_type &op, Func &&f) {
    64      r_guard_t _l(m_mutex);
    65      if (m_vector.empty()) {
    66        return std::make_pair(false, typename vector_t::value_type());
    67      }
    68      auto it = std::upper_bound(m_vector.begin(), m_vector.end(), op, f);
    69      it--;
    70      auto ret = *it;
    71      return std::make_pair(true, ret);
    72    }
    73  
    74    template <typename Func>
    75    std::pair<bool, typename vector_t::value_type>
    76    try_previous(const typename vector_t::value_type &op, Func &&f) {
    77      r_guard_t _l(m_mutex);
    78      if (m_vector.empty()) {
    79        return std::make_pair(false, typename vector_t::value_type());
    80      }
    81      auto it = std::lower_bound(m_vector.begin(), m_vector.end(), op, f);
    82      if (it == m_vector.begin()) {
    83        return std::make_pair(false, typename vector_t::value_type());
    84      }
    85      it--;
    86      auto ret = *it;
    87      return std::make_pair(true, ret);
    88    }
    89  
    90    size_t size() const {
    91      r_guard_t _l(m_mutex);
    92      return m_vector.size();
    93    }
    94  
    95    bool empty() const {
    96      r_guard_t _l(m_mutex);
    97      return m_vector.empty();
    98    }
    99  
   100  private:
   101    vector_t m_vector;
   102    mutable lock_t m_mutex;
   103  };
   104  } // namespace neb