1*8b6cd535SAndroid Build Coastguard Worker // Copyright (C) 2019 Google LLC
2*8b6cd535SAndroid Build Coastguard Worker //
3*8b6cd535SAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License");
4*8b6cd535SAndroid Build Coastguard Worker // you may not use this file except in compliance with the License.
5*8b6cd535SAndroid Build Coastguard Worker // You may obtain a copy of the License at
6*8b6cd535SAndroid Build Coastguard Worker //
7*8b6cd535SAndroid Build Coastguard Worker // http://www.apache.org/licenses/LICENSE-2.0
8*8b6cd535SAndroid Build Coastguard Worker //
9*8b6cd535SAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software
10*8b6cd535SAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS,
11*8b6cd535SAndroid Build Coastguard Worker // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*8b6cd535SAndroid Build Coastguard Worker // See the License for the specific language governing permissions and
13*8b6cd535SAndroid Build Coastguard Worker // limitations under the License.
14*8b6cd535SAndroid Build Coastguard Worker
15*8b6cd535SAndroid Build Coastguard Worker #include "icing/index/term-id-codec.h"
16*8b6cd535SAndroid Build Coastguard Worker
17*8b6cd535SAndroid Build Coastguard Worker #include <cstdint>
18*8b6cd535SAndroid Build Coastguard Worker #include <limits>
19*8b6cd535SAndroid Build Coastguard Worker #include <memory>
20*8b6cd535SAndroid Build Coastguard Worker
21*8b6cd535SAndroid Build Coastguard Worker #include "icing/text_classifier/lib3/utils/base/statusor.h"
22*8b6cd535SAndroid Build Coastguard Worker #include "icing/absl_ports/canonical_errors.h"
23*8b6cd535SAndroid Build Coastguard Worker #include "icing/legacy/core/icing-string-util.h"
24*8b6cd535SAndroid Build Coastguard Worker #include "icing/util/status-macros.h"
25*8b6cd535SAndroid Build Coastguard Worker
26*8b6cd535SAndroid Build Coastguard Worker namespace icing {
27*8b6cd535SAndroid Build Coastguard Worker namespace lib {
28*8b6cd535SAndroid Build Coastguard Worker
Create(uint32_t max_main_tvi,uint32_t max_lite_tvi)29*8b6cd535SAndroid Build Coastguard Worker libtextclassifier3::StatusOr<std::unique_ptr<TermIdCodec>> TermIdCodec::Create(
30*8b6cd535SAndroid Build Coastguard Worker uint32_t max_main_tvi, uint32_t max_lite_tvi) {
31*8b6cd535SAndroid Build Coastguard Worker uint64_t sum =
32*8b6cd535SAndroid Build Coastguard Worker static_cast<uint64_t>(max_main_tvi) + static_cast<uint64_t>(max_lite_tvi);
33*8b6cd535SAndroid Build Coastguard Worker if (sum > std::numeric_limits<uint32_t>::max()) {
34*8b6cd535SAndroid Build Coastguard Worker return absl_ports::InvalidArgumentError(IcingStringUtil::StringPrintf(
35*8b6cd535SAndroid Build Coastguard Worker "Sum of max_main_tvi, %d, and max_lite_tvi, %d must be less than the "
36*8b6cd535SAndroid Build Coastguard Worker "uint32_t max, %d.",
37*8b6cd535SAndroid Build Coastguard Worker max_main_tvi, max_lite_tvi, std::numeric_limits<uint32_t>::max()));
38*8b6cd535SAndroid Build Coastguard Worker }
39*8b6cd535SAndroid Build Coastguard Worker
40*8b6cd535SAndroid Build Coastguard Worker // TODO(cassiewang): When we convert these values to signed ints, we should
41*8b6cd535SAndroid Build Coastguard Worker // check to make sure they're >= 0.
42*8b6cd535SAndroid Build Coastguard Worker
43*8b6cd535SAndroid Build Coastguard Worker return std::unique_ptr<TermIdCodec>(
44*8b6cd535SAndroid Build Coastguard Worker new TermIdCodec(max_main_tvi, max_lite_tvi));
45*8b6cd535SAndroid Build Coastguard Worker }
46*8b6cd535SAndroid Build Coastguard Worker
EncodeTvi(uint32_t tvi,TviType tvi_type) const47*8b6cd535SAndroid Build Coastguard Worker libtextclassifier3::StatusOr<uint32_t> TermIdCodec::EncodeTvi(
48*8b6cd535SAndroid Build Coastguard Worker uint32_t tvi, TviType tvi_type) const {
49*8b6cd535SAndroid Build Coastguard Worker switch (tvi_type) {
50*8b6cd535SAndroid Build Coastguard Worker case TviType::MAIN:
51*8b6cd535SAndroid Build Coastguard Worker if (tvi >= max_main_tvi_) {
52*8b6cd535SAndroid Build Coastguard Worker return absl_ports::InvalidArgumentError(IcingStringUtil::StringPrintf(
53*8b6cd535SAndroid Build Coastguard Worker "Main tvi %d is greater "
54*8b6cd535SAndroid Build Coastguard Worker "than or equal to the max_main_tvi %d",
55*8b6cd535SAndroid Build Coastguard Worker tvi, max_main_tvi_));
56*8b6cd535SAndroid Build Coastguard Worker }
57*8b6cd535SAndroid Build Coastguard Worker return tvi;
58*8b6cd535SAndroid Build Coastguard Worker case TviType::LITE: {
59*8b6cd535SAndroid Build Coastguard Worker if (tvi >= max_lite_tvi_) {
60*8b6cd535SAndroid Build Coastguard Worker return absl_ports::InvalidArgumentError(IcingStringUtil::StringPrintf(
61*8b6cd535SAndroid Build Coastguard Worker "Lite tvi %d is greater "
62*8b6cd535SAndroid Build Coastguard Worker "than or equal to the max_lite_tvi %d",
63*8b6cd535SAndroid Build Coastguard Worker tvi, max_lite_tvi_));
64*8b6cd535SAndroid Build Coastguard Worker }
65*8b6cd535SAndroid Build Coastguard Worker return max_main_tvi_ + tvi;
66*8b6cd535SAndroid Build Coastguard Worker }
67*8b6cd535SAndroid Build Coastguard Worker }
68*8b6cd535SAndroid Build Coastguard Worker }
69*8b6cd535SAndroid Build Coastguard Worker
DecodeTviType(uint32_t term_id) const70*8b6cd535SAndroid Build Coastguard Worker libtextclassifier3::StatusOr<TviType> TermIdCodec::DecodeTviType(
71*8b6cd535SAndroid Build Coastguard Worker uint32_t term_id) const {
72*8b6cd535SAndroid Build Coastguard Worker if (term_id < max_main_tvi_) {
73*8b6cd535SAndroid Build Coastguard Worker return TviType::MAIN;
74*8b6cd535SAndroid Build Coastguard Worker } else if (term_id < max_term_id()) {
75*8b6cd535SAndroid Build Coastguard Worker return TviType::LITE;
76*8b6cd535SAndroid Build Coastguard Worker }
77*8b6cd535SAndroid Build Coastguard Worker return absl_ports::InvalidArgumentError(IcingStringUtil::StringPrintf(
78*8b6cd535SAndroid Build Coastguard Worker "Given TermId %d is greater than or equal to the max TermId %d", term_id,
79*8b6cd535SAndroid Build Coastguard Worker max_term_id()));
80*8b6cd535SAndroid Build Coastguard Worker }
81*8b6cd535SAndroid Build Coastguard Worker
82*8b6cd535SAndroid Build Coastguard Worker libtextclassifier3::StatusOr<TermIdCodec::DecodedTermInfo>
DecodeTermInfo(uint32_t term_id) const83*8b6cd535SAndroid Build Coastguard Worker TermIdCodec::DecodeTermInfo(uint32_t term_id) const {
84*8b6cd535SAndroid Build Coastguard Worker DecodedTermInfo result;
85*8b6cd535SAndroid Build Coastguard Worker ICING_ASSIGN_OR_RETURN(result.tvi_type, DecodeTviType(term_id));
86*8b6cd535SAndroid Build Coastguard Worker switch (result.tvi_type) {
87*8b6cd535SAndroid Build Coastguard Worker case TviType::MAIN:
88*8b6cd535SAndroid Build Coastguard Worker result.tvi = term_id;
89*8b6cd535SAndroid Build Coastguard Worker break;
90*8b6cd535SAndroid Build Coastguard Worker case TviType::LITE:
91*8b6cd535SAndroid Build Coastguard Worker result.tvi = term_id - max_main_tvi_;
92*8b6cd535SAndroid Build Coastguard Worker break;
93*8b6cd535SAndroid Build Coastguard Worker }
94*8b6cd535SAndroid Build Coastguard Worker return result;
95*8b6cd535SAndroid Build Coastguard Worker }
96*8b6cd535SAndroid Build Coastguard Worker
97*8b6cd535SAndroid Build Coastguard Worker } // namespace lib
98*8b6cd535SAndroid Build Coastguard Worker } // namespace icing
99