feisty meow concerns codebase 2.140
span_manager.cpp
Go to the documentation of this file.
1/*****************************************************************************\
2* *
3* Name : span_manager *
4* Author : Chris Koeritz *
5* *
6*******************************************************************************
7* Copyright (c) 1990-$now By Author. This program is free software; you can *
8* redistribute it and/or modify it under the terms of the GNU General Public *
9* License as published by the Free Software Foundation; either version 2 of *
10* the License or (at your option) any later version. This is online at: *
11* http://www.fsf.org/copyleft/gpl.html *
12* Please send any updates to: fred@gruntose.com *
13\*****************************************************************************/
14
15#include "span_manager.h"
16
17#include <basis/functions.h>
18#include <basis/guards.h>
19#include <basis/astring.h>
21#include <structures/set.h>
22
23using namespace basis;
24using namespace structures;
25//using namespace basis;
26
27namespace sockets {
28
30: _implementation(new bit_vector(packs))
31{}
32
34: _implementation(new bit_vector(*to_copy._implementation))
35{}
36
37span_manager::~span_manager() { WHACK(_implementation); }
38
40{
41 if (this == &to_copy) return *this;
42 *_implementation = *to_copy._implementation;
43 return *this;
44}
45
47{ return _implementation->find_first(0); }
48
49void span_manager::reset(int packs) { _implementation->resize(packs); }
50
51const bit_vector &span_manager::vector() const { return *_implementation; }
52
53bit_vector &span_manager::vector() { return *_implementation; }
54
56{
57 int recd_to = _implementation->find_first(0);
58 if (negative(recd_to)) return _implementation->bits() - 1;
59 return recd_to - 1;
60}
61
62void span_manager::make_received_list(int_array &to_make, int max_spans) const
63{
64 to_make.reset(0);
65 int zeros_start_at = _implementation->find_first(0);
66 if (negative(zeros_start_at)) {
67 // all bits are set in the vector, so the whole message is received.
68 to_make.concatenate(0);
69 to_make.concatenate(short(_implementation->bits() - 1));
70 return;
71 }
72 zeros_start_at--;
73 // the sequence of ones ends right before the first zero
74 if (zeros_start_at >= 0) {
75 to_make.concatenate(0);
76 to_make.concatenate(short(zeros_start_at));
77 }
78
79 int ones_to_here; // keeps track of the position of the ones.
80
81 for (int outer_loop = zeros_start_at + 2;
82 outer_loop < _implementation->bits(); ) {
83 // the first zero is zeros_start_at + 1, so we start at the first
84 // unknown bit.
85 if (_implementation->on(outer_loop)) {
86 // the bit is a one, so we are in a one-gathering mode.
87 ones_to_here = outer_loop;
88 int inner_loop = outer_loop + 1;
89 while (inner_loop < _implementation->bits()) {
90 if (_implementation->on(inner_loop)) ones_to_here=inner_loop;
91 else break; // a zero is found at this position, so leave loop.
92 inner_loop++;
93 }
94 // the stretch of ones is entered in the array.
95 to_make.concatenate(short(outer_loop));
96 to_make.concatenate(short(ones_to_here));
97 if ( (max_spans >= 0) && (to_make.length() >= 2 * max_spans) )
98 return;
99 outer_loop = ones_to_here + 1;
100 } else {
101 // the bit is a zero, so we are gathering zeros.
102 int inner_loop = outer_loop + 1;
103 ones_to_here = _implementation->bits();
104 while (inner_loop < _implementation->bits()) {
105 if (!_implementation->on(inner_loop)) inner_loop++;
106 else {
107 // ones_to_here is set to the first position of a one, actually.
108 ones_to_here = inner_loop;
109 break;
110 }
111 }
112 // the loop variable is set to the first unknown position again.
113 outer_loop = ones_to_here;
114 }
115 }
116}
117
118bool span_manager::update(const int_array &new_spans)
119{
120 for (int i = 0; i < new_spans.length(); i += 2) {
121 if ( (new_spans.get(i) >= _implementation->bits())
122 || (new_spans.get(i+1) >= _implementation->bits()) )
123 return false;
124 for (int j = new_spans.get(i); j <= new_spans.get(i+1); j++)
125 _implementation->light(j);
126 }
127 return true;
128}
129
130void span_manager::make_missing_list(int_array &to_make, int max_spans) const
131{
132 to_make.reset(0);
133 int ones_start_at = _implementation->find_first(1);
134 if (negative(ones_start_at)) {
135 // all bits are zero in the vector; no packets have been received.
136 to_make.concatenate(0);
137 to_make.concatenate(short(_implementation->bits() - 1));
138 return;
139 }
140 ones_start_at--;
141 // the sequence of zeros ends right before the first one
142 if (ones_start_at >= 0) {
143 to_make.concatenate(0);
144 to_make.concatenate(short(ones_start_at));
145 }
146
147 int zeros_to_here;
148 for (int outer_loop = ones_start_at + 2;
149 outer_loop < _implementation->bits(); ) {
150 int inner_loop;
151 // the first one is ones_start_at+1, so we start at the first unknown bit
152 if (!_implementation->on(outer_loop)) {
153 // the bit is a zero, so we are in a zero-gathering mode.
154 zeros_to_here = outer_loop;
155 int inner_loop = outer_loop + 1;
156 while (inner_loop < _implementation->bits()) {
157 if (!_implementation->on(inner_loop)) zeros_to_here=inner_loop;
158 else break;
159 // a one is found at this position, so leave loop.
160 inner_loop++;
161 }
162 // the stretch of zeros is entered in the array.
163 to_make.concatenate(short(outer_loop));
164 to_make.concatenate(short(zeros_to_here));
165 if ( (max_spans >= 0) && (to_make.length() >= 2 * max_spans) ) return;
166 outer_loop = zeros_to_here + 1;
167 } else {
168 // the bit is a one, so we are gathering ones.
169 inner_loop = outer_loop + 1;
170 zeros_to_here = _implementation->bits();
171 while (inner_loop < _implementation->bits()) {
172 if (_implementation->on(inner_loop))
173 inner_loop++;
174 else {
175 // zeros_to_here is set to the first position of a zero, actually.
176 zeros_to_here = inner_loop;
177 break;
178 }
179 }
180 // the loop variable is set to the first unknown position again.
181 outer_loop = zeros_to_here;
182 }
183 }
184}
185
186astring span_manager::funky_print(const int_array &to_spew, int rec_seq) const
187{
188 astring to_return(astring::SPRINTF, "through %d, [", rec_seq);
189 for (int i = 0; i < to_spew.length(); i += 2) {
190 to_return += astring(astring::SPRINTF, " %d-%d", to_spew.get(i),
191 to_spew.get(i+1));
192 }
193 to_return += astring(" ] ");
194 return to_return;
195}
196
198{
199 int_array hold_info;
200 make_received_list(hold_info);
201 astring to_return("received ");
202 to_return += funky_print(hold_info, received_sequence());
203 return to_return;
204}
205
207{
208 int_array hold_info;
209 make_missing_list(hold_info);
210 astring to_return("missing ");
211 to_return += funky_print(hold_info, received_sequence());
212 return to_return;
213}
214
215} //namespace.
216
void reset(int number=0, const contents *initial_contents=NULL_POINTER)
Resizes this array and sets the contents from an array of contents.
Definition array.h:349
array & concatenate(const array &to_concatenate)
Appends the array "to_concatenate" onto "this" and returns "this".
Definition array.h:379
const contents & get(int index) const
Accesses individual objects stored in "this" at the "index" position.
Definition array.h:372
int length() const
Returns the current reported length of the allocated C array.
Definition array.h:115
Provides a dynamically resizable ASCII character string.
Definition astring.h:35
A simple object that wraps a templated array of ints.
Definition array.h:275
Manages lists of numbers representing the completion of some activity.
bool update(const basis::int_array &new_spans)
updates the span information.
int received_sequence() const
returns the highest chunk number at which all chunks are ready.
const structures::bit_vector & vector() const
observes the held bit_vector that represents the spans.
void make_missing_list(basis::int_array &spans, int max_spans=-1) const
creates a list representing the spans that are not ready yet.
void make_received_list(basis::int_array &spans, int max_spans=-1) const
Creates a list for the received spans that are ready.
span_manager(int number_of_items)
span_manager & operator=(const span_manager &to_copy)
basis::astring print_received_list() const
prints out the span list for received blocks into a string.
basis::astring print_missing_list() const
prints out the span list for missing blocks into a string.
void reset(int number_of_items)
sets up the span manager with a new configuration.
int missing_sequence() const
returns the number of the chunk where the first item is missing.
An array of bits with operations for manipulating and querying individual bits.
Definition bit_vector.h:26
bool on(int position) const
returns true if the bit at "position" is set.
int find_first(bool to_find) const
Seeks the first occurrence of "to_find".
int bits() const
returns the number of bits in the vector.
void light(int position)
sets the value of the bit at "position".
void resize(int size)
Changes the size of the bit_vector to "size" bits.
The guards collection helps in testing preconditions and reporting errors.
Definition array.h:30
void WHACK(contents *&ptr)
deletion with clearing of the pointer.
Definition functions.h:121
bool negative(const type &a)
negative returns true if "a" is less than zero.
Definition functions.h:43
Provides access to the operating system's socket methods.
A dynamic container class that holds any kind of object via pointers.
Definition amorph.h:55