Tarantool development patches archive
 help / color / mirror / Atom feed
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

  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