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_HIT_DOC_HIT_INFO_H_ 16 #define ICING_INDEX_HIT_DOC_HIT_INFO_H_ 17 18 #include <limits> 19 20 #include "icing/index/hit/hit.h" 21 #include "icing/legacy/core/icing-packed-pod.h" 22 #include "icing/schema/section.h" 23 #include "icing/store/document-id.h" 24 25 namespace icing { 26 namespace lib { 27 28 // DocHitInfo provides a collapsed view of all hits for a specific doc. 29 // Hits contain a document_id, section_id and a term frequency. The 30 // information in multiple hits is collapse into a DocHitInfo by providing a 31 // SectionIdMask of all sections that contained a hit for this term as well as 32 // the highest term frequency of any hit for each section. 33 class DocHitInfo { 34 public: 35 explicit DocHitInfo(DocumentId document_id_in = kInvalidDocumentId, 36 SectionIdMask hit_section_ids_mask = kSectionIdMaskNone) document_id_(document_id_in)37 : document_id_(document_id_in), 38 hit_section_ids_mask_(hit_section_ids_mask) { 39 memset(hit_term_frequency_, Hit::kNoTermFrequency, 40 sizeof(hit_term_frequency_)); 41 } 42 document_id()43 DocumentId document_id() const { return document_id_; } 44 set_document_id(DocumentId document_id)45 void set_document_id(DocumentId document_id) { document_id_ = document_id; } 46 hit_section_ids_mask()47 SectionIdMask hit_section_ids_mask() const { return hit_section_ids_mask_; } 48 set_hit_section_ids_mask(SectionIdMask section_id_mask)49 void set_hit_section_ids_mask(SectionIdMask section_id_mask) { 50 hit_section_ids_mask_ = section_id_mask; 51 } 52 hit_term_frequency(SectionId section_id)53 Hit::TermFrequency hit_term_frequency(SectionId section_id) const { 54 return hit_term_frequency_[section_id]; 55 } 56 57 bool operator<(const DocHitInfo& other) const; 58 bool operator==(const DocHitInfo& other) const { 59 return (*this < other) == (other < *this); 60 } 61 62 // Updates the hit_section_ids_mask and hit_term_frequency for the 63 // section, if necessary. 64 void UpdateSection(SectionId section_id, 65 Hit::TermFrequency hit_term_frequency); 66 67 // Merges the sections of other into this. The hit_section_ids_masks are or'd; 68 // if this.hit_term_frequency_[sectionId] has already been defined, 69 // other.hit_term_frequency_[sectionId] value is ignored. 70 // 71 // This does not affect the DocumentId of this or other. If callers care about 72 // only merging sections for DocHitInfos with the same DocumentId, callers 73 // should check this themselves. 74 void MergeSectionsFrom(const DocHitInfo& other); 75 76 private: 77 DocumentId document_id_; 78 SectionIdMask hit_section_ids_mask_; 79 Hit::TermFrequency hit_term_frequency_[kMaxSectionId + 1]; 80 } __attribute__((packed)); 81 static_assert(sizeof(DocHitInfo) == 22, ""); 82 // TODO(b/138991332) decide how to remove/replace all is_packed_pod assertions. 83 static_assert(icing_is_packed_pod<DocHitInfo>::value, "go/icing-ubsan"); 84 static_assert( 85 sizeof(Hit::TermFrequency) == 1, 86 "Change how hit_term_frequency_ is initialized if changing the type " 87 "of Hit::TermFrequency"); 88 89 } // namespace lib 90 } // namespace icing 91 92 #endif // ICING_INDEX_HIT_DOC_HIT_INFO_H_ 93