1 //  Copyright (c) 2013, Facebook, Inc.  All rights reserved.
2 //  This source code is licensed under both the GPLv2 (found in the
3 //  COPYING file in the root directory) and Apache 2.0 License
4 //  (found in the LICENSE.Apache file in the root directory).
5 #pragma once
6 
7 #include <limits>
8 #include <list>
9 
10 #include "util/mutexlock.h"
11 
12 namespace ROCKSDB_NAMESPACE {
13 
14 //
15 // Simple synchronized queue implementation with the option of
16 // bounding the queue
17 //
18 // On overflow, the elements will be discarded
19 //
20 template <class T>
21 class BoundedQueue {
22  public:
23   explicit BoundedQueue(
24       const size_t max_size = std::numeric_limits<size_t>::max())
25       : cond_empty_(&lock_), max_size_(max_size) {}
26 
~BoundedQueue()27   virtual ~BoundedQueue() {}
28 
Push(T && t)29   void Push(T&& t) {
30     MutexLock _(&lock_);
31     if (max_size_ != std::numeric_limits<size_t>::max() &&
32         size_ + t.Size() >= max_size_) {
33       // overflow
34       return;
35     }
36 
37     size_ += t.Size();
38     q_.push_back(std::move(t));
39     cond_empty_.SignalAll();
40   }
41 
Pop()42   T Pop() {
43     MutexLock _(&lock_);
44     while (q_.empty()) {
45       cond_empty_.Wait();
46     }
47 
48     T t = std::move(q_.front());
49     size_ -= t.Size();
50     q_.pop_front();
51     return t;
52   }
53 
Size()54   size_t Size() const {
55     MutexLock _(&lock_);
56     return size_;
57   }
58 
59  private:
60   mutable port::Mutex lock_;
61   port::CondVar cond_empty_;
62   std::list<T> q_;
63   size_t size_ = 0;
64   const size_t max_size_;
65 };
66 
67 }  // namespace ROCKSDB_NAMESPACE
68