blob: 09c758636d58ec17f3a7ebbe1dcf224aacb65d06 [file] [log] [blame]
// 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.
#include "olap/short_key_index.h"
#include <gen_cpp/segment_v2.pb.h>
#include <ostream>
#include "common/cast_set.h"
#include "short_key_index.h"
#include "util/bvar_helper.h"
#include "util/coding.h"
namespace doris {
#include "common/compile_check_begin.h"
static bvar::Adder<size_t> g_short_key_index_memory_bytes("doris_short_key_index_memory_bytes");
Status ShortKeyIndexBuilder::add_item(const Slice& key) {
put_varint32(&_offset_buf, cast_set<uint32_t>(_key_buf.size()));
_key_buf.append(key.data, key.size);
_num_items++;
return Status::OK();
}
Status ShortKeyIndexBuilder::finalize(uint32_t num_segment_rows, std::vector<Slice>* body,
segment_v2::PageFooterPB* page_footer) {
page_footer->set_type(segment_v2::SHORT_KEY_PAGE);
page_footer->set_uncompressed_size(cast_set<uint32_t>(_key_buf.size() + _offset_buf.size()));
segment_v2::ShortKeyFooterPB* footer = page_footer->mutable_short_key_page_footer();
footer->set_num_items(_num_items);
footer->set_key_bytes(cast_set<uint32_t>(_key_buf.size()));
footer->set_offset_bytes(cast_set<uint32_t>(_offset_buf.size()));
footer->set_segment_id(_segment_id);
footer->set_num_rows_per_block(_num_rows_per_block);
footer->set_num_segment_rows(num_segment_rows);
body->emplace_back(_key_buf);
body->emplace_back(_offset_buf);
return Status::OK();
}
Status ShortKeyIndexDecoder::parse(const Slice& body, const segment_v2::ShortKeyFooterPB& footer) {
_footer = footer;
// check if body size match footer's information
if (body.size != (_footer.key_bytes() + _footer.offset_bytes())) {
return Status::Corruption("Index size not match, need={}, real={}",
_footer.key_bytes() + _footer.offset_bytes(), body.size);
}
// set index buffer
_key_data = Slice(body.data, _footer.key_bytes());
// parse offset information
Slice offset_slice(body.data + _footer.key_bytes(), _footer.offset_bytes());
// +1 for record total length
_offsets.resize(_footer.num_items() + 1);
for (uint32_t i = 0; i < _footer.num_items(); ++i) {
uint32_t offset = 0;
if (!get_varint32(&offset_slice, &offset)) {
return Status::Corruption("Fail to get varint from index offset buffer");
}
DCHECK(offset <= _footer.key_bytes())
<< "Offset is larger than total bytes, offset=" << offset
<< ", key_bytes=" << _footer.key_bytes();
_offsets[i] = offset;
}
_offsets[_footer.num_items()] = _footer.key_bytes();
if (offset_slice.size != 0) {
return Status::Corruption("Still has data after parse all key offset");
}
_parsed = true;
g_short_key_index_memory_bytes << sizeof(_footer) + _key_data.size +
_offsets.size() * sizeof(uint32_t) + sizeof(*this);
return Status::OK();
}
ShortKeyIndexDecoder::~ShortKeyIndexDecoder() {
if (_parsed) {
g_short_key_index_memory_bytes << -sizeof(_footer) - _key_data.size -
_offsets.size() * sizeof(uint32_t) -
sizeof(*this);
}
}
#include "common/compile_check_end.h"
} // namespace doris