GEOS
FixedSizeDeque.hpp
1 /*
2  * ------------------------------------------------------------------------------------------------------------
3  * SPDX-License-Identifier: LGPL-2.1-only
4  *
5  * Copyright (c) 2016-2024 Lawrence Livermore National Security LLC
6  * Copyright (c) 2018-2024 Total, S.A
7  * Copyright (c) 2018-2024 The Board of Trustees of the Leland Stanford Junior University
8  * Copyright (c) 2023-2024 Chevron
9  * Copyright (c) 2019- GEOS/GEOSX Contributors
10  * All rights reserved
11  *
12  * See top level LICENSE, COPYRIGHT, CONTRIBUTORS, NOTICE, and ACKNOWLEDGEMENTS files for details.
13  * ------------------------------------------------------------------------------------------------------------
14  */
15 
16 #ifndef FIXEDSIZEDEQUE_HPP
17 #define FIXEDSIZEDEQUE_HPP
18 
19 #include "LvArray/src/Array.hpp"
20 #include "LvArray/src/memcpy.hpp"
21 #include "LvArray/src/ChaiBuffer.hpp"
22 #include "common/logger/Logger.hpp"
23 
25 #define POSITIVE_MODULO( a, b ) ( ( ( a ) % ( b ) ) + b ) % ( b )
26 namespace geos
27 {
28 template< typename T, typename INDEX_TYPE >
31 {
33  using IndexType = INDEX_TYPE;
35  using ArraySlice1DLarge = LvArray::ArraySlice< T const, 1, 0, std::ptrdiff_t >;
37  using Array2D = LvArray::Array< T, 2, camp::make_idx_seq_t< 2 >, std::ptrdiff_t, LvArray::ChaiBuffer >;
38 public:
47  FixedSizeDeque( IndexType maxEntries, IndexType valuesPerEntry, LvArray::MemorySpace space, camp::resources::Resource stream ):
48  m_stream( stream )
49  {
50  GEOS_ERROR_IF( maxEntries < 0, "Fixed sized queue size must be positive" );
51  GEOS_ERROR_IF( valuesPerEntry < 0, "Fixed sized queue array size must be positive" );
52  m_storage.resizeWithoutInitializationOrDestruction( space, maxEntries, valuesPerEntry );
53  }
54 
56  bool empty() const
57  {
58  return m_begin > m_end;
59  }
60 
62  bool full() const
63  {
64  return size() == (size_t)m_storage.size( 0 );
65  }
66 
68  size_t size() const
69  {
70  return (size_t)( m_end - m_begin + 1 );
71  }
72 
74  size_t capacity() const
75  {
76  return m_storage.size( 0 );
77  }
78 
80  ArraySlice1DLarge front() const
81  {
82  GEOS_ERROR_IF( empty(), "Can't get front from empty queue" );
83  return m_storage[ POSITIVE_MODULO( m_begin, m_storage.size( 0 ) ) ];
84  }
85 
87  ArraySlice1DLarge next_front() const
88  {
89  GEOS_ERROR_IF( full(), "Can't increase in a full queue" );
90  return m_storage[ POSITIVE_MODULO( m_begin-1, m_storage.size( 0 ) ) ];
91  }
92 
94  ArraySlice1DLarge back() const
95  {
96  GEOS_ERROR_IF( empty(), "Can't get back from empty queue" );
97  return m_storage[ POSITIVE_MODULO( m_end, m_storage.size( 0 ) ) ];
98  }
99 
101  ArraySlice1DLarge next_back() const
102  {
103  GEOS_ERROR_IF( full(), "Can't increase in a full queue" );
104  return m_storage[ POSITIVE_MODULO( m_end+1, m_storage.size( 0 ) ) ];
105  }
106 
108  void pop_front()
109  {
110  GEOS_ERROR_IF( empty(), "Can't pop front from empty queue" );
111  m_begin++;
112  }
113 
115  void pop_back()
116  {
117  GEOS_ERROR_IF( empty(), "Can't pop back from empty queue" );
118  m_end--;
119  }
120 
122  void inc_front()
123  {
124  GEOS_ERROR_IF( full(), "Can't increase in a full queue" );
125  m_begin--;
126  }
127 
129  void inc_back()
130  {
131  GEOS_ERROR_IF( full(), "Can't increase in a full queue" );
132  m_end++;
133  }
134 
141  template< typename INDEX_TYPE2 >
142  camp::resources::Event emplace_front( const LvArray::ArraySlice< T const, 1, 0, INDEX_TYPE2 > & src )
143  {
144  GEOS_ERROR_IF( full(), "Can't emplace in a full queue" );
145  camp::resources::Event e = LvArray::memcpy( m_stream, m_storage[ POSITIVE_MODULO( m_begin-1, m_storage.size( 0 ) ) ], src );
146  --m_begin;
147  return e;
148  }
149 
156  template< typename INDEX_TYPE2 >
157  camp::resources::Event emplace_back( const LvArray::ArraySlice< T const, 1, 0, INDEX_TYPE2 > & src )
158  {
159  GEOS_ERROR_IF( full(), "Can't emplace in a full queue" );
160  camp::resources::Event e = LvArray::memcpy( m_stream, m_storage[ POSITIVE_MODULO( m_end+1, m_storage.size( 0 ) ) ], src );
161  ++m_end;
162  return e;
163 
164  }
165 
171  camp::resources::Resource getStream()
172  {
173  return m_stream;
174  }
175 
176 
177 private:
178  Array2D m_storage;
179  IndexType m_begin = 0;
180  IndexType m_end = -1;
181  camp::resources::Resource m_stream;
182 };
183 }
184 #endif // FIXEDSIZEDEQUE_HPP
#define GEOS_ERROR_IF(EXP, msg)
Conditionally raise a hard error and terminate the program.
Definition: Logger.hpp:142
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:79