add function split_string_ex

pull/37/head
YuQing 2020-02-02 20:49:57 +08:00
parent aac2abcfa9
commit a6066181ae
10 changed files with 145 additions and 23 deletions

3
.gitignore vendored
View File

@ -44,6 +44,9 @@ src/tests/test_sched_thread
src/tests/test_skiplist
src/tests/test_skiplist_set
src/tests/test_thourands_seperator
src/tests/test_pthread_lock
src/tests/test_split_string
src/tests/test_uniq_skiplist
# other
php-fastcommon/.deps

View File

@ -1,7 +1,8 @@
Version 1.44 2020-01-19
Version 1.44 2020-02-02
* add test file src/tests/test_pthread_lock.c
* add uniq_skiplist.[hc]
* add function split_string_ex
Version 1.43 2019-12-25
* replace function call system to getExecResult,

View File

@ -287,31 +287,23 @@ int fast_allocator_init_ex(struct fast_allocator_context *acontext,
return result;
}
#define INIT_REGION(region, _start, _end, _step, _alloc_once) \
do { \
region.start = _start; \
region.end = _end; \
region.step = _step; \
region.alloc_elements_once = _alloc_once; \
} while(0)
int fast_allocator_init(struct fast_allocator_context *acontext,
const int64_t alloc_bytes_limit, const double expect_usage_ratio,
const int reclaim_interval, const bool need_lock)
{
#define DEFAULT_REGION_COUNT 5
struct fast_region_info regions[DEFAULT_REGION_COUNT];
struct fast_region_info regions[DEFAULT_REGION_COUNT];
INIT_REGION(regions[0], 0, 256, 8, 4096);
INIT_REGION(regions[1], 256, 1024, 16, 1024);
INIT_REGION(regions[2], 1024, 4096, 64, 256);
INIT_REGION(regions[3], 4096, 16384, 256, 64);
INIT_REGION(regions[4], 16384, 65536, 1024, 16);
FAST_ALLOCATOR_INIT_REGION(regions[0], 0, 256, 8, 4096);
FAST_ALLOCATOR_INIT_REGION(regions[1], 256, 1024, 16, 1024);
FAST_ALLOCATOR_INIT_REGION(regions[2], 1024, 4096, 64, 256);
FAST_ALLOCATOR_INIT_REGION(regions[3], 4096, 16384, 256, 64);
FAST_ALLOCATOR_INIT_REGION(regions[4], 16384, 65536, 1024, 16);
return fast_allocator_init_ex(acontext, regions,
DEFAULT_REGION_COUNT, alloc_bytes_limit,
expect_usage_ratio, reclaim_interval, need_lock);
return fast_allocator_init_ex(acontext, regions,
DEFAULT_REGION_COUNT, alloc_bytes_limit,
expect_usage_ratio, reclaim_interval, need_lock);
}
void fast_allocator_destroy(struct fast_allocator_context *acontext)

View File

