Skip to content

Commit 27dddd4

Browse files
committed
per-thread kv table
alternate setstr (still in code) use ptkv_set and ptkv_get can get and set in the same query can also directly get values using SELECT value from PER_THREAD_KV WHERE key == 'key';
1 parent 1ce739b commit 27dddd4

File tree

7 files changed

+370
-3
lines changed

7 files changed

+370
-3
lines changed

include/gufi_query/per_thread_kv.h

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
/*
2+
This file is part of GUFI, which is part of MarFS, which is released
3+
under the BSD license.
4+
5+
6+
Copyright (c) 2017, Los Alamos National Security (LANS), LLC
7+
All rights reserved.
8+
9+
Redistribution and use in source and binary forms, with or without modification,
10+
are permitted provided that the following conditions are met:
11+
12+
1. Redistributions of source code must retain the above copyright notice, this
13+
list of conditions and the following disclaimer.
14+
15+
2. Redistributions in binary form must reproduce the above copyright notice,
16+
this list of conditions and the following disclaimer in the documentation and/or
17+
other materials provided with the distribution.
18+
19+
3. Neither the name of the copyright holder nor the names of its contributors
20+
may be used to endorse or promote products derived from this software without
21+
specific prior written permission.
22+
23+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
24+
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25+
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26+
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
27+
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
28+
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29+
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30+
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
31+
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
32+
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33+
34+
35+
From Los Alamos National Security, LLC:
36+
LA-CC-15-039
37+
38+
Copyright (c) 2017, Los Alamos National Security, LLC All rights reserved.
39+
Copyright 2017. Los Alamos National Security, LLC. This software was produced
40+
under U.S. Government contract DE-AC52-06NA25396 for Los Alamos National
41+
Laboratory (LANL), which is operated by Los Alamos National Security, LLC for
42+
the U.S. Department of Energy. The U.S. Government has rights to use,
43+
reproduce, and distribute this software. NEITHER THE GOVERNMENT NOR LOS
44+
ALAMOS NATIONAL SECURITY, LLC MAKES ANY WARRANTY, EXPRESS OR IMPLIED, OR
45+
ASSUMES ANY LIABILITY FOR THE USE OF THIS SOFTWARE. If software is
46+
modified to produce derivative works, such modified software should be
47+
clearly marked, so as not to confuse it with the version available from
48+
LANL.
49+
50+
THIS SOFTWARE IS PROVIDED BY LOS ALAMOS NATIONAL SECURITY, LLC AND CONTRIBUTORS
51+
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
52+
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
53+
ARE DISCLAIMED. IN NO EVENT SHALL LOS ALAMOS NATIONAL SECURITY, LLC OR
54+
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
55+
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
56+
OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
57+
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
58+
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
59+
IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
60+
OF SUCH DAMAGE.
61+
*/
62+
63+
64+
65+
#ifndef GUFI_QUERY_PER_THREAD_KV_H
66+
#define GUFI_QUERY_PER_THREAD_KV_H
67+
68+
#include "dbutils.h"
69+
#include "str.h"
70+
71+
/*
72+
* This is a wrapper around a simple key value table accessible on a
73+
* per-thread basis.
74+
*
75+
* CREATE TABLE temp.PER_THREAD_KV(key PRIMARY KEY TEXT, value TEXT);
76+
*
77+
* ptkv_set and ptkv_get are wrappers for
78+
* DELETE FROM PER_THREAD_KV WHERE key == 'key'; INSERT INTO PER_THREAD_KV VALUES (key, value);
79+
* and
80+
* SELECT value FROM PER_THREAD_KV WHERE key == 'key';
81+
* respectively.
82+
*
83+
* These functions exist to simplify storing state, with the trade-off
84+
* being extra memory copies in and out of sqlite3.
85+
*/
86+
87+
int ptkv_init(sqlite3 *db);
88+
void ptkv_set(sqlite3_context *context, int argc, sqlite3_value **argv);
89+
int ptkv_set_internal(const size_t tid, sqlite3 *db,
90+
const char *key, const size_t key_len,
91+
const refstr_t *val);
92+
void ptkv_get(sqlite3_context *context, int argc, sqlite3_value **argv);
93+
void ptkv_fini(sqlite3 *db);
94+
95+
#endif

