Skip to content

Commit ba013b4

Browse files
authored
feat: add index file metadata and handler infrastructure (#78)
1 parent 4d1c320 commit ba013b4

18 files changed

Lines changed: 1851 additions & 0 deletions
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
#pragma once
21+
22+
#include <cstdint>
23+
#include <memory>
24+
#include <optional>
25+
#include <string>
26+
#include <vector>
27+
28+
#include "arrow/api.h"
29+
#include "fmt/core.h"
30+
#include "fmt/format.h"
31+
32+
namespace paimon {
33+
/// Indicates the deletion vector info of member data_file_name, e.g., the length of dv.
34+
/// * DeletionVectorMeta is used when serialize to manifest file.
35+
class DeletionVectorMeta {
36+
public:
37+
static const std::shared_ptr<arrow::DataType>& DataType() {
38+
static std::shared_ptr<arrow::DataType> schema = arrow::struct_(
39+
{arrow::field("f0", arrow::utf8(), false), arrow::field("f1", arrow::int32(), false),
40+
arrow::field("f2", arrow::int32(), false),
41+
arrow::field("_CARDINALITY", arrow::int64(), true)});
42+
return schema;
43+
}
44+
DeletionVectorMeta(const std::string& data_file_name, int32_t offset, int32_t length,
45+
const std::optional<int64_t>& cardinality)
46+
: data_file_name_(data_file_name),
47+
offset_(offset),
48+
length_(length),
49+
cardinality_(cardinality) {}
50+
51+
bool operator==(const DeletionVectorMeta& other) const {
52+
if (this == &other) {
53+
return true;
54+
}
55+
return data_file_name_ == other.data_file_name_ && offset_ == other.offset_ &&
56+
length_ == other.length_ && cardinality_ == other.cardinality_;
57+
}
58+
59+
bool TEST_Equal(const DeletionVectorMeta& other) const {
60+
if (this == &other) {
61+
return true;
62+
}
63+
// ignore data_file_name
64+
return offset_ == other.offset_ && length_ == other.length_ &&
65+
cardinality_ == other.cardinality_;
66+
}
67+
68+
std::string ToString() const {
69+
return fmt::format(
70+
"DeletionVectorMeta{{data_file_name = {}, offset = {}, length = {}, cardinality = {}}}",
71+
data_file_name_, offset_, length_,
72+
cardinality_ == std::nullopt ? "null" : std::to_string(cardinality_.value()));
73+
}
74+
75+
const std::string& GetDataFileName() const {
76+
return data_file_name_;
77+
}
78+
79+
int32_t GetOffset() const {
80+
return offset_;
81+
}
82+
83+
int32_t GetLength() const {
84+
return length_;
85+
}
86+
87+
std::optional<int64_t> GetCardinality() const {
88+
return cardinality_;
89+
}
90+
91+
private:
92+
std::string data_file_name_;
93+
int32_t offset_;
94+
int32_t length_;
95+
std::optional<int64_t> cardinality_;
96+
};
97+
} // namespace paimon
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
#include "paimon/core/index/deletion_vector_meta.h"
21+
22+
#include "gtest/gtest.h"
23+
24+
namespace paimon::test {
25+
TEST(DeletionVectorMetaTest, EqualityOperator) {
26+
DeletionVectorMeta meta1("file1", 0, 100, 1000);
27+
DeletionVectorMeta meta2("file1", 0, 100, 1000);
28+
DeletionVectorMeta meta3("file2", 0, 100, 1000);
29+
30+
EXPECT_TRUE(meta1 == meta2);
31+
EXPECT_FALSE(meta1 == meta3);
32+
}
33+
34+
TEST(DeletionVectorMetaTest, ToString) {
35+
DeletionVectorMeta meta("file1", 0, 100, 1000);
36+
std::string expected =
37+
"DeletionVectorMeta{data_file_name = file1, offset = 0, length = 100, cardinality = 1000}";
38+
EXPECT_EQ(meta.ToString(), expected);
39+
40+
DeletionVectorMeta meta_null("file1", 0, 100, std::nullopt);
41+
expected =
42+
"DeletionVectorMeta{data_file_name = file1, offset = 0, length = 100, cardinality = null}";
43+
EXPECT_EQ(meta_null.ToString(), expected);
44+
}
45+
46+
} // namespace paimon::test
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
#include "paimon/core/index/global_index_meta.h"
21+
22+
#include <memory>
23+
#include <string>
24+
#include <vector>
25+
26+
#include "fmt/format.h"
27+
#include "fmt/ranges.h"
28+
#include "paimon/common/data/binary_array.h"
29+
#include "paimon/common/data/binary_row_writer.h"
30+
31+
namespace paimon {
32+
GlobalIndexMeta::GlobalIndexMeta(int64_t _row_range_start, int64_t _row_range_end,
33+
int32_t _index_field_id,
34+
const std::optional<std::vector<int32_t>>& _extra_field_ids,
35+
const std::shared_ptr<Bytes>& _index_meta)
36+
: row_range_start(_row_range_start),
37+
row_range_end(_row_range_end),
38+
index_field_id(_index_field_id),
39+
extra_field_ids(_extra_field_ids),
40+
index_meta(_index_meta) {}
41+
42+
bool GlobalIndexMeta::operator==(const GlobalIndexMeta& other) const {
43+
if (this == &other) {
44+
return true;
45+
}
46+
if ((index_meta && !other.index_meta) || (!index_meta && other.index_meta)) {
47+
return false;
48+
}
49+
if (index_meta && other.index_meta && !(*index_meta == *other.index_meta)) {
50+
return false;
51+
}
52+
return row_range_start == other.row_range_start && row_range_end == other.row_range_end &&
53+
index_field_id == other.index_field_id && extra_field_ids == other.extra_field_ids;
54+
}
55+
56+
std::string GlobalIndexMeta::ToString() const {
57+
std::string extra_field_ids_str =
58+
extra_field_ids == std::nullopt
59+
? "null"
60+
: fmt::format("{}", fmt::join(extra_field_ids.value(), ", "));
61+
62+
std::string index_meta_str =
63+
index_meta == nullptr ? "null" : std::string(index_meta->data(), index_meta->size());
64+
return fmt::format(
65+
"{{row_range_start={}, row_range_end={}, index_field_id={}, extra_field_ids={}, "
66+
"index_meta={}}}",
67+
row_range_start, row_range_end, index_field_id, extra_field_ids_str, index_meta_str);
68+
}
69+
70+
BinaryRow GlobalIndexMeta::ToRow(MemoryPool* pool) const {
71+
BinaryRow row(5);
72+
BinaryRowWriter writer(&row, 32 * 1024, pool);
73+
writer.WriteLong(0, row_range_start);
74+
writer.WriteLong(1, row_range_end);
75+
writer.WriteInt(2, index_field_id);
76+
if (!extra_field_ids) {
77+
writer.SetNullAt(3);
78+
} else {
79+
writer.WriteArray(3, BinaryArray::FromIntArray(extra_field_ids.value(), pool));
80+
}
81+
if (index_meta == nullptr) {
82+
writer.SetNullAt(4);
83+
} else {
84+
writer.WriteBinary(4, *index_meta);
85+
}
86+
writer.Complete();
87+
return row;
88+
}
89+
90+
Result<GlobalIndexMeta> GlobalIndexMeta::FromRow(const InternalRow& row) {
91+
int64_t row_range_start = row.GetLong(0);
92+
int64_t row_range_end = row.GetLong(1);
93+
int32_t index_field_id = row.GetInt(2);
94+
std::optional<std::vector<int32_t>> extra_field_ids;
95+
if (!row.IsNullAt(3)) {
96+
std::shared_ptr<InternalArray> array = row.GetArray(3);
97+
if (!array) {
98+
return Status::Invalid("GlobalIndexMeta FromRow failed with nullptr extra field ids");
99+
}
100+
PAIMON_ASSIGN_OR_RAISE(extra_field_ids, array->ToIntArray());
101+
}
102+
std::shared_ptr<Bytes> index_meta;
103+
if (!row.IsNullAt(4)) {
104+
index_meta = row.GetBinary(4);
105+
assert(index_meta);
106+
}
107+
return GlobalIndexMeta(row_range_start, row_range_end, index_field_id, extra_field_ids,
108+
index_meta);
109+
}
110+
111+
const std::shared_ptr<arrow::DataType>& GlobalIndexMeta::DataType() {
112+
static std::shared_ptr<arrow::DataType> schema = arrow::struct_({
113+
arrow::field("_ROW_RANGE_START", arrow::int64(), /*nullable=*/false),
114+
arrow::field("_ROW_RANGE_END", arrow::int64(), /*nullable=*/false),
115+
arrow::field("_INDEX_FIELD_ID", arrow::int32(), /*nullable=*/false),
116+
arrow::field("_EXTRA_FIELD_IDS",
117+
arrow::list(arrow::field("item", arrow::int32(), /*nullable=*/false)),
118+
/*nullable=*/true),
119+
arrow::field("_INDEX_META", arrow::binary(), /*nullable=*/true),
120+
});
121+
return schema;
122+
}
123+
124+
} // namespace paimon
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
#pragma once
21+
22+
#include <memory>
23+
#include <optional>
24+
#include <string>
25+
#include <vector>
26+
27+
#include "arrow/api.h"
28+
#include "fmt/format.h"
29+
#include "paimon/common/data/binary_row.h"
30+
#include "paimon/memory/bytes.h"
31+
namespace paimon {
32+
/// Schema for global index.
33+
struct GlobalIndexMeta {
34+
static constexpr int32_t NUM_FIELDS = 5;
35+
36+
GlobalIndexMeta(int64_t _row_range_start, int64_t _row_range_end, int32_t _index_field_id,
37+
const std::optional<std::vector<int32_t>>& _extra_field_ids,
38+
const std::shared_ptr<Bytes>& _index_meta);
39+
40+
bool operator==(const GlobalIndexMeta& other) const;
41+
42+
std::string ToString() const;
43+
44+
BinaryRow ToRow(MemoryPool* pool) const;
45+
46+
static Result<GlobalIndexMeta> FromRow(const InternalRow& row);
47+
48+
static const std::shared_ptr<arrow::DataType>& DataType();
49+
50+
int64_t row_range_start;
51+
int64_t row_range_end;
52+
int32_t index_field_id;
53+
std::optional<std::vector<int32_t>> extra_field_ids;
54+
std::shared_ptr<Bytes> index_meta;
55+
};
56+
57+
} // namespace paimon

0 commit comments

Comments
 (0)