42 lines
2.7 KiB
Markdown
42 lines
2.7 KiB
Markdown
Lab 1 Writeup
|
||
=============
|
||
|
||
My name: Catfood
|
||
|
||
My SUNet ID: 998244353
|
||
|
||
I collaborated with: An orange cat
|
||
|
||
This lab took me about `3` hours to do.
|
||
|
||
Program Structure and Design of the StreamReassembler:
|
||
|
||
首先写几个 dis-ambiguity
|
||
1. capacity限制:容量限制指的是bytestream.size + aux_storage.size。比较具有迷惑性的是auxiliary storage的容量,这里需要把中间空的字节也算进去,因此就可以简单地计算为`first_unacceptable = first_unread + capacity = first_unassembled + aux_buffer.size()`。形象地理解为类似于一个大的空白数组,往里面填东西,填满了开头的连续部分就push到bytestream里面。
|
||
2. 关于丢弃:这里是以字节为单位的丢弃,而不是以packet为单位,也就是一个string进来,有一部分超出了容量限制,这时候不能直接返回不写入,而是要把不超出限制的部分写进入,剩下的丢掉。
|
||
3. `unassembed_bytes`的计算:这个统计的就是实际收到的但是还没push到字节流的字节,不包括空白。因此需要在接受的时候动态统计。
|
||
4. `EOF`处理:因为可能带EOF的packet先到达,前面还有没收到的部分,因此需要单独记住EOF对应的Index,等push到这个Index的时候,再去调用字节流的`end_input()`。
|
||
|
||
然后简单说一下实现:
|
||
- 数据结构是两个`deque`,一个用来当缓冲区,另一个用来标志是否是收到的字节(这样就不用实现复杂的区间合并了,虽然需要消耗双倍内存)。开头的时候需要重新调整大小,因为可能被read过了。
|
||
- 过程中需要注意各种状态的取值,不要超过容量,也不要出现非法操作(比如取空队列的front,这个好像是个UB)
|
||
- 每次收到数据之后,都处理一下是否能够推进字节流,说明上是这么要求的(“尽快”)
|
||
|
||
最后简单记一下STL中`deque`的一些用法:
|
||
- 初始化:可以用`(size, data)`这样的方式一次性指定初始容量
|
||
- 入队出队:这个容器可以`push/pop_front/back`
|
||
- 调整大小:`resize(newsize, data)`,这个调用的行为符合直觉,data是用来填充的(如果增加了大小);如果减小了大小,那么尾部数据会被扔掉
|
||
===
|
||
Implementation Challenges:
|
||
[主要时间都浪费在了调试各种corner case上面了,感觉要是自己测试根本测不出来,感谢写测试的staff,太强啦]
|
||
|
||
Remaining Bugs:
|
||
无
|
||
|
||
- Optional: I had unexpected difficulty with: [describe]
|
||
|
||
- Optional: I think you could make this lab better by: [describe]
|
||
|
||
- Optional: I was surprised by: [describe]
|
||
|
||
- Optional: I'm not sure about: [万一,eof的地方冲突了咋办?虽然好像可以直接忽略来着] |