]>
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); | |
ae9cab37 LS |
37 | if (row && row->table == table && |
38 | ovsdb_condition_match_every_clause(row, cnd)) { | |
f85f8ebb BP |
39 | output_row(row, aux); |
40 | } | |
41 | } else { | |
42 | /* Linear scan. */ | |
43 | const struct ovsdb_row *row, *next; | |
44 | ||
4e8e4213 | 45 | HMAP_FOR_EACH_SAFE (row, next, hmap_node, &table->rows) { |
ae9cab37 LS |
46 | if (ovsdb_condition_match_every_clause(row, cnd) && |
47 | !output_row(row, aux)) { | |
f85f8ebb BP |
48 | break; |
49 | } | |
50 | } | |
51 | } | |
52 | } | |
53 | ||
54 | static bool | |
55 | query_row_set_cb(const struct ovsdb_row *row, void *results_) | |
56 | { | |
57 | struct ovsdb_row_set *results = results_; | |
58 | ovsdb_row_set_add_row(results, row); | |
59 | return true; | |
60 | } | |
61 | ||
62 | void | |
63 | ovsdb_query_row_set(struct ovsdb_table *table, | |
64 | const struct ovsdb_condition *condition, | |
65 | struct ovsdb_row_set *results) | |
66 | { | |
67 | ovsdb_query(table, condition, query_row_set_cb, results); | |
68 | } | |
69 | ||
70 | static bool | |
71 | query_distinct_cb(const struct ovsdb_row *row, void *hash_) | |
72 | { | |
73 | struct ovsdb_row_hash *hash = hash_; | |
74 | ovsdb_row_hash_insert(hash, row); | |
75 | return true; | |
76 | } | |
77 | ||
78 | void | |
79 | ovsdb_query_distinct(struct ovsdb_table *table, | |
80 | const struct ovsdb_condition *condition, | |
81 | const struct ovsdb_column_set *columns, | |
82 | struct ovsdb_row_set *results) | |
83 | { | |
84 | if (!columns || ovsdb_column_set_contains(columns, OVSDB_COL_UUID)) { | |
85 | /* All the result rows are guaranteed to be distinct anyway. */ | |
355ead69 GS |
86 | ovsdb_query_row_set(table, condition, results); |
87 | return; | |
f85f8ebb BP |
88 | } else { |
89 | /* Use hash table to drop duplicates. */ | |
90 | struct ovsdb_row_hash_node *node; | |
91 | struct ovsdb_row_hash hash; | |
92 | ||
93 | ovsdb_row_hash_init(&hash, columns); | |
94 | ovsdb_query(table, condition, query_distinct_cb, &hash); | |
4e8e4213 | 95 | HMAP_FOR_EACH (node, hmap_node, &hash.rows) { |
f85f8ebb BP |
96 | ovsdb_row_set_add_row(results, node->row); |
97 | } | |
98 | ovsdb_row_hash_destroy(&hash, false); | |
99 | } | |
100 | } |