cs144:Lab1 流重组器实现过程

1.流重组器作用

在tcp recevier端对接收到的混乱的字节流进行排序并装入实现的byte_stream中

2.总体思路

1 先将接受到的字节流加入 map中去重并且整理好

2 再将已经排过序的也就是_first_unread 的数据一个个写入out_put中

3.实现的方法 

a.使用unordered_map 存储每个char and index的映射关系

b.比较难理解的是map的下标和数据对应关系的判断

c.时刻保证容量的限制不能超过capacity

d.判断eof结束标志位 更新并设置_end_idx=index+sr_written

#include "stream_reassembler.hh"

// 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;

StreamReassembler::StreamReassembler(const size_t capacity) : _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) {
    //明确传入的三个参数含义
    //1.数据 2.数据中第一个字节的在整个字符串的下标 3.是否是最后的字符碎片

    //如果data长度过大 就只能截断超出的部分
    size_t sr_written_len=data.size();
    if(sr_written_len+_map.size()>_capacity){
        sr_written_len=_capacity-_map.size();
    }
    
    if(index+sr_written_len>_first_unasm+_capacity){
        //就是说下标超过接受的最大的限度了 
        //我们只能接受限度以内的
        sr_written_len=_first_unasm+_capacity-index;
    }

    //以上两个判断是为了维护容量地限制
    //如果遇到标识符
    if(eof){
        _eof=true;
        _end_idx=index+sr_written_len;
    }

    //开始将接受到地字节流 加入 _map中
    size_t data_start=0;//从接受到的数据的第data_start位开始读
    //如果接收到的index之前已经有序 那就丢弃
    if(index<_first_unasm){
        data_start=_first_unasm-index;
    }
    //加入map
    for(size_t i=data_start;(i<data_start+sr_written_len)&&(i<data.length());i++){
        _map[i+index]=data[i];
    }
    //尽可能地扩大有序的部分
    while(_map.count(_first_unasm)==1){
        _first_unasm++;//有序部分加加
    }
    //尽可能地将有序部分写入byte_stream
    string str;
    //需要写入的长度
    size_t bs_written_len=_first_unasm-_first_unread;
    //还需要判断此时byte_stream 又没有足够的空间
    if(bs_written_len>_output.remaining_capacity()){
        bs_written_len=_output.remaining_capacity();
    }
    while (bs_written_len>0)
    {
        str.append(1,_map[_first_unread]);
        _map.erase(_first_unread);
        _first_unread++;
        bs_written_len--;
    }
    _output.write(str);
    if(_eof&&_first_unread==_end_idx){
        //结束流
        _output.end_input();
    }

}

size_t StreamReassembler::unassembled_bytes() const { 
    //虽然有序但是方不下了
    size_t asm_bytes_in_map=(_first_unasm-_first_unread);
    return _map.size()-asm_bytes_in_map;
    }

bool StreamReassembler::empty() const { 
    return _map.size()==0&&_output.buffer_empty();
 }
#ifndef SPONGE_LIBSPONGE_STREAM_REASSEMBLER_HH
#define SPONGE_LIBSPONGE_STREAM_REASSEMBLER_HH

#include "byte_stream.hh"
#include <vector>
#include <cstdint>
#include <string>
#include <map>
#include <unordered_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 _first_unread=0;//第一个还未被读取的
    size_t _first_unasm=0;//第一个还未被排序的
    bool _eof=false;//结束标志
    size_t _end_idx=0;//字节流结束的索引
    std::unordered_map<size_t,char> _map{};
    //使用这个来对字节碎片进行重组

    
    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.
    //! \note This capacity limits both the bytes that have been reassembled,
    //! and those that have not yet been reassembled.
    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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值