COROIO: coroio/actors/envelope_reader.hpp Source File
COROIO
Loading...
Searching...
No Matches
envelope_reader.hpp
1#pragma once
2
3#include "actor.hpp"
4#include "queue.hpp"
5#include "intrusive_list.hpp"
6
7#include <deque>
8#include <span>
9#include <list>
10
11namespace NNet {
12namespace NActors {
13
14class TEnvelopeReader {
15public:
16 TEnvelopeReader(size_t unused1 = 0, size_t unused2 = 0) { }
17 void Push(const char* buf, size_t size);
18
19 std::optional<TEnvelope> Pop();
20 bool NeedMoreData() const {
21 return !Messages.empty();
22 }
23 size_t Size() const {
24 return Buffer.size();
25 }
26
27private:
28 void Process();
29
30 bool HasHeader = false;
31 THeader Header;
32 std::queue<TEnvelope> Messages;
33 std::deque<char> Buffer;
34};
35
36class TZeroCopyEnvelopeReader {
37public:
38 // capacity must be a power of two
39 TZeroCopyEnvelopeReader(size_t capacity = 1024, size_t unused = 0);
40 std::span<char> Acquire(size_t size);
41 void Commit(size_t size);
42 std::optional<TEnvelope> Pop();
43 size_t Size() const;
44 bool NeedMoreData() const {
45 return !HasHeader || Size() < Header.Size;
46 }
47
48 // for testing purposes
49 void Push(const char* p, size_t len);
50
51private:
52 void EnsureCapacity(size_t size);
53 template<size_t size>
54 void CopyOut(char* buf);
55 void CopyOut(char* buf, size_t size);
56 void TryReadHeader();
57
58 std::vector<char> Data;
59 size_t Head = 0;
60 size_t Tail = 0;
61 size_t LastIndex = 0;
62
63 bool HasHeader = false;
64 THeader Header;
65};
66
71class TZeroCopyEnvelopeReaderV2 {
72public:
73 TZeroCopyEnvelopeReaderV2(size_t chunkSize = 1024 * 1024, size_t lowWatermark = 64 * 1024);
74
75 std::span<char> Acquire(size_t size);
76 void Commit(size_t size);
77 std::optional<TEnvelope> Pop();
78 size_t Size() const {
79 return CurrentSize;
80 }
81 bool NeedMoreData() const {
82 return !HasHeader || Size() < Header.Size;
83 }
84
85 // for testing purposes
86 void Push(const char* p, size_t len);
87
88 int UsedChunksCount() const {
89 return UsedChunks.Size();
90 }
91
92private:
93 struct TChunk;
94
95 void Rotate();
96 void ReleaseDrained(std::unique_ptr<TChunk> chunk);
97 template<size_t size>
98 bool CopyOut(char* buf);
99 void CopyOut(char* buf, size_t size);
100 TBlob ExtractBlob(TChunk& chunk, size_t size);
101
102 struct TChunk : TIntrusiveListNode<TChunk> {
103 TChunk(size_t size, TZeroCopyEnvelopeReaderV2* parent);
104
105 std::span<char> TryAcquire(size_t size, size_t lowWatermark);
106 std::span<char> Acquire(size_t size);
107 void Commit(size_t size);
108 template<size_t size>
109 bool CopyOut(char* buf);
110 bool CopyOut(char* buf, size_t size);
111 size_t Size() const;
112 void Clear();
113
114 std::vector<char> Data;
115 size_t Head = 0;
116 size_t Tail = 0;
117 int UseCount = 0;
118
119 TZeroCopyEnvelopeReaderV2* Parent = nullptr;
120 };
121
122 const size_t ChunkSize;
123 const size_t LowWatermark;
124 size_t CurrentSize = 0;
125 THeader Header;
126 bool HasHeader = false;
127 std::unique_ptr<TChunk> CurrentChunk;
128 TIntrusiveList<TChunk> SealedChunks;
129 std::vector<std::unique_ptr<TChunk>> FreeChunks;
130 TIntrusiveList<TChunk> UsedChunks;
131};
132
133} // namespace NActors
134} // namespace NNet
Actor system implementation with message passing and behavior support.
Definition intrusive_list.hpp:16
Memory-efficient unbounded queue implementation for actor message passing.
Opaque message payload with Near/Far duality.
Definition messages.hpp:99
Wire header prepended to every remote actor message.
Definition actorid.hpp:98
Definition intrusive_list.hpp:9