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