-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathCBofCB.cpp
188 lines (164 loc) · 4.16 KB
/
CBofCB.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
//file: CBofCB.cpp
//author: Sean Custer
//date: 9/14/18
//email: [email protected]
//description: source code for circular buffer of circular buffers
#include "CBofCB.h"
#include <iostream>
using namespace std;
CBofCB::CBofCB(){
m_oldest = 0;
m_newest = 0;
m_buffers[0] = new InnerCB();
m_obSize = 1;
}
CBofCB::CBofCB(const CBofCB& other){
m_obSize = other.m_obSize;
m_oldest = other.m_oldest;
m_newest = other.m_newest;
//copy m_buffers using innerCB copy constructor
//regular case
if(m_obSize != 0){
for(int i = m_oldest; i<=m_newest; i++){
int index = i%m_obCapacity;
this->m_buffers[index] = new InnerCB(*other.m_buffers[index]);
}
}
}
CBofCB::~CBofCB(){
for(int i=0; i<m_obSize; i++){
delete m_buffers[i];
}
}
void CBofCB::enqueue(int data){
//Enqueueing to an empty buffer
if(isEmpty() == true){
m_buffers[m_newest]->enqueue(data);
}
//if outer circular buffer is full, throw exception
else if(this->isFull() == true){
throw overflow_error("Outer Circular Buffer is full.");
}
//if m_newest InnerCB is full, create a new InnerCB with double capacity
else if(m_buffers[m_newest]->isFull() && m_newest != m_obCapacity -1){
int n = m_buffers[m_newest]->capacity() * 2;
m_newest++;
m_obSize++;
m_buffers[m_newest] = new InnerCB(n);
m_buffers[m_newest]->enqueue(data);
}
//wrap around case
else if(m_newest == m_obCapacity-1 && m_buffers[m_newest]->isFull() == true
&& m_oldest != 0){
int n = m_buffers[m_newest]->capacity() * 2;
//reset m_newest to beginning of queue
m_newest = 0;
m_obSize++;
m_buffers[m_newest] = new InnerCB(n);
m_buffers[m_newest]->enqueue(data);
}
//regular enqueue
else{
m_buffers[m_newest]->enqueue(data);
}
}
int CBofCB::dequeue(){
int popNum;
//if entire data structure is empty
if(isEmpty()){
throw underflow_error("CBofCB is empty!");
}
//if dequeueing from an empty innerCB that isnt the first one
else if(m_obSize != 1 and (m_buffers[m_oldest]->size() == 1)
and m_oldest != m_obCapacity - 1){
popNum = m_buffers[m_oldest]->dequeue();
delete m_buffers[m_oldest];
m_oldest++;
m_obSize--;
return popNum;
}
//wrap around for dequeue
else if(m_oldest == m_obCapacity - 1 && m_buffers[m_oldest]->size() == 1){
m_obSize--;
popNum = m_buffers[m_oldest]->dequeue();
delete m_buffers[m_oldest];
m_oldest = 0;
return popNum;
}
//regular dequeue
else{
popNum = m_buffers[m_oldest]->dequeue();
return popNum;
}
}
bool CBofCB::isFull(){
if(m_obSize == m_obCapacity){
if(m_buffers[m_oldest]->isFull() && m_buffers[m_newest]->isFull())
return true;
}
return false;
}
bool CBofCB::isEmpty(){
if(size() == 0){
return true;
}
return false;
}
int CBofCB::size(){
int size = 0;
//iterate through the entire data struct
for(int i = m_oldest; i <= m_newest; i++){
int index = i % m_obCapacity;
size += m_buffers[index]->size();
}
return size;
}
const CBofCB& CBofCB::operator=(const CBofCB& rhs){
//check for self assignment
if(this != &rhs){
for(int i = 0; i < m_obSize; i++){
delete m_buffers[i];
m_buffers[i] = NULL;
}
m_obSize = rhs.m_obSize;
m_oldest = rhs.m_oldest;
m_newest = rhs.m_newest;
if(m_obSize != 0){
///copy buffers
for(int i = 0; i == m_obSize; i++){
m_buffers[i] = new InnerCB(*rhs.m_buffers[i]);
}
}
}
return *this;
}
void CBofCB::dump(){
if(this->isEmpty() == true){
throw "Error; Queue is empty!";
}
//standard print through queue
else if(m_oldest <= m_newest){
//if our first ICCB is at the first index, print < m_obSize
if(m_oldest == 0){
for(int i = m_oldest; i <= m_newest; i++){
m_buffers[i]->dump();
}
}
//if our first ICCB is not at our first index, print <= m_obSize
else{
for(int i = m_oldest; i < m_obCapacity; i++){
m_buffers[i]->dump();
}
}
}
//if queue wraps around
else{
//print out from start to end
for(int i = m_oldest; i<m_obCapacity; i++){
m_buffers[i]->dump();
}
for(int i = m_newest; i<m_oldest; i++){
m_buffers[i]->dump();
}
}
}