xref: /aosp_15_r20/external/zstd/contrib/pzstd/SkippableFrame.h (revision 01826a4963a0d8a59bc3812d29bdf0fb76416722)
1*01826a49SYabin Cui /*
2*01826a49SYabin Cui  * Copyright (c) Meta Platforms, Inc. and affiliates.
3*01826a49SYabin Cui  * All rights reserved.
4*01826a49SYabin Cui  *
5*01826a49SYabin Cui  * This source code is licensed under both the BSD-style license (found in the
6*01826a49SYabin Cui  * LICENSE file in the root directory of this source tree) and the GPLv2 (found
7*01826a49SYabin Cui  * in the COPYING file in the root directory of this source tree).
8*01826a49SYabin Cui  */
9*01826a49SYabin Cui #pragma once
10*01826a49SYabin Cui 
11*01826a49SYabin Cui #include "utils/Range.h"
12*01826a49SYabin Cui 
13*01826a49SYabin Cui #include <array>
14*01826a49SYabin Cui #include <cstddef>
15*01826a49SYabin Cui #include <cstdint>
16*01826a49SYabin Cui #include <cstdio>
17*01826a49SYabin Cui 
18*01826a49SYabin Cui namespace pzstd {
19*01826a49SYabin Cui /**
20*01826a49SYabin Cui  * We put a skippable frame before each frame.
21*01826a49SYabin Cui  * It contains a skippable frame magic number, the size of the skippable frame,
22*01826a49SYabin Cui  * and the size of the next frame.
23*01826a49SYabin Cui  * Each skippable frame is exactly 12 bytes in little endian format.
24*01826a49SYabin Cui  * The first 8 bytes are for compatibility with the ZSTD format.
25*01826a49SYabin Cui  * If we have N threads, the output will look like
26*01826a49SYabin Cui  *
27*01826a49SYabin Cui  * [0x184D2A50|4|size1] [frame1 of size size1]
28*01826a49SYabin Cui  * [0x184D2A50|4|size2] [frame2 of size size2]
29*01826a49SYabin Cui  * ...
30*01826a49SYabin Cui  * [0x184D2A50|4|sizeN] [frameN of size sizeN]
31*01826a49SYabin Cui  *
32*01826a49SYabin Cui  * Each sizeX is 4 bytes.
33*01826a49SYabin Cui  *
34*01826a49SYabin Cui  * These skippable frames should allow us to skip through the compressed file
35*01826a49SYabin Cui  * and only load at most N pages.
36*01826a49SYabin Cui  */
37*01826a49SYabin Cui class SkippableFrame {
38*01826a49SYabin Cui  public:
39*01826a49SYabin Cui   static constexpr std::size_t kSize = 12;
40*01826a49SYabin Cui 
41*01826a49SYabin Cui  private:
42*01826a49SYabin Cui   std::uint32_t frameSize_;
43*01826a49SYabin Cui   std::array<std::uint8_t, kSize> data_;
44*01826a49SYabin Cui   static constexpr std::uint32_t kSkippableFrameMagicNumber = 0x184D2A50;
45*01826a49SYabin Cui   // Could be improved if the size fits in less bytes
46*01826a49SYabin Cui   static constexpr std::uint32_t kFrameContentsSize = kSize - 8;
47*01826a49SYabin Cui 
48*01826a49SYabin Cui  public:
49*01826a49SYabin Cui    // Write the skippable frame to data_ in LE format.
50*01826a49SYabin Cui   explicit SkippableFrame(std::uint32_t size);
51*01826a49SYabin Cui 
52*01826a49SYabin Cui   // Read the skippable frame from bytes in LE format.
53*01826a49SYabin Cui   static std::size_t tryRead(ByteRange bytes);
54*01826a49SYabin Cui 
data()55*01826a49SYabin Cui   ByteRange data() const {
56*01826a49SYabin Cui     return {data_.data(), data_.size()};
57*01826a49SYabin Cui   }
58*01826a49SYabin Cui 
59*01826a49SYabin Cui   // Size of the next frame.
frameSize()60*01826a49SYabin Cui   std::size_t frameSize() const {
61*01826a49SYabin Cui     return frameSize_;
62*01826a49SYabin Cui   }
63*01826a49SYabin Cui };
64*01826a49SYabin Cui }
65