sorter.h 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. /*
  2. * Tencent is pleased to support the open source community by making wwsearch
  3. * available.
  4. *
  5. * Copyright (C) 2018-present Tencent. All Rights Reserved.
  6. *
  7. * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  8. * use this file except in compliance with the License. You may obtain a copy of
  9. * the License at
  10. *
  11. * https://opensource.org/licenses/Apache-2.0
  12. *
  13. * Unless required by applicable law or agreed to in writing, software
  14. * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  15. * WARRANTIES OF ANY KIND, either express or implied. See the License for the
  16. * specific language governing permissions and limitations under the License.
  17. */
  18. #pragma once
  19. #include "index_field.h"
  20. namespace wwsearch {
  21. enum kSortConditionType { kSortConditionDesc = 1, kSortConditionAsc = 2 };
  22. class SortCondition {
  23. protected:
  24. FieldID field_id_;
  25. kSortConditionType sort_type_;
  26. public:
  27. SortCondition(FieldID field_id, kSortConditionType sort_type)
  28. : field_id_(field_id), sort_type_(sort_type) {}
  29. virtual ~SortCondition() {}
  30. virtual bool Greater(const DocumentID &d1, const IndexField *f1,
  31. const DocumentID &d2, const IndexField *f2) const = 0;
  32. inline FieldID GetID() { return this->field_id_; }
  33. private:
  34. };
  35. // NumericSortCondition
  36. class NumericSortCondition : public SortCondition {
  37. private:
  38. public:
  39. NumericSortCondition(FieldID field_id, kSortConditionType sort_type)
  40. : SortCondition(field_id, sort_type) {}
  41. virtual ~NumericSortCondition() {}
  42. virtual bool Greater(const DocumentID &d1, const IndexField *f1,
  43. const DocumentID &d2, const IndexField *f2) const {
  44. auto ret = InnerGreater(d1, f1, d2, f2);
  45. return (kSortConditionDesc == sort_type_) ? ret : !ret;
  46. }
  47. // have field first
  48. // document id big first
  49. bool InnerGreater(const DocumentID &d1, const IndexField *f1,
  50. const DocumentID &d2, const IndexField *f2) const {
  51. const IndexField *nf1 =
  52. (f1 != nullptr && (f1->FieldType() == kUint32IndexField ||
  53. f1->FieldType() == kUint64IndexField))
  54. ? f1
  55. : nullptr;
  56. const IndexField *nf2 =
  57. (f2 != nullptr && (f2->FieldType() == kUint32IndexField ||
  58. f2->FieldType() == kUint64IndexField))
  59. ? f2
  60. : nullptr;
  61. if (nullptr == nf1 && nullptr == nf2) {
  62. return d1 > d2;
  63. } else if (nullptr == nf1) {
  64. return false;
  65. } else if (nullptr == nf2) {
  66. return true;
  67. }
  68. return nf1->NumericValue() > nf2->NumericValue();
  69. }
  70. private:
  71. };
  72. class StringSortCondition : public SortCondition {
  73. private:
  74. public:
  75. StringSortCondition(FieldID field_id, kSortConditionType sort_type)
  76. : SortCondition(field_id, sort_type) {}
  77. virtual ~StringSortCondition() {}
  78. virtual bool Greater(const DocumentID &d1, const IndexField *f1,
  79. const DocumentID &d2, const IndexField *f2) const {
  80. auto ret = InnerGreater(d1, f1, d2, f2);
  81. return (kSortConditionDesc == sort_type_) ? ret : !ret;
  82. }
  83. // have field first
  84. // document id big first
  85. bool InnerGreater(const DocumentID &d1, const IndexField *f1,
  86. const DocumentID &d2, const IndexField *f2) const {
  87. const IndexField *nf1 =
  88. (f1 != nullptr && f1->FieldType() == kStringIndexField) ? f1 : nullptr;
  89. const IndexField *nf2 =
  90. (f2 != nullptr && f2->FieldType() == kStringIndexField) ? f2 : nullptr;
  91. if (nullptr == nf1 && nullptr == nf2) {
  92. return d1 > d2;
  93. } else if (nullptr == nf1) {
  94. return false;
  95. } else if (nullptr == nf2) {
  96. return true;
  97. }
  98. size_t min_len = (nf1->StringValue().size() < nf2->StringValue().size()
  99. ? nf1->StringValue().size()
  100. : nf2->StringValue().size());
  101. int ret =
  102. memcmp(nf1->StringValue().c_str(), nf2->StringValue().c_str(), min_len);
  103. if (0 == ret) {
  104. return nf1->StringValue().size() > nf2->StringValue().size();
  105. }
  106. return ret > 0;
  107. }
  108. private:
  109. };
  110. class Sorter {
  111. private:
  112. std::vector<SortCondition *> *sort_condictions_;
  113. public:
  114. Sorter(std::vector<SortCondition *> *sort_condictions = nullptr)
  115. : sort_condictions_(sort_condictions) {}
  116. virtual ~Sorter() {}
  117. // do lhs should first pop ?
  118. inline bool operator()(Document *&lhs, Document *&rhs) const {
  119. if (nullptr == sort_condictions_) return lhs->ID() > rhs->ID();
  120. for (auto sc : *sort_condictions_) {
  121. auto lhs_field = lhs->FindField(sc->GetID());
  122. auto rhs_field = rhs->FindField(sc->GetID());
  123. auto c1 = sc->Greater(lhs->ID(), lhs_field, rhs->ID(), rhs_field);
  124. auto c2 = sc->Greater(rhs->ID(), rhs_field, lhs->ID(), lhs_field);
  125. if (c1 && c2) {
  126. continue;
  127. } else if (c1) {
  128. return true;
  129. } else {
  130. return false;
  131. }
  132. }
  133. // default sort
  134. // return lhs->ID() < rhs->ID();
  135. return lhs->ID() > rhs->ID();
  136. }
  137. private:
  138. };
  139. } // namespace wwsearch