From: Vladimir Davydov <vdavydov.dev@gmail.com>
To: Kirill Shcherbatov <kshcherbatov@tarantool.org>
Cc: tarantool-patches@freelists.org, kostja@tarantool.org
Subject: Re: [PATCH v5 3/9] box: manage format fields with JSON tree class
Date: Thu, 29 Nov 2018 22:07:57 +0300 [thread overview]
Message-ID: <20181129190757.oyu7kom6drgacd3j@esperanza> (raw)
In-Reply-To: <0ff5601b664e42d70d71be658b4ba45fe1237564.1543229303.git.kshcherbatov@tarantool.org>
On Mon, Nov 26, 2018 at 01:49:37PM +0300, Kirill Shcherbatov wrote:
> diff --git a/src/box/tuple_format.c b/src/box/tuple_format.c
> index d184dba..92028c5 100644
> --- a/src/box/tuple_format.c
> +++ b/src/box/tuple_format.c
> @@ -38,10 +38,28 @@ static intptr_t recycled_format_ids = FORMAT_ID_NIL;
>
> static uint32_t formats_size = 0, formats_capacity = 0;
>
> -static const struct tuple_field tuple_field_default = {
> - FIELD_TYPE_ANY, TUPLE_OFFSET_SLOT_NIL, false,
> - ON_CONFLICT_ACTION_NONE, NULL, COLL_NONE,
> -};
> +static struct tuple_field *
> +tuple_field_create(struct json_token *token)
> +{
> + struct tuple_field *ret = calloc(1, sizeof(struct tuple_field));
> + if (ret == NULL) {
> + diag_set(OutOfMemory, sizeof(struct tuple_field), "malloc",
> + "ret");
> + return NULL;
> + }
> + ret->type = FIELD_TYPE_ANY;
> + ret->offset_slot = TUPLE_OFFSET_SLOT_NIL;
> + ret->coll_id = COLL_NONE;
> + ret->nullable_action = ON_CONFLICT_ACTION_NONE;
> + ret->token = *token;
> + return ret;
> +}
> +
> +static void
> +tuple_field_destroy(struct tuple_field *field)
> +{
> + free(field);
> +}
We usually call methods that allocate/free an object _new/delete, not
_create/destroy. Please fix.
> @@ -258,39 +273,68 @@ tuple_format_alloc(struct key_def * const *keys, uint16_t key_count,
> }
> }
> uint32_t field_count = MAX(space_field_count, index_field_count);
> - uint32_t total = sizeof(struct tuple_format) +
> - field_count * sizeof(struct tuple_field);
>
> - struct tuple_format *format = (struct tuple_format *) malloc(total);
> + struct tuple_format *format = malloc(sizeof(struct tuple_format));
> if (format == NULL) {
> diag_set(OutOfMemory, sizeof(struct tuple_format), "malloc",
> "tuple format");
> return NULL;
> }
> + if (json_tree_create(&format->tree) != 0) {
> + free(format);
> + return NULL;
> + }
> + struct json_token token;
> + memset(&token, 0, sizeof(token));
> + token.key.type = JSON_TOKEN_NUM;
> + for (token.key.num = TUPLE_INDEX_BASE;
> + token.key.num < field_count + TUPLE_INDEX_BASE; token.key.num++) {
> + struct tuple_field *field = tuple_field_create(&token);
I've looked at your following patches - this is the only place where you
pass a non-NULL token to tuple_field_create. Let's not pass token to
this function at all, and initialize field->token directly here.
> + if (field == NULL)
> + goto error;
> + if (json_tree_add(&format->tree, NULL, &field->token) != 0) {
diag_set missing
> + tuple_field_destroy(field);
> + goto error;
> + }
> + }
> if (dict == NULL) {
> assert(space_field_count == 0);
> format->dict = tuple_dictionary_new(NULL, 0);
> - if (format->dict == NULL) {
> - free(format);
> - return NULL;
> - }
> + if (format->dict == NULL)
> + goto error;
> } else {
> format->dict = dict;
> tuple_dictionary_ref(dict);
> }
> format->refs = 0;
> format->id = FORMAT_ID_NIL;
> - format->field_count = field_count;
> format->index_field_count = index_field_count;
> format->exact_field_count = 0;
> format->min_field_count = 0;
> return format;
> +error:;
> + struct tuple_field *field;
> + json_tree_foreach_entry_safe(field, &format->tree.root,
> + struct tuple_field, token) {
> + json_tree_del(&format->tree, &field->token);
> + tuple_field_destroy(field);
> + }
> + json_tree_destroy(&format->tree);
And you have exactly the same piece of code in tuple_format_destroy.
Factor it out to a helper function?
> + free(format);
> + return NULL;
> }
>
> /** Free tuple format resources, doesn't unregister. */
> static inline void
> tuple_format_destroy(struct tuple_format *format)
> {
> + struct tuple_field *field;
> + json_tree_foreach_entry_safe(field, &format->tree.root,
> + struct tuple_field, token) {
> + json_tree_del(&format->tree, &field->token);
> + tuple_field_destroy(field);
> + }
> + json_tree_destroy(&format->tree);
> tuple_dictionary_unref(format->dict);
> }
>
> diff --git a/src/box/tuple_format.h b/src/box/tuple_format.h
> index 232df22..2da773b 100644
> --- a/src/box/tuple_format.h
> +++ b/src/box/tuple_format.h
> @@ -34,6 +34,7 @@
> #include "key_def.h"
> #include "field_def.h"
> #include "errinj.h"
> +#include "json/json.h"
> #include "tuple_dictionary.h"
>
> #if defined(__cplusplus)
> @@ -113,6 +114,8 @@ struct tuple_field {
> struct coll *coll;
> /** Collation identifier. */
> uint32_t coll_id;
> + /** An JSON entry to organize tree. */
/** Link in tuple_format::fields. */
would be more useful.
> + struct json_token token;
> };
>
> /**
> @@ -166,16 +169,33 @@ struct tuple_format {
> * index_field_count <= min_field_count <= field_count.
> */
> uint32_t min_field_count;
> - /* Length of 'fields' array. */
> - uint32_t field_count;
> /**
> * Shared names storage used by all formats of a space.
> */
> struct tuple_dictionary *dict;
> - /* Formats of the fields */
> - struct tuple_field fields[0];
> + /** JSON tree of fields. */
Would be prudent to say a few words about the tree structure, e.g.
/**
* Fields comprising the format, organized in a tree.
* First level nodes correspond to tuple fields.
* Deeper levels define indexed JSON paths within
* tuple fields. Nodes of the tree are linked by
* tuple_field::token.
*/
I hate to repeat myself, but you ought to pay more attention to comments
in the code.
> + struct json_tree tree;
format->tree - what tree?
Why not leave the same name - 'fields'?
> };
>
> +
> +static inline uint32_t
> +tuple_format_field_count(const struct tuple_format *format)
> +{
> + return format->tree.root.child_count;
> +}
> +
Comments, comments...
> +static inline struct tuple_field *
> +tuple_format_field(struct tuple_format *format, uint32_t fieldno)
> +{
> + assert(fieldno < tuple_format_field_count(format));
> + struct json_token token = {
> + .key.type = JSON_TOKEN_NUM,
> + .key.num = fieldno + TUPLE_INDEX_BASE
> + };
> + return json_tree_lookup_entry(&format->tree, NULL, &token,
> + struct tuple_field, token);
> +}
> +
> extern struct tuple_format **tuple_formats;
>
> static inline uint32_t
next prev parent reply other threads:[~2018-11-29 19:07 UTC|newest]
Thread overview: 41+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-11-26 10:49 [PATCH v5 0/9] box: indexes by JSON path Kirill Shcherbatov
2018-11-26 10:49 ` [PATCH v5 1/9] box: refactor json_path_parser class Kirill Shcherbatov
2018-11-26 12:53 ` [tarantool-patches] " Kirill Shcherbatov
2018-11-29 15:39 ` Vladimir Davydov
2018-11-26 10:49 ` [PATCH v5 2/9] lib: implement JSON tree class for json library Kirill Shcherbatov
2018-11-26 12:53 ` [tarantool-patches] " Kirill Shcherbatov
2018-11-29 17:38 ` Vladimir Davydov
2018-11-29 17:50 ` Vladimir Davydov
2018-12-04 15:22 ` Vladimir Davydov
2018-12-04 15:47 ` [tarantool-patches] " Kirill Shcherbatov
2018-12-04 17:54 ` Vladimir Davydov
2018-12-05 8:37 ` Kirill Shcherbatov
2018-12-05 9:07 ` Vladimir Davydov
2018-12-05 9:52 ` Vladimir Davydov
2018-12-06 7:56 ` Kirill Shcherbatov
2018-12-06 7:56 ` [tarantool-patches] Re: [PATCH v5 2/9] lib: make index_base support for json_lexer Kirill Shcherbatov
2018-11-26 10:49 ` [PATCH v5 3/9] box: manage format fields with JSON tree class Kirill Shcherbatov
2018-11-29 19:07 ` Vladimir Davydov [this message]
2018-12-04 15:47 ` [tarantool-patches] " Kirill Shcherbatov
2018-12-04 16:09 ` Vladimir Davydov
2018-12-04 16:32 ` Kirill Shcherbatov
2018-12-05 8:37 ` Kirill Shcherbatov
2018-12-06 7:56 ` Kirill Shcherbatov
2018-12-06 8:06 ` Vladimir Davydov
2018-11-26 10:49 ` [PATCH v5 4/9] lib: introduce json_path_cmp routine Kirill Shcherbatov
2018-11-30 10:46 ` Vladimir Davydov
2018-12-03 17:37 ` [tarantool-patches] " Konstantin Osipov
2018-12-03 18:48 ` Vladimir Davydov
2018-12-03 20:14 ` Konstantin Osipov
2018-12-06 7:56 ` [tarantool-patches] Re: [PATCH v5 4/9] lib: introduce json_path_cmp, json_path_validate Kirill Shcherbatov
2018-11-26 10:49 ` [tarantool-patches] [PATCH v5 5/9] box: introduce JSON indexes Kirill Shcherbatov
2018-11-30 21:28 ` Vladimir Davydov
2018-12-01 16:49 ` Vladimir Davydov
2018-11-26 10:49 ` [PATCH v5 6/9] box: introduce has_json_paths flag in templates Kirill Shcherbatov
2018-11-26 10:49 ` [PATCH v5 7/9] box: tune tuple_field_raw_by_path for indexed data Kirill Shcherbatov
2018-12-01 17:20 ` Vladimir Davydov
2018-11-26 10:49 ` [PATCH v5 8/9] box: introduce offset slot cache in key_part Kirill Shcherbatov
2018-12-03 21:04 ` Vladimir Davydov
2018-12-04 15:51 ` Vladimir Davydov
2018-11-26 10:49 ` [PATCH v5 9/9] box: specify indexes in user-friendly form Kirill Shcherbatov
2018-12-04 12:22 ` Vladimir Davydov
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20181129190757.oyu7kom6drgacd3j@esperanza \
--to=vdavydov.dev@gmail.com \
--cc=kostja@tarantool.org \
--cc=kshcherbatov@tarantool.org \
--cc=tarantool-patches@freelists.org \
--subject='Re: [PATCH v5 3/9] box: manage format fields with JSON tree class' \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox