Skip to content

Commit

Permalink
lab1. except reuse StreamReassmbler
Browse files Browse the repository at this point in the history
  • Loading branch information
dentiny committed May 17, 2021
1 parent c7bc207 commit 87a2190
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 13 deletions.
2 changes: 1 addition & 1 deletion libsponge/byte_stream.hh
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ class ByteStream {
bool buffer_empty() const { return buffer_size_ == 0; }

//! \returns `true` if the output has reached the ending
bool eof() const { return input_ended_ && buffer_empty(); }
bool eof() const { return input_ended() && buffer_empty(); }
//!@}

//! \name General accounting
Expand Down
57 changes: 52 additions & 5 deletions libsponge/stream_reassembler.cc
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#include "stream_reassembler.hh"

#include <iostream>

// Dummy implementation of a stream reassembler.

// For Lab 1, please replace with a real implementation that passes the
Expand All @@ -12,15 +14,60 @@ void DUMMY_CODE(Targs &&... /* unused */) {}

using namespace std;

StreamReassembler::StreamReassembler(const size_t capacity) : _output(capacity), _capacity(capacity) {}
StreamReassembler::StreamReassembler(const size_t capacity) :
bitmap_(capacity, false),
buffer_(capacity),
unassembled_bytes_(0),
first_unassembled_index_(0),
eof_index_(0),
has_met_eof_(false),
output_(capacity),
capacity_(capacity) {}

//! \details This function accepts a substring (aka a segment) of bytes,
//! possibly out-of-order, from the logical stream, and assembles any newly
//! contiguous substrings and writes them into the output stream in order.
void StreamReassembler::push_substring(const string &data, const size_t index, const bool eof) {
DUMMY_CODE(data, index, eof);
}
// Segment's effective substring index is [start_index, end_index) in total order.
size_t start_index = max(first_unassembled_index_, index);
size_t end_index = min(first_unassembled_index_ + output_.remaining_capacity(), index + data.length());

// Set bitmap and buffer.
for (size_t idx = start_index; idx < end_index; ++idx) {
buffer_[idx] = data[idx - index];
if (!bitmap_[idx]) {
++unassembled_bytes_;
bitmap_[idx] = true;
}
}

// Get the end index of possible submission.
size_t submit_end_index = first_unassembled_index_;
for (; submit_end_index < capacity_ && bitmap_[submit_end_index]; ++submit_end_index);

size_t StreamReassembler::unassembled_bytes() const { return {}; }
cout << "current input substring is " << data << " with index = " << index << endl;
cout << "submit start index = " << first_unassembled_index_ << endl;
cout << "submit end index = " << submit_end_index << endl;

bool StreamReassembler::empty() const { return {}; }
// Submit all possible characters.
if (submit_end_index > first_unassembled_index_) { // there's character to submit
string submit_data(buffer_.begin() + first_unassembled_index_, buffer_.begin() + submit_end_index);
size_t nwrite = output_.write(submit_data);
for (size_t idx = first_unassembled_index_; idx < first_unassembled_index_ + nwrite; ++idx) {
bitmap_[idx] = false;
}
first_unassembled_index_ += nwrite;
unassembled_bytes_ -= nwrite;

cout << "write " << nwrite << " bytes to ByteStream:" << submit_data << endl;
}

// Handle EOF.
if (eof) {
eof_index_ = index + data.length();
has_met_eof_ = true;
}
if (has_met_eof_ && output_.bytes_written() == eof_index_) { // all bytes have been placed into ByteStream
output_.end_input();
}
}
20 changes: 13 additions & 7 deletions libsponge/stream_reassembler.hh
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,22 @@
#include "byte_stream.hh"

#include <cstdint>
#include <map>
#include <string>

//! \brief A class that assembles a series of excerpts from a byte stream (possibly out of order,
//! possibly overlapping) into an in-order byte stream.
class StreamReassembler {
private:
// Your code here -- add private members as necessary.

ByteStream _output; //!< The reassembled in-order byte stream
size_t _capacity; //!< The maximum number of bytes
std::vector<bool> bitmap_; // whether StreamReassembler has received this byte
std::vector<char> buffer_;
size_t unassembled_bytes_;
size_t first_unassembled_index_;
size_t eof_index_;
bool has_met_eof_; // marks the end of ByteStream together with eof_index_
ByteStream output_; //!< The reassembled in-order byte stream
size_t capacity_; //!< The maximum number of bytes

public:
//! \brief Construct a `StreamReassembler` that will store up to `capacity` bytes.
Expand All @@ -33,19 +39,19 @@ class StreamReassembler {

//! \name Access the reassembled byte stream
//!@{
const ByteStream &stream_out() const { return _output; }
ByteStream &stream_out() { return _output; }
const ByteStream &stream_out() const { return output_; }
ByteStream &stream_out() { return output_; }
//!@}

//! The number of bytes in the substrings stored but not yet reassembled
//!
//! \note If the byte at a particular index has been pushed more than once, it
//! should only be counted once for the purpose of this function.
size_t unassembled_bytes() const;
size_t unassembled_bytes() const { return unassembled_bytes_; }

//! \brief Is the internal state empty (other than the output stream)?
//! \returns `true` if no substrings are waiting to be assembled
bool empty() const;
bool empty() const { return unassembled_bytes_ == 0; }
};

#endif // SPONGE_LIBSPONGE_STREAM_REASSEMBLER_HH
11 changes: 11 additions & 0 deletions tests/fsm_stream_reassembler_cap.cc
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ int main() {
test.execute(BytesAvailable("ef"));
}

cout << "testcase1 pass" << endl;

{
ReassemblerTestHarness test{2};

Expand All @@ -44,6 +46,9 @@ int main() {
test.execute(BytesAvailable("cd"));
}

cout << "testcase2 pass" << endl;


{
ReassemblerTestHarness test{1};

Expand All @@ -63,6 +68,9 @@ int main() {
test.execute(BytesAssembled(2));
}

cout << "testcase3 pass" << endl;


{
ReassemblerTestHarness test{3};
for (unsigned int i = 0; i < 99997; i += 3) {
Expand All @@ -73,6 +81,9 @@ int main() {
}
}

cout << "testcase4 pass" << endl;


} catch (const exception &e) {
cerr << "Exception: " << e.what() << endl;
return EXIT_FAILURE;
Expand Down

0 comments on commit 87a2190

Please sign in to comment.