Skip to content

Commit

Permalink
[C] Add support for human readable properties for term-length, linger…
Browse files Browse the repository at this point in the history
…, and mtu as channel params. Issue #603.
  • Loading branch information
mjpt777 committed Jan 6, 2019
1 parent 95fe70b commit 1bc177c
Show file tree
Hide file tree
Showing 6 changed files with 393 additions and 6 deletions.
2 changes: 2 additions & 0 deletions aeron-driver/src/main/c/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ SET(SOURCE
util/aeron_arrayutil.c
util/aeron_error.c
util/aeron_netutil.c
util/aeron_prop_util.c
aeron_driver_context.c
aeron_alloc.c
aeron_driver.c
Expand Down Expand Up @@ -154,6 +155,7 @@ SET(HEADERS
util/aeron_arrayutil.h
util/aeron_error.h
util/aeron_netutil.h
util/aeron_prop_util.h
concurrent/aeron_atomic.h
concurrent/aeron_atomic64_gcc_x86_64.h
concurrent/aeron_spsc_rb.h
Expand Down
13 changes: 7 additions & 6 deletions aeron-driver/src/main/c/uri/aeron_uri.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include <inttypes.h>
#include "uri/aeron_uri.h"
#include "util/aeron_arrayutil.h"
#include "util/aeron_prop_util.h"
#include "aeron_driver_context.h"
#include "aeron_uri.h"
#include "aeron_alloc.h"
Expand Down Expand Up @@ -276,9 +277,9 @@ int aeron_uri_get_term_length_param(aeron_uri_params_t *uri_params, aeron_uri_pu

if ((value_str = aeron_uri_find_param_value(uri_params, AERON_URI_TERM_LENGTH_KEY)) != NULL)
{
uint64_t value = strtoull(value_str, NULL, 0);
uint64_t value;

if (0 == value && EINVAL == errno)
if (-1 == aeron_parse_size64(value_str, &value))
{
aeron_set_err(EINVAL, "could not parse %s in URI", AERON_URI_TERM_LENGTH_KEY);
return -1;
Expand All @@ -301,9 +302,9 @@ int aeron_uri_get_mtu_length_param(aeron_uri_params_t *uri_params, aeron_uri_pub

if ((value_str = aeron_uri_find_param_value(uri_params, AERON_URI_MTU_LENGTH_KEY)) != NULL)
{
uint64_t value = strtoull(value_str, NULL, 0);
uint64_t value;

if (0 == value && EINVAL == errno)
if (-1 == aeron_parse_size64(value_str, &value))
{
aeron_set_err(EINVAL, "could not parse %s in URI", AERON_URI_MTU_LENGTH_KEY);
return -1;
Expand All @@ -326,9 +327,9 @@ int aeron_uri_linger_timeout_param(aeron_uri_params_t *uri_params, aeron_uri_pub

if ((value_str = aeron_uri_find_param_value(uri_params, AERON_URI_LINGER_TIMEOUT_KEY)) != NULL)
{
uint64_t value = strtoull(value_str, NULL, 0);
uint64_t value;

if (0 == value && EINVAL == errno)
if (-1 == aeron_parse_duration_ns(value_str, &value))
{
aeron_set_err(EINVAL, "could not parse %s in URI", AERON_URI_LINGER_TIMEOUT_KEY);
return -1;
Expand Down
178 changes: 178 additions & 0 deletions aeron-driver/src/main/c/util/aeron_prop_util.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
/*
* Copyright 2014-2019 Real Logic Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#include <memory.h>
#include <stdlib.h>
#include <errno.h>
#include <limits.h>
#include <ctype.h>
#include "util/aeron_prop_util.h"

const uint64_t AERON_MAX_G_VALUE = 8589934591ULL;
const uint64_t AERON_MAX_M_VALUE = 8796093022207ULL;
const uint64_t AERON_MAX_K_VALUE = 9007199254739968ULL;

int aeron_parse_size64(const char *str, uint64_t *result)
{
if (NULL == str)
{
return -1;
}

char *end;
const int64_t v = strtoll(str, &end, 0);
if (v < 0 || EINVAL == errno || ERANGE == errno || end == str)
{
return -1;
}

const uint64_t value = (uint64_t)v;

if ('\0' != *end)
{
switch (*end)
{
case 'k':
case 'K':
if (value > AERON_MAX_K_VALUE)
{
return -1;
}
*result = value * 1024;
break;

case 'm':
case 'M':
if (value > AERON_MAX_M_VALUE)
{
return -1;
}
*result = value * 1024 * 1024;
break;

case 'g':
case 'G':
if (value > AERON_MAX_G_VALUE)
{
return -1;
}
*result = value * 1024 * 1024 * 1024;
break;

default:
return -1;
}
}
else
{
*result = value;
}

return 0;
}

int aeron_parse_duration_ns(const char *str, uint64_t *result)
{
if (NULL == str)
{
return -1;
}

char *end;
const int64_t v = strtoll(str, &end, 0);
if (v < 0 || EINVAL == errno || ERANGE == errno || end == str)
{
return -1;
}

const uint64_t value = (uint64_t)v;

if ('\0' != *end)
{
switch (tolower(*end))
{
case 's':
if ('\0' != *(end + 1))
{
return -1;
}

if (value > LLONG_MAX / 1000000000)
{
*result = LLONG_MAX;
}
else
{
*result = value * 1000000000;
}
break;

case 'm':
if (tolower(*(end + 1)) != 's' && '\0' != *(end + 2))
{
return -1;
}

if (value > LLONG_MAX / 1000000)
{
*result = LLONG_MAX;
}
else
{
*result = value * 1000000;
}
break;

case 'u':
if (tolower(*(end + 1)) != 's' && '\0' != *(end + 2))
{
return -1;
}

if (value > LLONG_MAX / 1000)
{
*result = LLONG_MAX;
}
else
{
*result = value * 1000;
}
break;

case 'n':
if (tolower(*(end + 1)) != 's' && '\0' != *(end + 2))
{
return -1;
}

*result = value;
break;

default:
return -1;
}
}
else
{
*result = value;
}

return 0;
}

extern int aeron_parse_size64(const char *str, uint64_t *result);

extern int aeron_parse_duration_ns(const char *str, uint64_t *result);
26 changes: 26 additions & 0 deletions aeron-driver/src/main/c/util/aeron_prop_util.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* Copyright 2014-2019 Real Logic Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#ifndef AERON_PROP_UTIL_H
#define AERON_PROP_UTIL_H

#include <stdint.h>

int aeron_parse_size64(const char *str, uint64_t *result);

int aeron_parse_duration_ns(const char *str, uint64_t *result);

#endif //AERON_AERON_PROP_UTIL_H
1 change: 1 addition & 0 deletions aeron-driver/src/test/c/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ aeron_driver_test(retransmit_handler_test aeron_retransmit_handler_test.cpp)
aeron_driver_test(loss_reporter_test aeron_loss_reporter_test.cpp)
aeron_driver_test(logbuffer_unblocker aeron_logbuffer_unblocker_test.cpp)
aeron_driver_test(term_gap_filler_test aeron_term_gap_filler_test.cpp)
aeron_driver_test(prop_test aeron_prop_util_test.cpp)

function(aeron_driver_benchmark name file)
add_executable(${name} ${file})
Expand Down
Loading

0 comments on commit 1bc177c

Please sign in to comment.