Line data Source code
1 : /****************************************************************************** 2 : * 3 : * Project: GDAL 4 : * Purpose: Icechunk driver 5 : * Author: Even Rouault <even dot rouault at spatialys.com> 6 : * 7 : ****************************************************************************** 8 : * Copyright (c) 2026, Even Rouault <even dot rouault at spatialys.com> 9 : * 10 : * SPDX-License-Identifier: MIT 11 : ****************************************************************************/ 12 : 13 : #ifndef ICECHUNKSNAPSHOT_H 14 : #define ICECHUNKSNAPSHOT_H 15 : 16 : #include "icechunkdefs.h" 17 : #include "icechunkfile.h" 18 : 19 : #include "cpl_error.h" 20 : #include "cpl_string.h" 21 : 22 : #include <memory> 23 : #include <string> 24 : #include <utility> 25 : #include <vector> 26 : 27 : namespace gdal::icechunk 28 : { 29 : 30 : /************************************************************************/ 31 : /* IcechunkSnapshot */ 32 : /************************************************************************/ 33 : 34 : /** Instance of https://icechunk.io/en/stable/reference/spec/#snapshot-files 35 : * 36 : * It is thread-safe. 37 : */ 38 6567 : class IcechunkSnapshot final : public IcechunkFile 39 : { 40 : public: 41 : IcechunkSnapshot(); 42 : ~IcechunkSnapshot() override; 43 : 44 : struct ChunkIndexRange 45 : { 46 : const uint32_t from; // inclusive 47 : const uint32_t to; // exclusive 48 : 49 2315 : inline ChunkIndexRange(uint32_t fromIn, uint32_t toIn) 50 2315 : : from(fromIn), to(toIn) 51 : { 52 2315 : } 53 : }; 54 : 55 : struct ManifestRef 56 : { 57 : ObjectId12 manifestId{}; 58 : // Pair [from, to[, along each array dimension 59 : std::vector<ChunkIndexRange> extents{}; 60 : }; 61 : 62 : struct Node 63 : { 64 : ObjectId8 id{}; 65 : std::string path{}; 66 : std::string content{}; 67 : bool isArray = false; 68 : 69 : // Below for arrays only 70 : std::vector<uint32_t> numChunks{}; // along each dimension 71 : std::vector<ManifestRef> manifestRefs{}; 72 : 73 : // Defined as a template to be stripped from non-DEBUG builds 74 : template <class T = void> 75 8088510 : size_t countManifestIdForChunk(const ChunkIdx &anChunkIdx) const 76 : { 77 8088510 : CPLAssert(anChunkIdx.size() == numChunks.size()); 78 : 79 8088510 : size_t counter = 0; 80 16177200 : for (const auto &ref : manifestRefs) 81 : { 82 8088680 : bool match = true; 83 31347500 : for (size_t iDim = 0; iDim < numChunks.size(); ++iDim) 84 : { 85 47223600 : if (anChunkIdx[iDim] < ref.extents[iDim].from || 86 23474900 : anChunkIdx[iDim] >= ref.extents[iDim].to) 87 : { 88 489780 : match = false; 89 489780 : break; 90 : } 91 : } 92 8088680 : if (match) 93 : { 94 7598900 : ++counter; 95 : } 96 : } 97 : 98 8088510 : return counter; 99 : } 100 : 101 : const ObjectId12 * 102 : findManifestIdForChunk(const ChunkIdx &anChunkIdx) const; 103 : }; 104 : 105 : struct ManifestInfo 106 : { 107 : ObjectId12 id{}; 108 : std::string strId{}; 109 : uint64_t sizeBytes = 0; 110 : uint32_t numChunkRefs = 0; 111 : }; 112 : 113 : static std::unique_ptr<IcechunkSnapshot> Open(const char *pszFilename); 114 : 115 3 : inline const std::string &GetCommitMessage() const 116 : { 117 3 : return m_osCommitMessage; 118 : } 119 : 120 : /** Return the t ime at which this snapshot was committed, as non-leap 121 : * microseconds since Jan 1, 1970 UTC. 122 : */ 123 3 : inline uint64_t GetFlushTimestamp() const 124 : { 125 3 : return m_flushTimestamp; 126 : } 127 : 128 136 : size_t GetNodeCount() const 129 : { 130 136 : return m_nodes.size(); 131 : } 132 : 133 8 : const std::vector<Node> &GetNodes() const 134 : { 135 8 : return m_nodes; 136 : } 137 : 138 : const Node *GetNodeFromPath(const std::string &path) const; 139 : 140 : const ManifestInfo *GetManifestInfoFromId(const ObjectId12 &id) const; 141 : 142 : private: 143 : std::string m_osCommitMessage{}; 144 : 145 : // Non-leap microseconds since Jan 1, 1970 UTC. 146 : uint64_t m_flushTimestamp = 0; 147 : 148 : // Elements are sorted according to increasing value of Node::path 149 : std::vector<Node> m_nodes{}; 150 : 151 : // Elements are sorted according to increasing value of ManifestInfo::id 152 : std::vector<ManifestInfo> m_manifestInfos{}; 153 : }; 154 : 155 : } // namespace gdal::icechunk 156 : 157 : #endif