您的位置:首页 > 理论基础 > 数据结构算法

Twemproxy源码分析(四)数据结构(array和string)

2015-08-05 10:03 671 查看


概述:

本节我们介绍Twemproxy的两个重要的自定义数据结构:array和string。


array:

故名思议,array就是数组,array的代码在nc_array.c和nc_array.h中,我们先来看看array的结构:


数据结构:

123456struct array { uint32_t nelem; /* # element */ void *elem; /* element */ size_t size; /* element size */ uint32_t nalloc; /* # allocated element */};
array的结构包含:当前数组中元素的数量
指向元素的void指针
元素的大小
预申请的空间的元素数
由此可见,array应该具有以下特点:需要预申请空间,空间不足则需要重新申请
数组每个元素大小必须相同
后面我们将通过数组的操作验证。

操作:

对数组的操作包含下面这些,这些都是在nc_array.h中声明和定义的:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

/** 将数组置为null **/

static
inline
void

array_null(struct
array
*a)

{

a->nelem
=
0;

a->elem
=
NULL;

a->size
=
0;

a->nalloc
=
0;

}



/** 设置一个数组struct的值 **/

static
inline
void

array_set(struct
array
*a,
void
*elem,
size_t
size,
uint32_t
nalloc)

{

a->nelem
=
0;

a->elem
=
elem;

a->size
=
size;

a->nalloc
=
nalloc;

}



/** 返回数组的元素数 **/

static
inline
uint32_t

array_n(const
struct
array
*a)

{

return
a->nelem;

}



struct
array
*array_create(uint32_t
n,
size_t
size); //创建包含n个大小为size的elements的数组

void
array_destroy(struct
array
*a); //销毁一个数组

rstatus_t
array_init(struct
array
*a,
uint32_t
n,
size_t
size); //初始化一个数组

void
array_deinit(struct
array
*a); //deinit



uint32_t
array_idx(struct
array
*a,
void
*elem); //返回元素的数组下标

void
*array_push(struct
array
*a); //push一个元素,返回该元素的指针

void
*array_pop(struct
array
*a); //pop一个元素,返回这个元素的指针

void
*array_get(struct
array
*a,
uint32_t
idx); //返回idx位置上的元素

void
*array_top(struct
array
*a);
//返回队尾的元素

void
array_swap(struct
array
*a,
struct
array
*b); //交换两个数组

void
array_sort(struct
array
*a,
array_compare_t
compare); //数组排序

rstatus_t
array_each(struct
array
*a,
array_each_t
func,
void
*data); //数组迭代

接下来我们通过create和push验证一下我们之前的猜想:

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849struct array *array_create(uint32_t n, size_t size){ struct array *a; ASSERT(n != 0 && size != 0); a = nc_alloc(sizeof(*a)); //申请array的空间 if (a == NULL) { return NULL; } a->elem = nc_alloc(n * size); //预申请elements空间 if (a->elem == NULL) { nc_free(a); return NULL; } a->nelem = 0; a->size = size; a->nalloc = n; return a;} void *array_push(struct array *a){ void *elem, *new; size_t size; if (a->nelem == a->nalloc) { /* array已满,重新申请空间,重新申请的大小为原来的2倍 */ size = a->size * a->nalloc; new = nc_realloc(a->elem, 2 * size); if (new == NULL) { return NULL; } a->elem = new; a->nalloc *= 2; } elem = (uint8_t *)a->elem + a->size * a->nelem; a->nelem++; //增加element数 return elem;}
从代码可以看出是如何realloc空间的,这里实现的奇怪的是,push操作是将elements数加1,然后返回末尾的element指针。也就是说,调用者需要先调用array_push得到elements指针,然后为其设置字段值,来完成数组元素的push。另外值得一提的是,array提供了create/destroy和init/deinit这两组创建和销毁函数,这两组函数的区别是:create/destroy同时创建/销毁array和elements空间,而init和deinit只创建/销毁elements空间,看一下array_destroy代码就明白了:

1

2

3

4

5

6

void

array_destroy(struct
array
*a)

{

array_deinit(a);

nc_free(a);

}

array的代码很少,只有200多行,就不详细介绍其他的操作了。


string:

string的代码在nc_string.c和nc_string.h中,封装了一些对字符串的操作。


数据结构:

1234struct string { uint32_t len; /* string length */ uint8_t *data; /* string data */};
string的结构包含两个字段:字符串的长度、指向字符串的指针,就这么简单。

操作:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

/** set字符串 **/

#define string_set_text(_str, _text) do { \

(_str)->len
=
(uint32_t)(sizeof(_text)
-
1);\

(_str)->data
=
(uint8_t
*)(_text); \

}
while
(0);



/** set字符串 **/

#define string_set_raw(_str, _raw) do { \

(_str)->len
=
(uint32_t)(nc_strlen(_raw)); \

(_str)->data
=
(uint8_t
*)(_raw);
\

}
while
(0);



void
string_init(struct
string
*str); //初始化string

void
string_deinit(struct
string
*str); //dinit

bool
string_empty(const
struct
string
*str); //判断字符串是否是空

rstatus_t
string_duplicate(struct
string
*dst,
const
struct
string
*src); //duplicate一个字符串

rstatus_t
string_copy(struct
string
*dst,
const
uint8_t *src,
uint32_t
srclen); //copy一个字符串

int
string_compare(const
struct
string
*s1,
const
struct
string
*s2); //字符串比较

底下还有用宏定义的一些操作,不过都是操作char*的,这里就不列举了。总的来说string的结构很简单,代码也只有100多行。


小结:

本节我们看了一下array和string这两个数据结构,都很简单,后面我们马上会用到。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: