1/**
2 * Copyright 2021 Alibaba, Inc. and its affiliates. All Rights Reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 * \author guonix
17 * \date Nov 2020
18 * \brief
19 */
20
21#include "query_factory.h"
22#include <atomic>
23#include "common/error_code.h"
24#include "common/logger.h"
25#include "equal_query.h"
26#include "knn_query.h"
27#include "meta_wrapper.h"
28
29namespace proxima {
30namespace be {
31namespace query {
32
33namespace {
34
35static uint64_t SequenceTraceId() {
36 static std::atomic<uint64_t> kTraceID(0);
37 return kTraceID++;
38}
39
40/*!
41 * DummyQuery implementation
42 */
43class DummyQuery : public Query {
44 public:
45 //! Destructor
46 ~DummyQuery() override = default;
47
48 public:
49 //! Unique request id, using trace all relevant information
50 uint64_t id() const override {
51 return 0;
52 }
53
54 //! Validate query object, 0 for valid, otherwise non zero returned
55 int validate() const override {
56 return PROXIMA_BE_ERROR_CODE(RuntimeError);
57 }
58
59 //! Retrieve IOMode of query
60 IOMode mode() const override {
61 return IOMode::READONLY;
62 }
63
64 //! Retrieve the type of query, Readonly
65 QueryType type() const override {
66 return QueryType::UNDEFINED;
67 }
68
69 //! Prepare resources, 0 for success, otherwise failed
70 int prepare() override {
71 return PROXIMA_BE_ERROR_CODE(RuntimeError);
72 }
73
74 //! Evaluate query, and collection feedback
75 int evaluate() override {
76 return PROXIMA_BE_ERROR_CODE(RuntimeError);
77 }
78
79 int finalize() override {
80 return PROXIMA_BE_ERROR_CODE(RuntimeError);
81 }
82
83 ProfilerPtr profiler() const override {
84 return nullptr;
85 }
86};
87
88} // namespace
89
90QueryPtr QueryFactory::Create(const proto::QueryRequest *request,
91 index::IndexServicePtr index_service,
92 MetaWrapperPtr meta_service, ExecutorPtr executor,
93 ProfilerPtr profiler,
94 proto::QueryResponse *response) {
95 static QueryPtr kDummyQuery = std::make_shared<DummyQuery>();
96
97 uint64_t trace_id = SequenceTraceId();
98 QueryPtr query = kDummyQuery;
99
100 proto::QueryRequest::QueryType type = request->query_type();
101 LOG_DEBUG("Received request, trace_id[%zu], type[%d]", (size_t)trace_id,
102 type);
103
104 switch (type) {
105 case proto::QueryRequest_QueryType_QT_KNN:
106 query.reset(new (std::nothrow)
107 KNNQuery(trace_id, request, index_service, meta_service,
108 executor, profiler, response));
109 break;
110 default:
111 LOG_ERROR("Ignore unknown query.");
112 break;
113 }
114
115 return query;
116}
117
118//! Factory method, build one Query Object
119QueryPtr QueryFactory::Create(const proto::GetDocumentRequest *request,
120 index::IndexServicePtr index_service,
121 MetaWrapperPtr meta_service, ExecutorPtr executor,
122 ProfilerPtr profiler,
123 proto::GetDocumentResponse *response) {
124 uint64_t trace_id = SequenceTraceId();
125 auto query =
126 std::make_shared<EqualQuery>(trace_id, request, index_service,
127 meta_service, executor, profiler, response);
128 return query;
129}
130
131} // namespace query
132} // namespace be
133} // namespace proxima
134