Slow distinct() implementation that uses Equal() to compare values in O(n^2).
| 70 | |
| 71 | // Slow distinct() implementation that uses Equal() to compare values in O(n^2). |
| 72 | absl::Status ListDistinctHeterogeneousImpl( |
| 73 | const ListValue& list, |
| 74 | const google::protobuf::DescriptorPool* absl_nonnull descriptor_pool, |
| 75 | google::protobuf::MessageFactory* absl_nonnull message_factory, |
| 76 | google::protobuf::Arena* absl_nonnull arena, ListValueBuilder* absl_nonnull builder, |
| 77 | int64_t start_index = 0, std::vector<Value> seen = {}) { |
| 78 | CEL_ASSIGN_OR_RETURN(size_t size, list.Size()); |
| 79 | for (int64_t i = start_index; i < size; ++i) { |
| 80 | CEL_ASSIGN_OR_RETURN(Value value, |
| 81 | list.Get(i, descriptor_pool, message_factory, arena)); |
| 82 | bool is_distinct = true; |
| 83 | for (const Value& seen_value : seen) { |
| 84 | CEL_ASSIGN_OR_RETURN(Value equal, value.Equal(seen_value, descriptor_pool, |
| 85 | message_factory, arena)); |
| 86 | if (equal.IsTrue()) { |
| 87 | is_distinct = false; |
| 88 | break; |
| 89 | } |
| 90 | } |
| 91 | if (is_distinct) { |
| 92 | seen.push_back(value); |
| 93 | CEL_RETURN_IF_ERROR(builder->Add(value)); |
| 94 | } |
| 95 | } |
| 96 | return absl::OkStatus(); |
| 97 | } |
| 98 | |
| 99 | // Fast distinct() implementation for homogeneous hashable types. Falls back to |
| 100 | // the slow implementation if the list is not actually homogeneous. |
no test coverage detected