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