|
|
|
@ -30,10 +30,6 @@ |
|
|
|
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
|
|
|
|
* |
|
|
|
|
*/ |
|
|
|
|
/*
|
|
|
|
|
- comment about key/value ptrs being to mem |
|
|
|
|
- add comment about encode/decode being for RPC use only. |
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
#include <grpc/census.h> |
|
|
|
|
#include <grpc/support/alloc.h> |
|
|
|
@ -65,10 +61,10 @@ |
|
|
|
|
// that can be directly copied to the wire. This makes iteration by index
|
|
|
|
|
// somewhat less efficient. If it becomes a problem, we could consider
|
|
|
|
|
// building an index at tag_set creation.
|
|
|
|
|
// * Binary tags are encoded seperately from non-binary tags. There are a
|
|
|
|
|
// primarily because non-binary tags are far more likely to be repeated
|
|
|
|
|
// across multiple RPC calls, so are more efficiently cached and
|
|
|
|
|
// compressed in any metadata schemes.
|
|
|
|
|
// * Binary tags share the same structure as, but are encoded seperately from,
|
|
|
|
|
// non-binary tags. This is primarily because non-binary tags are far more
|
|
|
|
|
// likely to be repeated across multiple RPC calls, so are more efficiently
|
|
|
|
|
// cached and compressed in any metadata schemes.
|
|
|
|
|
// * all lengths etc. are restricted to one byte. This eliminates endian
|
|
|
|
|
// issues.
|
|
|
|
|
|
|
|
|
@ -108,7 +104,7 @@ struct raw_tag { |
|
|
|
|
char *value; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
// use reserved flag bit for indication of deleted tag.
|
|
|
|
|
// Use a reserved flag bit for indication of deleted tag.
|
|
|
|
|
#define CENSUS_TAG_DELETED CENSUS_TAG_RESERVED |
|
|
|
|
#define CENSUS_TAG_IS_DELETED(flags) (flags & CENSUS_TAG_DELETED) |
|
|
|
|
|
|
|
|
@ -125,8 +121,8 @@ struct census_tag_set { |
|
|
|
|
#define LOCAL_TAGS 2 |
|
|
|
|
|
|
|
|
|
// Extract a raw tag given a pointer (raw) to the tag header. Allow for some
|
|
|
|
|
// extra bytes in the tag header (see encode/decode for usage: allows for
|
|
|
|
|
// future expansion of the tag header).
|
|
|
|
|
// extra bytes in the tag header (see encode/decode functions for usage: this
|
|
|
|
|
// allows for future expansion of the tag header).
|
|
|
|
|
static char *decode_tag(struct raw_tag *tag, char *header, int offset) { |
|
|
|
|
tag->key_len = (uint8_t)(*header++); |
|
|
|
|
tag->value_len = (uint8_t)(*header++); |
|
|
|
@ -145,7 +141,7 @@ static void tag_set_copy(struct tag_set *to, const struct tag_set *from) { |
|
|
|
|
memcpy(to->kvm, from->kvm, to->kvm_used); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Delete a tag from a tag set, if it exists (returns true it it did).
|
|
|
|
|
// Delete a tag from a tag_set, if it exists (returns true it it did).
|
|
|
|
|
static bool tag_set_delete_tag(struct tag_set *tags, const char *key, |
|
|
|
|
size_t key_len) { |
|
|
|
|
char *kvp = tags->kvm; |
|
|
|
@ -163,7 +159,7 @@ static bool tag_set_delete_tag(struct tag_set *tags, const char *key, |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Delete a tag from a tag set, return true if it existed.
|
|
|
|
|
// Delete a tag from a census_tag_set, return true if it existed.
|
|
|
|
|
static bool cts_delete_tag(census_tag_set *tags, const census_tag *tag, |
|
|
|
|
size_t key_len) { |
|
|
|
|
return (tag_set_delete_tag(&tags->tags[LOCAL_TAGS], tag->key, key_len) || |
|
|
|
@ -172,8 +168,8 @@ static bool cts_delete_tag(census_tag_set *tags, const census_tag *tag, |
|
|
|
|
key_len)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Add a tag to a tag set. Return true on sucess, false if the tag could
|
|
|
|
|
// not be added because of tag size constraints.
|
|
|
|
|
// Add a tag to a tag_set. Return true on sucess, false if the tag could
|
|
|
|
|
// not be added because of constraints on tag set size.
|
|
|
|
|
static bool tag_set_add_tag(struct tag_set *tags, const census_tag *tag, |
|
|
|
|
size_t key_len) { |
|
|
|
|
if (tags->ntags == CENSUS_MAX_PROPAGATED_TAGS) { |
|
|
|
@ -203,11 +199,14 @@ static bool tag_set_add_tag(struct tag_set *tags, const census_tag *tag, |
|
|
|
|
return true; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Add a tag to a census_tag_set.
|
|
|
|
|
static void cts_add_tag(census_tag_set *tags, const census_tag *tag, |
|
|
|
|
size_t key_len, census_tag_set_create_status *status) { |
|
|
|
|
// first delete the tag if it is already present
|
|
|
|
|
// Add/modify/delete a tag to/in a census_tag_set. Caller must validate that
|
|
|
|
|
// tag key etc. are valid.
|
|
|
|
|
static void cts_modify_tag(census_tag_set *tags, const census_tag *tag, |
|
|
|
|
size_t key_len, |
|
|
|
|
census_tag_set_create_status *status) { |
|
|
|
|
// First delete the tag if it is already present.
|
|
|
|
|
bool deleted = cts_delete_tag(tags, tag, key_len); |
|
|
|
|
// Determine if we need to add it back.
|
|
|
|
|
bool call_add = tag->value != NULL && tag->value_len != 0; |
|
|
|
|
bool added = false; |
|
|
|
|
if (call_add) { |
|
|
|
@ -239,7 +238,7 @@ static void cts_add_tag(census_tag_set *tags, const census_tag *tag, |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Remove any deleted tags from the tag set. Basic algorithm:
|
|
|
|
|
// Remove memory used for deleted tags from the tag set. Basic algorithm:
|
|
|
|
|
// 1) Walk through tag set to find first deleted tag. Record where it is.
|
|
|
|
|
// 2) Find the next not-deleted tag. Copy all of kvm from there to the end
|
|
|
|
|
// "over" the deleted tags
|
|
|
|
@ -289,6 +288,8 @@ census_tag_set *census_tag_set_create(const census_tag_set *base, |
|
|
|
|
memset(status, 0, sizeof(*status)); |
|
|
|
|
} |
|
|
|
|
census_tag_set *new_ts = gpr_malloc(sizeof(census_tag_set)); |
|
|
|
|
// If we are given a base, copy it into our new tag set. Otherwise set it
|
|
|
|
|
// to zero/NULL everything.
|
|
|
|
|
if (base == NULL) { |
|
|
|
|
memset(new_ts, 0, sizeof(census_tag_set)); |
|
|
|
|
} else { |
|
|
|
@ -297,17 +298,20 @@ census_tag_set *census_tag_set_create(const census_tag_set *base, |
|
|
|
|
&base->tags[PROPAGATED_BINARY_TAGS]); |
|
|
|
|
tag_set_copy(&new_ts->tags[LOCAL_TAGS], &base->tags[LOCAL_TAGS]); |
|
|
|
|
} |
|
|
|
|
// Walk over the additional tags and, for those that aren't invalid, modify
|
|
|
|
|
// the tag set to add/replace/delete as required.
|
|
|
|
|
for (int i = 0; i < ntags; i++) { |
|
|
|
|
const census_tag *tag = &tags[i]; |
|
|
|
|
size_t key_len = strlen(tag->key) + 1; |
|
|
|
|
// ignore the tag if it is too long/short.
|
|
|
|
|
if (key_len != 1 && key_len <= CENSUS_MAX_TAG_KV_LEN && |
|
|
|
|
tag->value_len <= CENSUS_MAX_TAG_KV_LEN) { |
|
|
|
|
cts_add_tag(new_ts, tag, key_len, status); |
|
|
|
|
cts_modify_tag(new_ts, tag, key_len, status); |
|
|
|
|
} else { |
|
|
|
|
n_invalid_tags++; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
// Remove any deleted tags, update status if needed, and return.
|
|
|
|
|
tag_set_flatten(&new_ts->tags[PROPAGATED_TAGS]); |
|
|
|
|
tag_set_flatten(&new_ts->tags[PROPAGATED_BINARY_TAGS]); |
|
|
|
|
tag_set_flatten(&new_ts->tags[LOCAL_TAGS]); |
|
|
|
@ -334,8 +338,8 @@ int census_tag_set_ntags(const census_tag_set *tags) { |
|
|
|
|
tags->tags[LOCAL_TAGS].ntags; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* Initialize a tag set iterator. Must be called before first use of the
|
|
|
|
|
iterator. */ |
|
|
|
|
// Initialize a tag set iterator. Must be called before first use of the
|
|
|
|
|
// iterator.
|
|
|
|
|
void census_tag_set_initialize_iterator(const census_tag_set *tags, |
|
|
|
|
census_tag_set_iterator *iterator) { |
|
|
|
|
iterator->tags = tags; |
|
|
|
@ -354,9 +358,9 @@ void census_tag_set_initialize_iterator(const census_tag_set *tags, |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* Get the contents of the "next" tag in the tag set. If there are no more
|
|
|
|
|
tags in the tag set, returns 0 (and 'tag' contents will be unchanged), |
|
|
|
|
otherwise returns 1. */ |
|
|
|
|
// Get the contents of the "next" tag in the tag set. If there are no more
|
|
|
|
|
// tags in the tag set, returns 0 (and 'tag' contents will be unchanged),
|
|
|
|
|
// otherwise returns 1. */
|
|
|
|
|
int census_tag_set_next_tag(census_tag_set_iterator *iterator, |
|
|
|
|
census_tag *tag) { |
|
|
|
|
if (iterator->base < 0) { |
|
|
|
|