GEOSX
FixedSizeDeque.hpp
1 /*
2  * ------------------------------------------------------------------------------------------------------------
3  * SPDX-License-Identifier: LGPL-2.1-only
4  *
5  * Copyright (c) 2018-2020 Lawrence Livermore National Security LLC
6  * Copyright (c) 2018-2020 The Board of Trustees of the Leland Stanford Junior University
7  * Copyright (c) 2018-2020 TotalEnergies
8  * Copyright (c) 2019- GEOSX Contributors
9  * All rights reserved
10  *
11  * See top level LICENSE, COPYRIGHT, CONTRIBUTORS, NOTICE, and ACKNOWLEDGEMENTS files for details.
12  * ------------------------------------------------------------------------------------------------------------
13  */
14 #ifndef FIXEDSIZEDEQUE_HPP
15 #define FIXEDSIZEDEQUE_HPP
16 
17 #include "LvArray/src/Array.hpp"
18 #include "LvArray/src/memcpy.hpp"
19 #include "LvArray/src/ChaiBuffer.hpp"
20 #include "common/Logger.hpp"
21 
23 #define POSITIVE_MODULO( a, b ) ( ( ( a ) % ( b ) ) + b ) % ( b )
24 namespace geos
25 {
26 template< typename T, typename INDEX_TYPE >
29 {
31  using IndexType = INDEX_TYPE;
33  using ArraySlice1DLarge = LvArray::ArraySlice< T const, 1, 0, std::ptrdiff_t >;
35  using Array2D = LvArray::Array< T, 2, camp::make_idx_seq_t< 2 >, std::ptrdiff_t, LvArray::ChaiBuffer >;
36 public:
45  FixedSizeDeque( IndexType maxEntries, IndexType valuesPerEntry, LvArray::MemorySpace space, camp::resources::Resource stream ):
46  m_stream( stream )
47  {
48  GEOS_ERROR_IF( maxEntries < 0, "Fixed sized queue size must be positive" );
49  GEOS_ERROR_IF( valuesPerEntry < 0, "Fixed sized queue array size must be positive" );
50  m_storage.resizeWithoutInitializationOrDestruction( space, maxEntries, valuesPerEntry );
51  }
52 
54  bool empty() const
55  {
56  return m_begin > m_end;
57  }
58 
60  bool full() const
61  {
62  return size() == (size_t)m_storage.size( 0 );
63  }
64 
66  size_t size() const
67  {
68  return (size_t)( m_end - m_begin + 1 );
69  }
70 
72  size_t capacity() const
73  {
74  return m_storage.size( 0 );
75  }
76 
78  ArraySlice1DLarge front() const
79  {
80  GEOS_ERROR_IF( empty(), "Can't get front from empty queue" );
81  return m_storage[ POSITIVE_MODULO( m_begin, m_storage.size( 0 ) ) ];
82  }
83 
85  ArraySlice1DLarge next_front() const
86  {
87  GEOS_ERROR_IF( full(), "Can't increase in a full queue" );
88  return m_storage[ POSITIVE_MODULO( m_begin-1, m_storage.size( 0 ) ) ];
89  }
90 
92  ArraySlice1DLarge back() const
93  {
94  GEOS_ERROR_IF( empty(), "Can't get back from empty queue" );
95  return m_storage[ POSITIVE_MODULO( m_end, m_storage.size( 0 ) ) ];
96  }
97 
99  ArraySlice1DLarge next_back() const
100  {
101  GEOS_ERROR_IF( full(), "Can't increase in a full queue" );
102  return m_storage[ POSITIVE_MODULO( m_end+1, m_storage.size( 0 ) ) ];
103  }
104 
106  void pop_front()
107  {
108  GEOS_ERROR_IF( empty(), "Can't pop front from empty queue" );
109  m_begin++;
110  }
111 
113  void pop_back()
114  {
115  GEOS_ERROR_IF( empty(), "Can't pop back from empty queue" );
116  m_end--;
117  }
118 
120  void inc_front()
121  {
122  GEOS_ERROR_IF( full(), "Can't increase in a full queue" );
123  m_begin--;
124  }
125 
127  void inc_back()
128  {
129  GEOS_ERROR_IF( full(), "Can't increase in a full queue" );
130  m_end++;
131  }
132 
139  template< typename INDEX_TYPE2 >
140  camp::resources::Event emplace_front( const LvArray::ArraySlice< T const, 1, 0, INDEX_TYPE2 > & src )
141  {
142  GEOS_ERROR_IF( full(), "Can't emplace in a full queue" );
143  camp::resources::Event e = LvArray::memcpy( m_stream, m_storage[ POSITIVE_MODULO( m_begin-1, m_storage.size( 0 ) ) ], src );
144  --m_begin;
145  return e;
146  }
147 
154  template< typename INDEX_TYPE2 >
155  camp::resources::Event emplace_back( const LvArray::ArraySlice< T const, 1, 0, INDEX_TYPE2 > & src )
156  {
157  GEOS_ERROR_IF( full(), "Can't emplace in a full queue" );
158  camp::resources::Event e = LvArray::memcpy( m_stream, m_storage[ POSITIVE_MODULO( m_end+1, m_storage.size( 0 ) ) ], src );
159  ++m_end;
160  return e;
161 
162  }
163 
169  camp::resources::Resource getStream()
170  {
171  return m_stream;
172  }
173 
174 
175 private:
176  Array2D m_storage;
177  IndexType m_begin = 0;
178  IndexType m_end = -1;
179  camp::resources::Resource m_stream;
180 };
181 }
182 #endif // FIXEDSIZEDEQUE_HPP
#define GEOS_ERROR_IF(EXP, msg)
Conditionally raise a hard error and terminate the program.
Definition: Logger.hpp:107
Implement a double ended queue with fixed number of fixed size buffer to be stored.
camp::resources::Resource getStream()
void inc_front()
Add one array (uninitialized) at the front of the queue.
camp::resources::Event emplace_back(const LvArray::ArraySlice< T const, 1, 0, INDEX_TYPE2 > &src)
size_t capacity() const
ArraySlice1DLarge back() const
ArraySlice1DLarge next_back() const
void inc_back()
Add one array (uninitialized) at the end of the queue.
camp::resources::Event emplace_front(const LvArray::ArraySlice< T const, 1, 0, INDEX_TYPE2 > &src)
ArraySlice1DLarge next_front() const
void pop_back()
Removes last array of the queue.
void pop_front()
Removes first array of the queue.
ArraySlice1DLarge front() const
FixedSizeDeque(IndexType maxEntries, IndexType valuesPerEntry, LvArray::MemorySpace space, camp::resources::Resource stream)
std::size_t size_t
Unsigned size type.
Definition: DataTypes.hpp:119