@ -28,8 +28,8 @@ struct fast_allocator_info
struct fast_region_info
{
int start;
int end;
int start; //exclude
int end; //include
int step;
int alloc_elements_once;
int pad_mask; //for internal use
@ -60,6 +60,14 @@ struct fast_allocator_context
bool need_lock; //if need mutex lock for acontext
};
#define FAST_ALLOCATOR_INIT_REGION(region, _start, _end, _step, _alloc_once) \
do { \
region.start = _start; \
region.end = _end; \
region.step = _step; \
region.alloc_elements_once = _alloc_once; \
} while(0)
#ifdef __cplusplus
extern "C" {
#endif

View File

@ -793,6 +793,47 @@ int splitEx(char *src, const char seperator, char **pCols, const int nMaxCols)
return count;
}
int split_string_ex(const string_t *src, const char seperator,
string_t *dest, const int max_count, const bool ignore_empty)
{
const char *p;
string_t *current;
int len;
p = src->str;
len = src->len;
current = dest;
while (true)
{
if ((int)(current - dest) >= max_count)
{
break;
}
current->str = (char *)p;
p = memchr(p, seperator, len);
if (p == NULL)
{
if (len > 0 || !ignore_empty)
{
current->len = len;
current++;
}
break;
}
current->len = (char *)p - current->str;
len -= current->len + 1;
if (current->len > 0 || !ignore_empty)
{
current++;
}
p++;
}
return (int)(current - dest);
}
bool fc_match_delim(const char *str, const char *delim)
{
const char *sp;

View File

@ -392,6 +392,18 @@ void freeSplit(char **p);
int splitEx(char *src, const char seperator, char **pCols, const int nMaxCols);
/** split string
* parameters:
* src: the source string
* seperator: seperator char
* dest: store split strings
* max_count: max split count
* ignore_empty: if ignore empty string
* return: string array count
*/
int split_string_ex(const string_t *src, const char seperator,
string_t *dest, const int max_count, const bool ignore_empty);
/** split string by delimiter characters
* parameters:
* src: the source string, will be modified by this function

View File

@ -7,7 +7,7 @@ LIB_PATH = -lfastcommon -lpthread
ALL_PRGS = test_allocator test_skiplist test_multi_skiplist test_mblock test_blocked_queue \
test_id_generator test_ini_parser test_char_convert test_char_convert_loader \
test_logger test_skiplist_set test_crc32 test_thourands_seperator test_sched_thread \
test_json_parser test_pthread_lock test_uniq_skiplist
test_json_parser test_pthread_lock test_uniq_skiplist test_split_string
all: $(ALL_PRGS)
.c:

View File

@ -0,0 +1,65 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <time.h>
#include <limits.h>
#include <errno.h>
#include <inttypes.h>
#include <sys/time.h>
#include "fastcommon/logger.h"
#include "fastcommon/shared_func.h"
#include "fastcommon/sched_thread.h"
#include "fastcommon/ini_file_reader.h"
#include "fastcommon/fast_allocator.h"
#define MAX_PATH_COUNT 100
int main(int argc, char *argv[])
{
string_t path;
string_t paths[MAX_PATH_COUNT];
char new_path[PATH_MAX];
int count;
int i;
int len;
bool ignore_empty = false;
log_init();
srand(time(NULL));
g_log_context.log_level = LOG_DEBUG;
if (argc < 2) {
fprintf(stderr, "Usage: %s <path> [ignore_empty=false]\n", argv[0]);
return EINVAL;
}
FC_SET_STRING(path, argv[1]);
if (path.len >= PATH_MAX) {
fprintf(stderr, "path length: %d exceeds %d\n", path.len, PATH_MAX);
return ENAMETOOLONG;
}
if (argc > 2) {
ignore_empty = FAST_INI_STRING_IS_TRUE(argv[2]);
}
count = split_string_ex(&path, '/', paths, MAX_PATH_COUNT, ignore_empty);
if (ignore_empty && (path.len > 0 && path.str[0] == '/')) {
strcpy(new_path, "/");
len = 1;
} else {
*new_path = '\0';
len = 0;
}
if (count > 0) {
len += sprintf(new_path + len, "%.*s", paths[0].len, paths[0].str);
for (i=1; i<count; i++) {
len += sprintf(new_path + len, "/%.*s", paths[i].len, paths[i].str);
}
}
printf("count: %d, path: %s, length: %d\n",
count, new_path, len);
return 0;
}

View File

@ -194,7 +194,7 @@ int main(int argc, char *argv[])
return result;
}
sl = uniq_skiplist_new(&factory, 2);
sl = uniq_skiplist_new(&factory, 8);
if (sl == NULL) {
return ENOMEM;
}

View File

@ -56,7 +56,7 @@ extern "C" {
#define uniq_skiplist_init(factory, max_level_count, compare_func, free_func) \
uniq_skiplist_init_ex(factory, max_level_count, \
compare_func, free_func, 64 * 1024, \
SKIPLIST_DEFAULT_MIN_ALLOC_ELEMENTS_ONCE)
SKIPLIST_DEFAULT_MIN_ALLOC_ELEMENTS_ONCE, 0)
int uniq_skiplist_init_ex(UniqSkiplistFactory *factory,
const int max_level_count, skiplist_compare_func compare_func,