src/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,7 @@ add_library(gufi_query_lib OBJECT
185185
gufi_query/external.c
186186
gufi_query/gqw.c
187187
gufi_query/handle_sql.c
188+
gufi_query/per_thread_kv.c
188189
gufi_query/process_queries.c
189190
gufi_query/processdir.c
190191
gufi_query/query.c

src/gufi_query/PoolArgs.c

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ OF SUCH DAMAGE.
7272

7373
#include "gufi_query/PoolArgs.h"
7474
#include "gufi_query/external.h"
75+
#include "gufi_query/per_thread_kv.h"
7576

7677
/* don't introduce undefined behavior by casting function when passing into trie_insert */
7778
static void str_free_wrapper(void *str) {
@@ -159,9 +160,9 @@ int PoolArgs_init(PoolArgs_t *pa, struct input *in, pthread_mutex_t *global_mute
159160
ta->user_strs = trie_alloc();
160161

161162
/*
162-
* {s} defaults to the source tree path - can change, but generally do not
163+
* {s} defaults to the source tree path - can change, but generally will not
163164
*
164-
* maybe move this into processdir?
165+
* maybe move this into processdir to reset the value every time?
165166
*/
166167
if (in->sql_format.source_prefix.data && in->sql_format.source_prefix.len) {
167168
trie_insert(ta->user_strs, "s", 1, &in->sql_format.source_prefix, NULL);
@@ -173,6 +174,18 @@ int PoolArgs_init(PoolArgs_t *pa, struct input *in, pthread_mutex_t *global_mute
173174
break;
174175
}
175176

177+
/* create a simple kv table and functions to set and get */
178+
if (ptkv_init(ta->outdb) != SQLITE_OK) {
179+
break;
180+
}
181+
182+
/* set key s with the source tree path - can change, but generally will not */
183+
if (in->sql_format.source_prefix.data && in->sql_format.source_prefix.len) {
184+
if (ptkv_set_internal(i, ta->outdb, "s", 1, &in->sql_format.source_prefix) != SQLITE_OK) {
185+
break;
186+
}
187+
}
188+
176189
if (sqlite3_create_function(ta->outdb, "thread_id", 0, SQLITE_UTF8,
177190
(void *) (uintptr_t) i, &thread_id, NULL, NULL) != SQLITE_OK) {
178191
fprintf(stderr, "Error: Could not add thread_id to sqlite\n");
@@ -277,6 +290,8 @@ void PoolArgs_fin(PoolArgs_t *pa, const size_t allocated) {
277290
for(size_t i = 0; i < allocated; i++) {
278291
ThreadArgs_t *ta = &pa->ta[i];
279292

293+
ptkv_fini(ta->outdb);
294+
280295
closedb(ta->outdb);
281296

282297
trie_free(ta->user_strs);

src/gufi_query/per_thread_kv.c

Lines changed: 243 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,243 @@
1+
/*
2+
This file is part of GUFI, which is part of MarFS, which is released
3+
under the BSD license.
4+
5+
6+
Copyright (c) 2017, Los Alamos National Security (LANS), LLC
7+
All rights reserved.
8+
9+
Redistribution and use in source and binary forms, with or without modification,
10+
are permitted provided that the following conditions are met:
11+
12+
1. Redistributions of source code must retain the above copyright notice, this
13+
list of conditions and the following disclaimer.
14+
15+
2. Redistributions in binary form must reproduce the above copyright notice,
16+
this list of conditions and the following disclaimer in the documentation and/or
17+
other materials provided with the distribution.
18+
19+
3. Neither the name of the copyright holder nor the names of its contributors
20+
may be used to endorse or promote products derived from this software without
21+
specific prior written permission.
22+
23+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
24+
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25+
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26+
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
27+
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
28+
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29+
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30+
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
31+
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
32+
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33+
34+
35+
From Los Alamos National Security, LLC:
36+
LA-CC-15-039
37+
38+
Copyright (c) 2017, Los Alamos National Security, LLC All rights reserved.
39+
Copyright 2017. Los Alamos National Security, LLC. This software was produced
40+
under U.S. Government contract DE-AC52-06NA25396 for Los Alamos National
41+
Laboratory (LANL), which is operated by Los Alamos National Security, LLC for
42+
the U.S. Department of Energy. The U.S. Government has rights to use,
43+
reproduce, and distribute this software. NEITHER THE GOVERNMENT NOR LOS
44+
ALAMOS NATIONAL SECURITY, LLC MAKES ANY WARRANTY, EXPRESS OR IMPLIED, OR
45+
ASSUMES ANY LIABILITY FOR THE USE OF THIS SOFTWARE. If software is
46+
modified to produce derivative works, such modified software should be
47+
clearly marked, so as not to confuse it with the version available from
48+
LANL.
49+
50+
THIS SOFTWARE IS PROVIDED BY LOS ALAMOS NATIONAL SECURITY, LLC AND CONTRIBUTORS
51+
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
52+
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
53+
ARE DISCLAIMED. IN NO EVENT SHALL LOS ALAMOS NATIONAL SECURITY, LLC OR
54+
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
55+
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
56+
OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
57+
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
58+
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
59+
IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
60+
OF SUCH DAMAGE.
61+
*/
62+
63+
64+
65+
#include <stdlib.h>
66+
#include <string.h>
67+
68+
#include "gufi_query/per_thread_kv.h"
69+
#include "str.h"
70+
#include "utils.h"
71+
72+
#define PER_THREAD_KV "temp.PER_THREAD_KV"
73+
#define KEY "key"
74+
#define VALUE "value"
75+
76+
int ptkv_init(sqlite3 *db) {
77+
int rc = SQLITE_OK;
78+
char *err = NULL;
79+
80+
/* create the per-thread kv table */
81+
rc = sqlite3_exec(db,
82+
"DROP TABLE IF EXISTS " PER_THREAD_KV ";"
83+
"CREATE TABLE " PER_THREAD_KV "(" KEY " TEXT PRIMARY KEY, " VALUE " TEXT);",
84+
NULL, NULL, &err);
85+
if (rc != SQLITE_OK) {
86+
sqlite_print_err_and_free(err, stderr, "Error: Could not create per-thread kv table: %s\n", err);
87+
return rc;
88+
}
89+
90+
/* add per-thread kv store setter */
91+
rc = sqlite3_create_function(db, "ptkv_set", 2, SQLITE_UTF8,
92+
db, &ptkv_set, NULL, NULL);
93+
if (rc != SQLITE_OK) {
94+
sqlite_print_err_and_free(NULL, stderr, "Error: Could not create pktv_set function\n");
95+
return rc;
96+
}
97+
98+
/* add per-thread kv store getter */
99+
rc = sqlite3_create_function(db, "ptkv_get", 1, SQLITE_UTF8,
100+
db, &ptkv_get, NULL, NULL);
101+
if (rc != SQLITE_OK) {
102+
sqlite_print_err_and_free(NULL, stderr, "Error: Could not create pktv_get function\n");
103+
return rc;
104+
}
105+
106+
return SQLITE_OK;
107+
}
108+
109+
/* ptkv_set(key, value) */
110+
void ptkv_set(sqlite3_context *context, int argc, sqlite3_value **argv) {
111+
(void) argc;
112+
113+
sqlite3 *db = (sqlite3 *) sqlite3_user_data(context);
114+
const char *key = (const char *) sqlite3_value_text(argv[0]);
115+
const size_t key_len = strlen(key);
116+
const char *val = (const char *) sqlite3_value_text(argv[1]);
117+
const size_t val_len = strlen(val);
118+
119+
#define DELETE "DELETE FROM " PER_THREAD_KV " WHERE " KEY " == "
120+
#define INSERT "INSERT INTO " PER_THREAD_KV "(" KEY ", " VALUE ") VALUES ("
121+
122+
const size_t sql_len = (
123+
((sizeof(DELETE) - 1) +
124+
1 + key_len + 1 + /* 'key' */
125+
1 + 1) + /* ; + space */
126+
((sizeof(INSERT) - 1) +
127+
1 + key_len + 1 + /* 'key' */
128+
1 + 1 + /* , + space */
129+
1 + val_len + 1 + /* 'value' */
130+
1 + 1) /* ); */
131+
);
132+
133+
char *sql = malloc(sql_len + 1);
134+
SNFORMAT_S(sql, sql_len + 1, 10,
135+
DELETE, sizeof(DELETE) - 1,
136+
"'", (size_t) 1,
137+
key, key_len,
138+
"'; ", (size_t) 3,
139+
INSERT, sizeof(INSERT) - 1,
140+
"'", (size_t) 1,
141+
key, key_len,
142+
"', '", (size_t) 4,
143+
val, val_len,
144+
"');", (size_t) 3);
145+
146+
char *err = NULL;
147+
const int rc = sqlite3_exec(db, sql, NULL, NULL, &err);
148+
free(sql);
149+
150+
if (rc != SQLITE_OK) {
151+
sqlite3_result_error(context, err, -1);
152+
sqlite3_free(err);
153+
}
154+
}
155+
156+
int ptkv_set_internal(const size_t tid, sqlite3 *db,
157+
const char *key, const size_t key_len,
158+
const refstr_t *val) {
159+
#define PTKV_SET "SELECT ptkv_set("
160+
const size_t sql_len = (
161+
(sizeof(PTKV_SET) - 1) +
162+
1 + key_len + 1 + /* 'key' */
163+
1 + 1 + /* , + space */
164+
1 + val->len + 1 + /* 'value' */
165+
1 + 1 /* ); */
166+
);
167+
168+
char *sql = malloc(sql_len + 1);
169+
SNFORMAT_S(sql, sql_len + 1, 6,
170+
PTKV_SET, (sizeof(PTKV_SET) - 1),
171+
"'", (size_t) 1,
172+
key, key_len,
173+
"', '", (size_t) 4,
174+
val->data, val->len,
175+
"');", (size_t) 3);
176+
177+
char *err = NULL;
178+
const int rc = sqlite3_exec(db, sql, NULL, NULL, &err);
179+
free(sql);
180+
if (rc != SQLITE_OK) {
181+
sqlite_print_err_and_free(err, stderr, "Error: Could not set predefined key \"%s\" on thread %zu: %s\n",
182+
key, tid, err);
183+
return rc;
184+
}
185+
186+
return SQLITE_OK;
187+
}
188+
189+
static int ptkv_get_val(void *args, int count, char **data, char **columns) {
190+
(void) count; (void) columns;
191+
192+
str_t *str = (str_t *) args;
193+
str->len = strlen(data[0]);
194+
str->data = malloc(str->len + 1);
195+
memcpy(str->data, data[0], str->len);
196+
str->data[str->len] = '\0';
197+
return 0;
198+
}
199+
200+
/* ptkv_get(key) */
201+
void ptkv_get(sqlite3_context *context, int argc, sqlite3_value **argv) {
202+
(void) argc;
203+
204+
sqlite3 *db = (sqlite3 *) sqlite3_user_data(context);
205+
const char *key = (const char *) sqlite3_value_text(argv[0]);
206+
const size_t key_len = strlen(key);
207+
208+
#define SELECT "SELECT " VALUE " FROM " PER_THREAD_KV " WHERE " KEY " == "
209+
210+
const size_t sql_len = (
211+
(sizeof(SELECT) - 1) +
212+
1 + key_len + 1 + /* 'key' */
213+
1 /* ; */
214+
);
215+
216+
char *sql = malloc(sql_len + 1);
217+
SNFORMAT_S(sql, sql_len + 1, 4,
218+
SELECT, sizeof(SELECT) - 1,
219+
"'", (size_t) 1,
220+
key, key_len,
221+
"';", (size_t) 2);
222+
223+
str_t val;
224+
char *err = NULL;
225+
const int rc = sqlite3_exec(db, sql, ptkv_get_val, &val, &err);
226+
free(sql);
227+
228+
if (rc != SQLITE_OK) {
229+
sqlite3_result_error(context, err, -1);
230+
sqlite3_free(err);
231+
}
232+
233+
sqlite3_result_text(context, val.data, val.len, SQLITE_TRANSIENT);
234+
str_free_existing(&val);
235+
}
236+
237+
void ptkv_fini(sqlite3 *db) {
238+
/* dropping PER_THREAD_KV is not strictly necessary since it is in the temp namespace */
239+
char *err = NULL;
240+
if (sqlite3_exec(db, "DROP TABLE IF EXISTS " PER_THREAD_KV ";", NULL, NULL, &err) != SQLITE_OK) {
241+
sqlite_print_err_and_free(err, stderr, "Error: Could not drop per-thread kv table: %s\n", err);
242+
}
243+
}

0 commit comments

Comments
 (0)