Hybrid ICN (hICN) plugin  v21.06-rc0-4-g18fa668
rs.h
1 
2 /*
3  * Copyright (c) 2021 Cisco and/or its affiliates.
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at:
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #pragma once
18 
19 #include <arpa/inet.h>
20 #include <hicn/transport/portability/c_portability.h>
21 #include <hicn/transport/utils/membuf.h>
22 #include <protocols/fec/fec_info.h>
23 #include <protocols/fec_base.h>
24 
25 #include <array>
26 #include <cstdint>
27 #include <map>
28 #include <unordered_set>
29 #include <vector>
30 
31 namespace transport {
32 namespace protocol {
33 
34 namespace fec {
35 
36 #define foreach_rs_fec_type \
37  _(RS, 1, 3) \
38  _(RS, 4, 5) \
39  _(RS, 4, 6) \
40  _(RS, 4, 7) \
41  _(RS, 6, 10) \
42  _(RS, 8, 10) \
43  _(RS, 8, 11) \
44  _(RS, 8, 12) \
45  _(RS, 8, 14) \
46  _(RS, 8, 16) \
47  _(RS, 8, 32) \
48  _(RS, 10, 30) \
49  _(RS, 10, 40) \
50  _(RS, 10, 60) \
51  _(RS, 10, 90) \
52  _(RS, 16, 18) \
53  _(RS, 16, 21) \
54  _(RS, 16, 23) \
55  _(RS, 16, 24) \
56  _(RS, 16, 27) \
57  _(RS, 17, 21) \
58  _(RS, 17, 34) \
59  _(RS, 32, 36) \
60  _(RS, 32, 41) \
61  _(RS, 32, 46) \
62  _(RS, 32, 54) \
63  _(RS, 34, 42) \
64  _(RS, 35, 70) \
65  _(RS, 52, 62)
66 
67 static const constexpr uint16_t MAX_SOURCE_BLOCK_SIZE = 128;
68 
76 using Packets = std::array<std::tuple</* index */ uint32_t, /* buffer */ buffer,
77  uint32_t /* offset */>,
78  MAX_SOURCE_BLOCK_SIZE>;
79 
83 struct fec_header {
87  uint32_t seq_number;
88 
93 
98 
102  uint8_t n_fec_symbols;
103 
107  uint8_t padding;
108 
109  void setSeqNumberBase(uint32_t suffix) { seq_number = htonl(suffix); }
110  uint32_t getSeqNumberBase() { return ntohl(seq_number); }
111  void setEncodedSymbolId(uint8_t esi) { encoded_symbol_id = esi; }
112  uint8_t getEncodedSymbolId() { return encoded_symbol_id; }
113  void setSourceBlockLen(uint8_t k) { source_block_len = k; }
114  uint8_t getSourceBlockLen() { return source_block_len; }
115  void setNFecSymbols(uint8_t n_r) { n_fec_symbols = n_r; }
116  uint8_t getNFecSymbols() { return n_fec_symbols; }
117 };
118 
119 class rs;
120 
124 class BlockCode : public Packets {
129  static constexpr std::size_t LEN_SIZE_BYTES = 2;
130 
131  public:
132  BlockCode(uint32_t k, uint32_t n, uint32_t seq_offset, struct fec_parms *code,
133  rs &params);
134 
138  bool addRepairSymbol(const fec::buffer &packet, uint32_t i,
139  uint32_t offset = 0);
140 
144  bool addSourceSymbol(const fec::buffer &packet, uint32_t i,
145  uint32_t offset = 0);
146 
150  std::size_t length() { return current_block_size_; }
151 
155  uint32_t getN() { return n_; }
156 
160  uint32_t getK() { return k_; }
161 
165  void clear();
166 
167  private:
171  bool addSymbol(const fec::buffer &packet, uint32_t i, uint32_t offset,
172  std::size_t size);
173 
177  void encode();
178 
185  void decode();
186 
187  private:
188  uint32_t k_;
189  uint32_t n_;
190  uint32_t seq_offset_;
191  struct fec_parms *code_;
192  std::size_t max_buffer_size_;
193  std::size_t current_block_size_;
194  std::vector<uint32_t> sorted_index_;
195  bool to_decode_;
196  rs &params_;
197 };
198 
211 class rs : public virtual FECBase {
212  friend class BlockCode;
213 
217  struct MatrixDeleter {
218  void operator()(struct fec_parms *params);
219  };
220 
225  using Matrix = std::unique_ptr<struct fec_parms, MatrixDeleter>;
226 
231  using Code = std::pair<std::uint32_t /* k */, std::uint32_t /* n */>;
232 
236  struct CodeHasher {
237  std::size_t operator()(const Code &code) const {
238  uint64_t ret = uint64_t(code.first) << 32 | uint64_t(code.second);
239  return std::hash<uint64_t>{}(ret);
240  }
241  };
242 
243  protected:
248  using PacketsReady = std::function<void(std::vector<buffer> &)>;
249 
253  using SNBase = std::uint32_t;
254 
260  using SourceBlocks = std::unordered_map<SNBase, BlockCode>;
261 
265  using Codes = std::unordered_map<Code, Matrix, CodeHasher>;
266 
267  public:
268  rs(uint32_t k, uint32_t n, uint32_t seq_offset = 0);
269  ~rs() = default;
270 
271  virtual void clear() { processed_source_blocks_.clear(); }
272 
273  bool isSymbol(uint32_t index) { return ((index - seq_offset_) % n_) >= k_; }
274 
275  private:
279  static Codes createCodes();
280 
281  protected:
282  bool processed(SNBase seq_base) {
283  return processed_source_blocks_.find(seq_base) !=
285  }
286 
287  void setProcessed(SNBase seq_base) {
288  processed_source_blocks_.emplace(seq_base);
289  }
290 
291  std::uint32_t k_;
292  std::uint32_t n_;
293  std::uint32_t seq_offset_;
294 
298  std::unordered_set<SNBase> processed_source_blocks_;
299 
300  static Codes codes_;
301 };
302 
307 class RSEncoder : public rs, public ProducerFEC {
308  public:
309  RSEncoder(uint32_t k, uint32_t n, uint32_t seq_offset = 0);
313  void consume(const fec::buffer &packet, uint32_t index, uint32_t offset = 0);
314 
315  void onPacketProduced(core::ContentObject &content_object,
316  uint32_t offset) override;
317 
321  std::size_t getFecHeaderSize() override { return 0; }
322 
323  void clear() override {
324  rs::clear();
325  source_block_.clear();
326  }
327 
328  void reset() override { clear(); }
329 
330  private:
331  struct fec_parms *current_code_;
337  BlockCode source_block_;
338 };
339 
344 class RSDecoder : public rs, public ConsumerFEC {
345  public:
346  RSDecoder(uint32_t k, uint32_t n, uint32_t seq_offset = 0);
347 
351  void consumeSource(const fec::buffer &packet, uint32_t i,
352  uint32_t offset = 0);
353 
357  void consumeRepair(const fec::buffer &packet, uint32_t offset = 0);
358 
362  void onDataPacket(core::ContentObject &content_object,
363  uint32_t offset) override;
364 
368  std::size_t getFecHeaderSize() override { return 0; }
369 
373  void clear() override {
374  rs::clear();
375  src_blocks_.clear();
376  parked_packets_.clear();
377  }
378 
379  void reset() override { clear(); }
380 
381  private:
382  void recoverPackets(SourceBlocks::iterator &src_block_it);
383 
384  private:
390  SourceBlocks src_blocks_;
391 
401  std::unordered_map<uint32_t, std::vector<std::pair<buffer, uint32_t>>>
402  parked_packets_;
403 };
404 
405 } // namespace fec
406 
407 } // namespace protocol
408 
409 } // namespace transport
transport::protocol::fec::fec_header::source_block_len
uint8_t source_block_len
Definition: rs.h:97
transport::protocol::fec::ProducerFEC
Definition: fec_base.h:77
transport::protocol::fec::RSEncoder::getFecHeaderSize
std::size_t getFecHeaderSize() override
Get the fec header size, if added to source packets.
Definition: rs.h:321
transport::protocol::fec::RSDecoder::consumeSource
void consumeSource(const fec::buffer &packet, uint32_t i, uint32_t offset=0)
transport::protocol::fec::RSEncoder
Definition: rs.h:307
transport::protocol::fec::fec_header::n_fec_symbols
uint8_t n_fec_symbols
Definition: rs.h:102
transport::protocol::fec::fec_header
Definition: rs.h:83
transport::protocol::fec::fec_header::seq_number
uint32_t seq_number
Definition: rs.h:87
transport::protocol::fec::RSEncoder::onPacketProduced
void onPacketProduced(core::ContentObject &content_object, uint32_t offset) override
transport::protocol::fec::RSDecoder::consumeRepair
void consumeRepair(const fec::buffer &packet, uint32_t offset=0)
transport::protocol::fec::BlockCode
Definition: rs.h:124
transport::core::ContentObject
Definition: content_object.h:29
transport::protocol::fec::ConsumerFEC
Definition: fec_base.h:90
transport::protocol::fec::rs::PacketsReady
std::function< void(std::vector< buffer > &)> PacketsReady
Definition: rs.h:248
transport::protocol::fec::fec_header::padding
uint8_t padding
Definition: rs.h:107
transport::protocol::fec::BlockCode::length
std::size_t length()
Definition: rs.h:150
transport::protocol::fec::rs
Definition: rs.h:211
transport::protocol::fec::RSDecoder::onDataPacket
void onDataPacket(core::ContentObject &content_object, uint32_t offset) override
transport::protocol::fec::FECBase
Definition: fec_base.h:31
transport::protocol::fec::BlockCode::clear
void clear()
transport::protocol::fec::BlockCode::getK
uint32_t getK()
Definition: rs.h:160
transport
Definition: forwarder_config.h:32
transport::protocol::fec::fec_header::encoded_symbol_id
uint8_t encoded_symbol_id
Definition: rs.h:92
transport::protocol::fec::RSDecoder
Definition: rs.h:344
transport::protocol::fec::rs::processed_source_blocks_
std::unordered_set< SNBase > processed_source_blocks_
Definition: rs.h:298
transport::protocol::fec::rs::SNBase
std::uint32_t SNBase
Definition: rs.h:253
transport::protocol::fec::rs::SourceBlocks
std::unordered_map< SNBase, BlockCode > SourceBlocks
Definition: rs.h:260
transport::protocol::fec::rs::Codes
std::unordered_map< Code, Matrix, CodeHasher > Codes
Definition: rs.h:265
transport::protocol::fec::RSDecoder::clear
void clear() override
Definition: rs.h:373
transport::protocol::fec::BlockCode::getN
uint32_t getN()
Definition: rs.h:155
fec_parms
Definition: fec.h:53
transport::protocol::fec::BlockCode::addRepairSymbol
bool addRepairSymbol(const fec::buffer &packet, uint32_t i, uint32_t offset=0)
transport::protocol::fec::RSEncoder::consume
void consume(const fec::buffer &packet, uint32_t index, uint32_t offset=0)
transport::protocol::fec::BlockCode::addSourceSymbol
bool addSourceSymbol(const fec::buffer &packet, uint32_t i, uint32_t offset=0)
transport::protocol::fec::RSDecoder::getFecHeaderSize
std::size_t getFecHeaderSize() override
Get the fec header size, if added to source packets.
Definition: rs.h:368