CS144 Lab1
lab1
这次作业主要完成两个类 StreamReassembler 和 ByteStream。我的思路是每读入数据就O(n)扫一遍,用map维护每个index对应的数据,用一个指针指向当前需要写入值的位置,不断向后移动。原本没深刻认识到overleap的含义,记录的是整串string,然而测试数据相当于把一个字符串随机剁碎,字符串反而不好维护。
这是第三个版本,能过94%,15/16。没过的因为lab0的历史遗留问题,连接CS144官网时会connection reset by peer。
stream_reassembler.hh
#ifndef SPONGE_LIBSPONGE_STREAM_REASSEMBLER_HH
#define SPONGE_LIBSPONGE_STREAM_REASSEMBLER_HH
#include "byte_stream.hh"
#include <cstdint>
#include <climits>
#include <string>
#include <set>
#include <map>
using std::string;
using std::map;
//! \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.
size_t _capacity; //!< The maximum number of bytes
map<size_t,char>store;
ByteStream _output; //!< The reassembled in-order byte stream
size_t reassembleByte = 0;
size_t unAssemble = 0;
int lastIndex = -1;
public:
//! \brief Construct a `StreamReassembler` that will store up to `capacity` bytes.
//! \note This capacity limits both the bytes that have been reassembled,
//! and those that have not yet been reassembled.
StreamReassembler();
StreamReassembler(const size_t capacity);
//! \brief Receives a substring and writes any newly contiguous bytes into the stream.
//!
//! If accepting all the data would overflow the `capacity` of this
//! `StreamReassembler`, then only the part of the data that fits will be
//! accepted. If the substring is only partially accepted, then the `eof`
//! will be disregarded.
//!
//! \param data the string being added
//! \param index the index of the first byte in `data`
//! \param eof whether or not this segment ends with the end of the stream
void push_substring(const std::string &data, const uint64_t index, const bool eof);
//! \name Access the reassembled byte stream
//!@{
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 submitted twice, it
//! should only be counted once for the purpose of this function.
size_t unassembled_bytes() const;
//! \brief Is the internal state empty (other than the output stream)?
//! \returns `true` if no substrings are waiting to be assembled
bool empty() const;
};
#endif // SPONGE_LIBSPONGE_STREAM_REASSEMBLER_HH
stream_reassembler.cc
#include "stream_reassembler.hh"
#include <iostream>
// Dummy implementation of a stream reassembler.
// For Lab 1, please replace with a real implementation that passes the
// automated checks run by `make check_lab1`.
// You will need to add private members to the class declaration in `stream_reassembler.hh`
template <typename... Targs>
void DUMMY_CODE(Targs &&... /* unused */) {}
using namespace std;
/*
size_t _capacity; //!< The maximum number of bytes
set<dataNode>s;
map<size_t,int>submited;
ByteStream _output; //!< The reassembled in-order byte stream
size_t reassembleByte = 0;
bool isEof = false;
*/
StreamReassembler::StreamReassembler(const size_t capacity)
: _capacity(capacity),
store(),
_output(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) {
size_t len = data.length();
for(size_t i = 0;i < len;i++){
if(store.find(index+i) != store.end() ) {}
else store[index+i] = data[i],unAssemble++;
}
if(eof == true) lastIndex = index + len;
while(store.find(reassembleByte) != store.end()){
_output.write(std::string(1,store[reassembleByte]));
unAssemble--;
reassembleByte++;
}
if(lastIndex != -1 && static_cast<int>(reassembleByte) == lastIndex ){
_output.end_input();
}
}
size_t StreamReassembler::unassembled_bytes() const { return unAssemble; }
// myTodo
bool StreamReassembler::empty() const { return unAssemble == 0; }
byte_stream.hh
#ifndef SPONGE_LIBSPONGE_BYTE_STREAM_HH
#define SPONGE_LIBSPONGE_BYTE_STREAM_HH
#include <cstddef>
#include <cstdint>
#include <deque>
#include <list>
#include <string>
#include <utility>
#include <deque>
//! \brief An in-order byte stream.
//! Bytes are written on the "input" side and read from the "output"
//! side. The byte stream is finite: the writer can end the input,
//! and then no more bytes can be written.
class ByteStream {
private:
// Your code here -- add private members as necessary.
size_t capacity;
std::deque<char> buffer;
size_t writtenByte = 0;
size_t readByte = 0;
bool endInput = false;
bool _error{}; //!< Flag indicating that the stream suffered an error.
public:
//! Construct a stream with room for `capacity` bytes.
ByteStream(const size_t capacity);
//! \name "Input" interface for the writer
//!@{
//! Write a string of bytes into the stream. Write as many
//! as will fit, and return how many were written.
//! \returns the number of bytes accepted into the stream
size_t write(const std::string &data);
//! \returns the number of additional bytes that the stream has space for
size_t remaining_capacity() const;
//! Signal that the byte stream has reached its ending
void end_input();
//! Indicate that the stream suffered an error.
void set_error() { _error = true; }
//!@}
//! \name "Output" interface for the reader
//!@{
//! Peek at next "len" bytes of the stream
//! \returns a string
std::string peek_output(const size_t len) const;
//! Remove bytes from the buffer
void pop_output(const size_t len);
//! Read (i.e., copy and then pop) the next "len" bytes of the stream
//! \returns a vector of bytes read
std::string read(const size_t len) {
const auto ret = peek_output(len);
pop_output(len);
return ret;
}
//! \returns `true` if the stream input has ended
bool input_ended() const;
//! \returns `true` if the stream has suffered an error
bool error() const { return _error; }
//! \returns the maximum amount that can currently be read from the stream
size_t buffer_size() const;
//! \returns `true` if the buffer is empty
bool buffer_empty() const;
//! \returns `true` if the output has reached the ending
bool eof() const;
//!@}
//! \name General accounting
//!@{
//! Total number of bytes written
size_t bytes_written() const;
//! Total number of bytes popped
size_t bytes_read() const;
//!@}
};
#endif // SPONGE_LIBSPONGE_BYTE_STREAM_HH
byte_stream.cc
#include "byte_stream.hh"
#include <algorithm>
#include <iterator>
#include <stdexcept>
#include <iostream>
// Dummy implementation of a flow-controlled in-memory byte stream.
// For Lab 0, please replace with a real implementation that passes the
// automated checks run by `make check_lab0`.
// You will need to add private members to the class declaration in `byte_stream.hh`
template <typename... Targs>
void DUMMY_CODE(Targs &&... /* unused */) {}
using namespace std;
ByteStream::ByteStream(const size_t Capacity):capacity(Capacity),buffer(){
}
size_t ByteStream::write(const string &data) {
size_t len = data.length();
size_t bufferLeft = capacity - buffer.size();
size_t i;
for(i = 0;i < len && bufferLeft;i++,bufferLeft--){
writtenByte++;
buffer.push_back(data[i]);
}
return i;
}
//! \param[in] len bytes will be copied from the output side of the buffer
string ByteStream::peek_output(const size_t len) const {
size_t i;
std::string s = "";
for(i = 0;i < min(len,buffer.size());i++){
s.push_back(buffer[i]);
}
return s;
}
//! \param[in] len bytes will be removed from the output side of the buffer
void ByteStream::pop_output(const size_t len) {
size_t i;
for(i = 0;i < len;i++){
readByte++;
buffer.pop_front();
}
}
void ByteStream::end_input() { endInput = true; }
bool ByteStream::input_ended() const { return endInput; }
size_t ByteStream::buffer_size() const { return buffer.size(); }
bool ByteStream::buffer_empty() const { return buffer.empty(); }
bool ByteStream::eof() const { return endInput && buffer.empty(); }
size_t ByteStream::bytes_written() const { return writtenByte; }
size_t ByteStream::bytes_read() const { return readByte; }
size_t ByteStream::remaining_capacity() const { return capacity - buffer.size(); }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了