| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #pragma once |
| |
| #include <fmt/format.h> |
| |
| #include <memory> |
| |
| #include "paimon/memory/bytes.h" |
| #include "paimon/predicate/literal.h" |
| #include "paimon/result.h" |
| |
| namespace paimon { |
| |
| class Chunk { |
| public: |
| virtual ~Chunk() = default; |
| |
| virtual Result<bool> TryAdd(const Literal& key) = 0; |
| |
| /// Finds a key within this chunk using binary search. |
| /// |
| /// @param key The key to search for |
| /// @return index of the search key, if it is contained in the chunk; |
| /// otherwise, -(insertion_point + 1). The insertion point |
| /// is defined as the point at which the key would be inserted into the chunk: |
| /// the index of the first element greater than the key, or the chunk's size |
| /// if all elements in the chunk are less than the specified key. Note that |
| /// this guarantees that the return value will be >= 0 if and only if the key is found. |
| virtual Result<int32_t> Find(const Literal& key) { |
| PAIMON_ASSIGN_OR_RAISE(int32_t cmp_with_key, CompareKey(Key(), key)); |
| if (cmp_with_key == 0) { |
| return Code(); |
| } |
| int32_t low = 0; |
| int32_t high = Size() - 1; |
| const int32_t base = Code() + 1; |
| while (low <= high) { |
| const int32_t mid = low + (high - low) / 2; |
| PAIMON_ASSIGN_OR_RAISE(Literal key_at_mid, GetKey(mid)); |
| PAIMON_ASSIGN_OR_RAISE(int32_t cmp, CompareKey(key_at_mid, key)); |
| if (cmp < 0) { |
| low = mid + 1; |
| } else if (cmp > 0) { |
| high = mid - 1; |
| } else { |
| return base + mid; |
| } |
| } |
| return -(base + low + 1); |
| } |
| |
| virtual Result<Literal> Find(int32_t code) { |
| const auto current = Code(); |
| if (current == code) { |
| return Key(); |
| } |
| const auto index = code - current - 1; |
| if (index < 0 || index >= Size()) { |
| return Status::Invalid(fmt::format("Invalid Code: {}", code)); |
| } |
| return GetKey(index); |
| } |
| |
| virtual const Literal& Key() const = 0; |
| |
| virtual int32_t Code() const = 0; |
| |
| virtual int32_t Offset() const = 0; |
| |
| virtual void SetOffset(int32_t offset) = 0; |
| |
| virtual int32_t Size() const = 0; |
| |
| virtual Result<PAIMON_UNIQUE_PTR<Bytes>> SerializeChunk() const = 0; |
| |
| virtual Result<PAIMON_UNIQUE_PTR<Bytes>> SerializeKeys() const = 0; |
| |
| protected: |
| virtual Result<Literal> GetKey(int32_t index) = 0; |
| |
| virtual Result<int32_t> CompareKey(const Literal& lhs, const Literal& rhs) = 0; |
| }; |
| |
| } // namespace paimon |