1 // Copyright (C) 2019 Google LLC 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #ifndef ICING_INDEX_TERM_ID_HIT_PAIR_H_ 16 #define ICING_INDEX_TERM_ID_HIT_PAIR_H_ 17 18 #include <array> 19 #include <cstdint> 20 21 #include "icing/index/hit/hit.h" 22 23 namespace icing { 24 namespace lib { 25 26 class TermIdHitPair { 27 public: 28 // Layout bits: 24 termid + 32 hit value + 8 hit flags + 8 hit term frequency. 29 using Value = std::array<uint8_t, 9>; 30 31 static constexpr int kTermIdBits = 24; 32 static constexpr int kHitValueBits = sizeof(Hit::Value) * 8; 33 static constexpr int kHitFlagsBits = sizeof(Hit::Flags) * 8; 34 static constexpr int kHitTermFrequencyBits = sizeof(Hit::TermFrequency) * 8; 35 36 static const Value kInvalidValue; 37 value_(v)38 explicit TermIdHitPair(Value v = kInvalidValue) : value_(v) {} 39 TermIdHitPair(uint32_t term_id,const Hit & hit)40 TermIdHitPair(uint32_t term_id, const Hit& hit) { 41 static_assert( 42 kTermIdBits + kHitValueBits + kHitFlagsBits + kHitTermFrequencyBits <= 43 sizeof(Value) * 8, 44 "TermIdHitPairTooBig"); 45 46 // Set termId. Term id takes 3 bytes and goes into value_[0:2] (most 47 // significant bits) because it takes precedent in sorts. 48 value_[0] = static_cast<uint8_t>((term_id >> 16) & 0xff); 49 value_[1] = static_cast<uint8_t>((term_id >> 8) & 0xff); 50 value_[2] = static_cast<uint8_t>((term_id >> 0) & 0xff); 51 52 // Set hit value. Hit value takes 4 bytes and goes into value_[3:6] 53 value_[3] = static_cast<uint8_t>((hit.value() >> 24) & 0xff); 54 value_[4] = static_cast<uint8_t>((hit.value() >> 16) & 0xff); 55 value_[5] = static_cast<uint8_t>((hit.value() >> 8) & 0xff); 56 value_[6] = static_cast<uint8_t>((hit.value() >> 0) & 0xff); 57 58 // Set flags in value_[7]. 59 value_[7] = hit.flags(); 60 61 // Set term-frequency in value_[8] 62 value_[8] = hit.term_frequency(); 63 } 64 term_id()65 uint32_t term_id() const { 66 return (static_cast<uint32_t>(value_[0]) << 16) | 67 (static_cast<uint32_t>(value_[1]) << 8) | 68 (static_cast<uint32_t>(value_[2]) << 0); 69 } 70 hit()71 Hit hit() const { 72 Hit::Value hit_value = (static_cast<uint32_t>(value_[3]) << 24) | 73 (static_cast<uint32_t>(value_[4]) << 16) | 74 (static_cast<uint32_t>(value_[5]) << 8) | 75 (static_cast<uint32_t>(value_[6]) << 0); 76 Hit::Flags hit_flags = value_[7]; 77 Hit::TermFrequency term_frequency = value_[8]; 78 79 return Hit(hit_value, hit_flags, term_frequency); 80 } 81 value()82 const Value& value() const { return value_; } 83 84 bool operator==(const TermIdHitPair& rhs) const { 85 return value_ == rhs.value_; 86 } 87 88 bool operator<(const TermIdHitPair& rhs) const { return value_ < rhs.value_; } 89 90 private: 91 Value value_; 92 }; 93 94 } // namespace lib 95 } // namespace icing 96 97 #endif // ICING_INDEX_TERM_ID_HIT_PAIR_H_ 98