]>
Commit | Line | Data |
---|---|---|
e0edde6f | 1 | /* Copyright (c) 2009, 2010 Nicira, Inc. |
f85f8ebb BP |
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 | ||
16 | #include <config.h> | |
17 | ||
18 | #include "query.h" | |
19 | ||
20 | #include "column.h" | |
21 | #include "condition.h" | |
22 | #include "row.h" | |
23 | #include "table.h" | |
24 | ||
25 | void | |
26 | ovsdb_query(struct ovsdb_table *table, const struct ovsdb_condition *cnd, | |
27 | bool (*output_row)(const struct ovsdb_row *, void *aux), void *aux) | |
28 | { | |
29 | if (cnd->n_clauses > 0 | |
30 | && cnd->clauses[0].column->index == OVSDB_COL_UUID | |
31 | && cnd->clauses[0].function == OVSDB_F_EQ) { | |
32 | /* Optimize the case where the query has a clause of the form "uuid == | |
33 | * <some-uuid>", since we have an index on UUID. */ | |
34 | const struct ovsdb_row *row; | |
35 | ||
36 | row = ovsdb_table_get_row(table, &cnd->clauses[0].arg.keys[0].uuid); | |
37 | if (row && row->table == table && ovsdb_condition_evaluate(row, cnd)) { | |
38 | output_row(row, aux); | |
39 | } | |
40 | } else { | |
41 | /* Linear scan. */ | |
42 | const struct ovsdb_row *row, *next; | |
43 | ||
4e8e4213 | 44 | HMAP_FOR_EACH_SAFE (row, next, hmap_node, &table->rows) { |
f85f8ebb BP |
45 | if (ovsdb_condition_evaluate(row, cnd) && !output_row(row, aux)) { |
46 | break; | |
47 | } | |
48 | } | |
49 | } | |
50 | } | |
51 | ||
52 | static bool | |
53 | query_row_set_cb(const struct ovsdb_row *row, void *results_) | |
54 | { | |
55 | struct ovsdb_row_set *results = results_; | |
56 | ovsdb_row_set_add_row(results, row); | |
57 | return true; | |
58 | } | |
59 | ||
60 | void | |
61 | ovsdb_query_row_set(struct ovsdb_table *table, | |
62 | const struct ovsdb_condition *condition, | |
63 | struct ovsdb_row_set *results) | |
64 | { | |
65 | ovsdb_query(table, condition, query_row_set_cb, results); | |
66 | } | |
67 | ||
68 | static bool | |
69 | query_distinct_cb(const struct ovsdb_row *row, void *hash_) | |
70 | { | |
71 | struct ovsdb_row_hash *hash = hash_; | |
72 | ovsdb_row_hash_insert(hash, row); | |
73 | return true; | |
74 | } | |
75 | ||
76 | void | |
77 | ovsdb_query_distinct(struct ovsdb_table *table, | |
78 | const struct ovsdb_condition *condition, | |
79 | const struct ovsdb_column_set *columns, | |
80 | struct ovsdb_row_set *results) | |
81 | { | |
82 | if (!columns || ovsdb_column_set_contains(columns, OVSDB_COL_UUID)) { | |
83 | /* All the result rows are guaranteed to be distinct anyway. */ | |
84 | return ovsdb_query_row_set(table, condition, results); | |
85 | } else { | |
86 | /* Use hash table to drop duplicates. */ | |
87 | struct ovsdb_row_hash_node *node; | |
88 | struct ovsdb_row_hash hash; | |
89 | ||
90 | ovsdb_row_hash_init(&hash, columns); | |
91 | ovsdb_query(table, condition, query_distinct_cb, &hash); | |
4e8e4213 | 92 | HMAP_FOR_EACH (node, hmap_node, &hash.rows) { |
f85f8ebb BP |
93 | ovsdb_row_set_add_row(results, node->row); |
94 | } | |
95 | ovsdb_row_hash_destroy(&hash, false); | |
96 | } | |
97 | } |