// Copyright (C) 2019 Google LLC // // Licensed 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 "icing/index/term-id-codec.h" #include #include #include #include "icing/text_classifier/lib3/utils/base/statusor.h" #include "icing/absl_ports/canonical_errors.h" #include "icing/legacy/core/icing-string-util.h" #include "icing/util/status-macros.h" namespace icing { namespace lib { libtextclassifier3::StatusOr> TermIdCodec::Create( uint32_t max_main_tvi, uint32_t max_lite_tvi) { uint64_t sum = static_cast(max_main_tvi) + static_cast(max_lite_tvi); if (sum > std::numeric_limits::max()) { return absl_ports::InvalidArgumentError(IcingStringUtil::StringPrintf( "Sum of max_main_tvi, %d, and max_lite_tvi, %d must be less than the " "uint32_t max, %d.", max_main_tvi, max_lite_tvi, std::numeric_limits::max())); } // TODO(cassiewang): When we convert these values to signed ints, we should // check to make sure they're >= 0. return std::unique_ptr( new TermIdCodec(max_main_tvi, max_lite_tvi)); } libtextclassifier3::StatusOr TermIdCodec::EncodeTvi( uint32_t tvi, TviType tvi_type) const { switch (tvi_type) { case TviType::MAIN: if (tvi >= max_main_tvi_) { return absl_ports::InvalidArgumentError(IcingStringUtil::StringPrintf( "Main tvi %d is greater " "than or equal to the max_main_tvi %d", tvi, max_main_tvi_)); } return tvi; case TviType::LITE: { if (tvi >= max_lite_tvi_) { return absl_ports::InvalidArgumentError(IcingStringUtil::StringPrintf( "Lite tvi %d is greater " "than or equal to the max_lite_tvi %d", tvi, max_lite_tvi_)); } return max_main_tvi_ + tvi; } } } libtextclassifier3::StatusOr TermIdCodec::DecodeTviType( uint32_t term_id) const { if (term_id < max_main_tvi_) { return TviType::MAIN; } else if (term_id < max_term_id()) { return TviType::LITE; } return absl_ports::InvalidArgumentError(IcingStringUtil::StringPrintf( "Given TermId %d is greater than or equal to the max TermId %d", term_id, max_term_id())); } libtextclassifier3::StatusOr TermIdCodec::DecodeTermInfo(uint32_t term_id) const { DecodedTermInfo result; ICING_ASSIGN_OR_RETURN(result.tvi_type, DecodeTviType(term_id)); switch (result.tvi_type) { case TviType::MAIN: result.tvi = term_id; break; case TviType::LITE: result.tvi = term_id - max_main_tvi_; break; } return result; } } // namespace lib } // namespace icing