Skip to content

Commit

Permalink
Merge pull request #1265 from chu11/issue1193-part1
Browse files Browse the repository at this point in the history
kvs: support append operation
  • Loading branch information
garlick authored Nov 1, 2017
2 parents 3a286cb + 0145b56 commit 00b06d1
Show file tree
Hide file tree
Showing 12 changed files with 808 additions and 151 deletions.
6 changes: 4 additions & 2 deletions doc/man1/flux-kvs.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -50,13 +50,15 @@ interpreted as encoded JSON and formatted accordingly. If '-r', value
is displayed without a newline. If '-t', the RFC 11 object is displayed.
'-a treeobj' causes the lookup to be relative to an RFC 11 snapshot reference.

*put* [-j|-r|-t] [-n] 'key=value' ['key=value...']::
*put* [-j|-r|-t] [-n] [-A] 'key=value' ['key=value...']::
Store 'value' under 'key' and commit it. If it already has a value,
overwrite it. If no options, value is stored directly. If '-j', it is
first encoded as JSON, then stored. If '-r', the value may be read from
standard input if specified as "-", and may include embedded NULL bytes.
If '-t', value is stored as a RFC 11 object. '-n' prevents the commit
from being merged with with other contemporaneous commits.
from being merged with with other contemporaneous commits. '-A' appends the
value to a key instead of overwriting the value. Append is incompatible with
the -j option.

*ls* [-R] [-d] [-F] [-w COLS] [-1] ['key' ...]::
Display directory referred to by _key_, or "." (root) if unspecified.
Expand Down
8 changes: 7 additions & 1 deletion doc/man3/flux_kvs_txn_create.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ Each function below adds a single operation to _txn_. _key_ is a
hierarchical path name with period (".") used as path separator.
When the transaction is committed, any existing keys or path components
that are in conflict with the requested operation are overwritten.
_flags_ can modify the request as described below.
`flux_kvs_txn_put()` sets _key_ to a NULL terminated string _value_.
_value_ may be NULL indicating that an empty value should be stored.
Expand All @@ -83,7 +84,12 @@ as a JSON string.
FLAGS
-----

The _flags_ argument is currently unused and must be zero.
The following are valid bits in a _flags_ mask passed as an argument
to `flux_kvs_txn_put()` or `flux_kvs_txn_put_raw()`.

FLUX_KVS_APPEND::
Append value instead of overwriting it. If the key does not exist,
it will be created with the value as the initial value.


include::JSON_PACK.adoc[]
Expand Down
15 changes: 13 additions & 2 deletions src/cmd/flux-kvs.c
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,9 @@ static struct optparse_option put_opts[] = {
{ .name = "no-merge", .key = 'n', .has_arg = 0,
.usage = "Set the NO_MERGE flag to ensure commit is standalone",
},
{ .name = "append", .key = 'A', .has_arg = 0,
.usage = "Append value(s) to key instead of overwriting",
},
OPTPARSE_TABLE_END
};

Expand Down Expand Up @@ -498,6 +501,7 @@ int cmd_put (optparse_t *p, int argc, char **argv)
flux_future_t *f;
flux_kvs_txn_t *txn;
int commit_flags = 0;
int put_flags = 0;

optindex = optparse_option_index (p);
if ((optindex - argc) == 0) {
Expand Down Expand Up @@ -534,18 +538,25 @@ int cmd_put (optparse_t *p, int argc, char **argv)
else if (optparse_hasopt (p, "raw")) {
int len;
uint8_t *buf = NULL;

if (optparse_hasopt (p, "append"))
put_flags |= FLUX_KVS_APPEND;

if (!strcmp (val, "-")) { // special handling for "--raw key=-"
if ((len = read_all (STDIN_FILENO, &buf)) < 0)
log_err_exit ("stdin");
val = (char *)buf;
} else
len = strlen (val);
if (flux_kvs_txn_put_raw (txn, 0, key, val, len) < 0)
if (flux_kvs_txn_put_raw (txn, put_flags, key, val, len) < 0)
log_err_exit ("%s", key);
free (buf);
}
else {
if (flux_kvs_txn_put (txn, 0, key, val) < 0)
if (optparse_hasopt (p, "append"))
put_flags |= FLUX_KVS_APPEND;

if (flux_kvs_txn_put (txn, put_flags, key, val) < 0)
log_err_exit ("%s", key);
}
free (key);
Expand Down
1 change: 1 addition & 0 deletions src/common/libkvs/kvs.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ enum {
FLUX_KVS_READDIR = 1,
FLUX_KVS_READLINK = 2,
FLUX_KVS_TREEOBJ = 16,
FLUX_KVS_APPEND = 32,
};

/* Synchronization:
Expand Down
8 changes: 5 additions & 3 deletions src/common/libkvs/kvs_txn.c
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ int flux_kvs_txn_put_raw (flux_kvs_txn_t *txn, int flags,
errno = EINVAL;
goto error;
}
if (validate_flags (flags, 0) < 0)
if (validate_flags (flags, FLUX_KVS_APPEND) < 0)
goto error;
if (!(dirent = treeobj_create_val (data, len)))
goto error;
Expand Down Expand Up @@ -174,7 +174,7 @@ int flux_kvs_txn_put (flux_kvs_txn_t *txn, int flags,
errno = EINVAL;
goto error;
}
if (validate_flags (flags, 0) < 0)
if (validate_flags (flags, FLUX_KVS_APPEND) < 0)
goto error;
if (!(dirent = treeobj_create_val (value, value ? strlen (value) : 0)))
goto error;
Expand Down Expand Up @@ -373,11 +373,13 @@ int txn_encode_op (const char *key, int flags, json_t *dirent, json_t **opp)
{
json_t *op;

if (!key || strlen (key) == 0 || flags != 0 || !dirent
if (!key || strlen (key) == 0 || !dirent
|| (!json_is_null (dirent) && treeobj_validate (dirent) < 0)) {
errno = EINVAL;
return -1;
}
if (validate_flags (flags, FLUX_KVS_APPEND) < 0)
return -1;
if (!(op = json_pack ("{s:s s:i s:O}",
"key", key,
"flags", flags,
Expand Down
17 changes: 17 additions & 0 deletions src/common/libkvs/test/kvs_txn.c
Original file line number Diff line number Diff line change
Expand Up @@ -317,13 +317,30 @@ void test_raw_values (void)
flux_kvs_txn_destroy (txn);
}

void test_corner_cases (void)
{
json_t *val;
json_t *op;

ok (txn_encode_op (NULL, 0, NULL, NULL) < 0 && errno == EINVAL,
"txn_encode_op fails on bad input");

val = treeobj_create_val ("abcd", 4);

ok (txn_encode_op ("key", 0x44, val, &op) < 0 && errno == EINVAL,
"txn_encode_op fails on bad flags");

json_decref (val);
}

int main (int argc, char *argv[])
{

plan (NO_PLAN);

basic ();
test_raw_values ();
test_corner_cases ();

done_testing();
return (0);
Expand Down
Loading

0 comments on commit 00b06d1

Please sign in to comment.