Browse code

optimalizations of string and dstring functions

Vaclav Kubart authored on 28/06/2006 15:22:37
Showing 10 changed files
... ...
@@ -1,3 +1,8 @@
1
+2006-06-28
2
+	* optimalization of dstring operations (internal buffers allocated in PKG
3
+	memory, some functions changed to macros, added function dstr_get_str_pkg)
4
+	* some str functions changed to macros
5
+
1 6
 2006-06-23
2 7
 	* added function requires_extension
3 8
 
4 9
deleted file mode 100644
... ...
@@ -1,138 +0,0 @@
1
-/* 
2
- * Copyright (C) 2005 iptelorg GmbH
3
- *
4
- * This file is part of ser, a free SIP server.
5
- *
6
- * ser is free software; you can redistribute it and/or modify
7
- * it under the terms of the GNU General Public License as published by
8
- * the Free Software Foundation; either version 2 of the License, or
9
- * (at your option) any later version
10
- *
11
- * For a license to use the ser software under conditions
12
- * other than those described here, or to purchase support for this
13
- * software, please contact iptel.org by e-mail at the following addresses:
14
- *    info@iptel.org
15
- *
16
- * ser is distributed in the hope that it will be useful,
17
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
18
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19
- * GNU General Public License for more details.
20
- *
21
- * You should have received a copy of the GNU General Public License
22
- * along with this program; if not, write to the Free Software
23
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
24
- */
25
-
26
-#include <cds/dlink.h>
27
-#include <cds/memory.h>
28
-#include <stdlib.h>
29
-
30
-dlink_element_t *dlink_element_alloc(int _data_length)
31
-{
32
-	dlink_element_t *e = (dlink_element_t*)cds_malloc(_data_length + sizeof(dlink_element_t)); /* shm */
33
-	if (e) {
34
-		e->data_length = _data_length;
35
-		e->next = NULL;
36
-		e->prev = NULL;
37
-	}
38
-	return e;
39
-}
40
-
41
-void dlink_element_free(dlink_element_t *e)
42
-{
43
-	if (e) cds_free(e); /* shm */
44
-}
45
-
46
-/* dlink_element_t *dlink_element_alloc_pkg(int _data_length)
47
-{
48
-	dlink_element_t *e = (dlink_element_t*)DLINK_PKG_ALLOC(_data_length + sizeof(dlink_element_t));
49
-	if (e) {
50
-		e->data_length = _data_length;
51
-		e->next = NULL;
52
-		e->prev = NULL;
53
-	}
54
-	return e;
55
-}
56
-
57
-void dlink_element_free_pkg(dlink_element_t *e) 
58
-{
59
-	if (e) DLINK_PKG_FREE(e);
60
-} */
61
-
62
-char* dlink_element_data(dlink_element_t *e)
63
-{
64
-	if (e) return e->data;
65
-	else return NULL;
66
-}
67
-
68
-
69
-void dlink_init(dlink_t *l) 
70
-{
71
-	if (l) {
72
-		l->first = NULL;
73
-		l->last = NULL;
74
-	}
75
-}
76
-
77
-void dlink_add(dlink_t *l, dlink_element_t *e)
78
-{
79
-	if ( (!l) || (!e) ) return;
80
-	
81
-	e->next = NULL;
82
-	if (!l->last) {
83
-		l->first = e;
84
-		e->prev = NULL;
85
-	}
86
-	else {
87
-		l->last->next = e;
88
-		e->prev = l->last;
89
-	}
90
-	l->last = e;
91
-}
92
-
93
-void dlink_remove(dlink_t *l, dlink_element_t *e)
94
-{
95
-	if ((!l) || (!e)) return;
96
-
97
-	if (e == l->first) l->first = e->next;
98
-	if (e == l->last) l->last = e->prev;
99
-	
100
-	if (e->prev) e->prev->next = e->next;
101
-	if (e->next) e->next->prev = e->prev;
102
-	
103
-	e->next = NULL;
104
-	e->prev = NULL;
105
-}
106
-
107
-dlink_element_t *dlink_start_walk(dlink_t *l) { if (l) return l->first; else return NULL; }
108
-dlink_element_t *dlink_next_element(dlink_element_t *e) { if (e) return e->next; else return NULL; }
109
-dlink_element_t *dlink_prev_element(dlink_element_t *e) { if (e) return e->prev; else return NULL; }
110
-
111
-dlink_element_t *dlink_last_element(dlink_t *l) 
112
-{
113
-	if (l) return l->last;
114
-	else return NULL;
115
-}
116
-
117
-void dlink_destroy(dlink_t *l)
118
-{
119
-	dlink_element_t *e,*n;
120
-	e = dlink_start_walk(l);
121
-	while (e) {
122
-		n = dlink_next_element(e);
123
-		dlink_element_free(e);
124
-		e = n;
125
-	}
126
-}
127
-/*
128
-void dlink_destroy_pkg(dlink_t *l)
129
-{
130
-	dlink_element_t *e,*n;
131
-	e = dlink_start_walk(l);
132
-	while (e) {
133
-		n = dlink_next_element(e);
134
-		dlink_element_free_pkg(e);
135
-		e = n;
136
-	}
137
-}
138
-*/
139 0
deleted file mode 100644
... ...
@@ -1,100 +0,0 @@
1
-/* 
2
- * Copyright (C) 2005 iptelorg GmbH
3
- *
4
- * This file is part of ser, a free SIP server.
5
- *
6
- * ser is free software; you can redistribute it and/or modify
7
- * it under the terms of the GNU General Public License as published by
8
- * the Free Software Foundation; either version 2 of the License, or
9
- * (at your option) any later version
10
- *
11
- * For a license to use the ser software under conditions
12
- * other than those described here, or to purchase support for this
13
- * software, please contact iptel.org by e-mail at the following addresses:
14
- *    info@iptel.org
15
- *
16
- * ser is distributed in the hope that it will be useful,
17
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
18
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19
- * GNU General Public License for more details.
20
- *
21
- * You should have received a copy of the GNU General Public License
22
- * along with this program; if not, write to the Free Software
23
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
24
- */
25
-
26
-#ifndef __DLINK_H
27
-#define __DLINK_H
28
-
29
-#include <stdio.h>
30
-
31
-/** 
32
- * \defgroup dlink Universal double linked lists
33
- *
34
- */
35
-
36
-/**
37
- * One element of dynamic linked list. Each element 
38
- * can carry an arbitrary data element, which is allocated 
39
- * together with extra data needed for linking 
40
- * (pointers to next and previous elements).
41
- */
42
-typedef struct dlink_element {
43
-	struct dlink_element *next;
44
-	struct dlink_element *prev;
45
-	
46
-	int data_length;
47
-	/** data array of unspecified size */
48
-	char data[1];
49
-} dlink_element_t;
50
-
51
-dlink_element_t *dlink_element_alloc(int _data_length);
52
-void dlink_element_free(dlink_element_t *e);
53
-/* dlink_element_t *dlink_element_alloc_pkg(int _data_length);
54
-void dlink_element_free_pkg(dlink_element_t *e); */
55
-char* dlink_element_data(dlink_element_t *e);
56
-
57
-/**
58
- * Structure carying information about linked list.
59
- */
60
-typedef struct dlink {
61
-	/** Pointer to the first element of this list. */
62
-	dlink_element_t *first;
63
-	
64
-	/** Pointer to the last element of this list due 
65
-	 * to more effective adding to the end of the list */	
66
-	dlink_element_t *last;
67
-
68
-	/* TODO: add some members for monitoring, ...
69
-	 * add hash map?
70
-	 */
71
-} dlink_t;
72
-
73
-/**
74
- * Initializes dlink structure - clears pointers to the
75
- * start and end of the link and so on.
76
- */
77
-void dlink_init(dlink_t *l);
78
-
79
-/** destroys all elements in shared memory */
80
-void dlink_destroy(dlink_t *l);
81
-
82
-/* destroys all elements in pkg memory */
83
-/* void dlink_destroy_pkg(dlink_t *l); */
84
-
85
-/** Adds one (only one!) element e to the end of the link l. */
86
-void dlink_add(dlink_t *l, dlink_element_t *e);
87
-
88
-/** Removes an element e from the link. */
89
-void dlink_remove(dlink_t *l, dlink_element_t *e);
90
-
91
-/** Thiss method initiates walking through the list.
92
- * It returns a pointer to the first element of the link. */
93
-dlink_element_t *dlink_start_walk(dlink_t *l);
94
-
95
-dlink_element_t *dlink_last_element(dlink_t *l);
96
-
97
-dlink_element_t *dlink_next_element(dlink_element_t *e);
98
-dlink_element_t *dlink_prev_element(dlink_element_t *e);
99
-
100
-#endif
... ...
@@ -28,7 +28,8 @@ multiple strings without worry about memory allocations.</para>
28 28
 
29 29
 <para>Internaly it uses list of data buffers which are allocated 
30 30
 if needed. The content of dynamic string may be copied out from internal buffers
31
-using simple function call (see <xref linkend="dstr_get_data"/>).
31
+using simple function call (see <xref linkend="dstr_get_data"/>). Internal
32
+buffers are allocated in package memory (when compiled with SER)!
32 33
 </para>
33 34
 
34 35
 <para>This structure is used as base for simple object serialization (see <xref
... ...
@@ -27,26 +27,28 @@
27 27
 #include <string.h>
28 28
 #include <cds/dstring.h>
29 29
 #include <cds/memory.h>
30
+#include <cds/list.h>
31
+#include <cds/logger.h>
30 32
 
31
-static dstr_buff_t *get_current_buffer(dstring_t *dstr) 
32
-{
33
-	dstr_buff_t *buff;
34
-	buff = (dstr_buff_t*)dlink_element_data(dlink_last_element(&dstr->buffers));
35
-	return buff;
36
-}
33
+#define get_current_buffer(dstr) (dstr)->last
37 34
 
38 35
 static dstr_buff_t *add_new_buffer(dstring_t *dstr) 
39 36
 {
40 37
 	dstr_buff_t *buff = NULL;
41
-	dlink_element_t *e;
42 38
 	
43 39
 	/* e = dlink_element_alloc_pkg(sizeof(dstr_buff_t) + dstr->buff_size); */
44
-	e = dlink_element_alloc(sizeof(dstr_buff_t) + dstr->buff_size);
45
-	if (e) {
46
-		buff = (dstr_buff_t*)dlink_element_data(e);
40
+/*	if (dstr->flags & DSTR_PKG_MEM)
41
+		buff = cds_malloc_pkg(sizeof(dstr_buff_t) + dstr->buff_size);
42
+	else
43
+		buff = cds_malloc(sizeof(dstr_buff_t) + dstr->buff_size);
44
+		*/
45
+/*	buff = cds_malloc(sizeof(dstr_buff_t) + dstr->buff_size);*/
46
+	buff = cds_malloc_pkg(sizeof(dstr_buff_t) + dstr->buff_size);
47
+	if (buff) {
47 48
 		buff->len = dstr->buff_size;
48 49
 		buff->used = 0;
49
-		dlink_add(&dstr->buffers, e);
50
+		buff->next = NULL;
51
+		LINKED_LIST_ADD(dstr->first, dstr->last, buff);
50 52
 	}
51 53
 	else dstr->error = 1;
52 54
 	return buff;
... ...
@@ -57,7 +59,7 @@ int dstr_append(dstring_t *dstr, const char *s, int len)
57 59
 	int size;
58 60
 	dstr_buff_t *buff;
59 61
 
60
-	if (!dstr) return -1;
62
+/*	if (!dstr) return -1; */
61 63
 	if (dstr->error) return -2;
62 64
 
63 65
 	if (len == 0) return 0; /*append empty string*/
... ...
@@ -83,38 +85,36 @@ int dstr_append(dstring_t *dstr, const char *s, int len)
83 85
 
84 86
 int dstr_append_zt(dstring_t *dstr, const char *s)
85 87
 {
86
-	if (!dstr) return -1;
88
+/*	if (!dstr) return -1; */
87 89
 	if (!s) return 0; /*append empty string*/
88 90
 	return dstr_append(dstr, s, strlen(s));
89 91
 }
90 92
 
91 93
 int dstr_append_str(dstring_t *dstr, const str_t *s)
92 94
 {
93
-	if (!dstr) return -1;
95
+/*	if (!dstr) return -1; */
94 96
 	if (!s) return 0; /*append empty string*/
95 97
 	return dstr_append(dstr, s->s, s->len);
96 98
 }
97 99
 
98
-int dstr_get_data_length(dstring_t *dstr)
100
+/* int dstr_get_data_length(dstring_t *dstr)
99 101
 {
100 102
 	if (!dstr) return 0;
101 103
 	else return dstr->len;
102
-}
104
+} */
103 105
 
104 106
 int dstr_get_data(dstring_t *dstr, char *dst)
105 107
 {
106
-	dlink_element_t *e;
107 108
 	dstr_buff_t* buff;
108 109
 	
109
-	if (!dstr) return -1;
110
+	/* if (!dstr) return -1; */
110 111
 	if (dstr->error) return -2; /* a previous operation returned error */
111 112
 	
112
-	e = dlink_start_walk(&dstr->buffers);
113
-	while (e) {
114
-		buff = (dstr_buff_t*)dlink_element_data(e);
113
+	buff = dstr->first;
114
+	while (buff) {
115 115
 		memcpy(dst, buff->data, buff->used);
116 116
 		dst += buff->used;
117
-		e = dlink_next_element(e);
117
+		buff = buff->next;
118 118
 	}
119 119
 	return 0;
120 120
 }
... ...
@@ -125,7 +125,8 @@ int dstr_get_str(dstring_t *dstr, str_t *dst)
125 125
 	
126 126
 	if (!dst) return -1;
127 127
 	if (dstr->error) {
128
-		str_clear(dst);
128
+		dst->s = NULL;
129
+		dst->len = 0;
129 130
 		return -2; /* a previous operation returned error */
130 131
 	}
131 132
 
... ...
@@ -135,7 +136,6 @@ int dstr_get_str(dstring_t *dstr, str_t *dst)
135 136
 		if (!dst->s) {
136 137
 			res = -1;
137 138
 			dst->len = 0;
138
-			dst->s = NULL;
139 139
 		}
140 140
 		else res = dstr_get_data(dstr, dst->s);
141 141
 	} 
... ...
@@ -147,34 +147,65 @@ int dstr_get_str(dstring_t *dstr, str_t *dst)
147 147
 	return res;
148 148
 }
149 149
 
150
+int dstr_get_str_pkg(dstring_t *dstr, str_t *dst)
151
+{
152
+	int res = 0;
153
+	
154
+	if (!dst) return -1;
155
+	if (dstr->error) {
156
+		dst->s = NULL;
157
+		dst->len = 0;
158
+		return -2; /* a previous operation returned error */
159
+	}
160
+
161
+	dst->len = dstr_get_data_length(dstr);
162
+	if (dst->len > 0) {
163
+		dst->s = (char*)cds_malloc_pkg(dst->len);
164
+		if (!dst->s) {
165
+			res = -1;
166
+			dst->len = 0;
167
+		}
168
+		else res = dstr_get_data(dstr, dst->s);
169
+	} 
170
+	else {
171
+		dst->s = NULL;
172
+		dst->len = 0;
173
+	}
174
+
175
+	return res;
176
+}
150 177
 
151 178
 int dstr_init(dstring_t *dstr, int buff_size)
152 179
 {
153
-	if (!dstr) return -1;
180
+	/* if (!dstr) return -1; */
154 181
 	dstr->buff_size = buff_size;
155 182
 	dstr->len = 0;
156 183
 	dstr->error = 0;
157
-	dlink_init(&dstr->buffers);
184
+	dstr->first = 0;
185
+	dstr->last = 0;
158 186
 	return 0;
159 187
 }
160 188
 
161 189
 int dstr_destroy(dstring_t *dstr)
162 190
 {
163
-	dlink_element_t *e,*n;
164
-	if (!dstr) return -1;
191
+	dstr_buff_t *e,*n;
192
+/*	if (!dstr) return -1; */
165 193
 	/* dlink_destroy(&dstr->buffers); */
166
-	e = dlink_start_walk(&dstr->buffers);
194
+	e = dstr->first;
167 195
 	while (e) {
168
-		n = dlink_next_element(e);
169
-		dlink_remove(&dstr->buffers, e);
170
-		dlink_element_free(e);
171
-		/* dlink_element_free_pkg(e); */
196
+		n = e->next;
197
+/*		if (dstr->flags & DSTR_PKG_MEM) cds_free_pkg(e);
198
+		else cds_free(e);*/
199
+/*		cds_free(e);*/
200
+		cds_free_pkg(e);
172 201
 		e = n;
173 202
 	}
203
+	dstr->first = 0;
204
+	dstr->last = 0;
174 205
 	return 0;
175 206
 }
176 207
 
177
-int dstr_error(dstring_t *dstr)
208
+/* int dstr_error(dstring_t *dstr)
178 209
 {
179 210
 	if (dstr) return dstr->error;
180 211
 	else return -1;
... ...
@@ -184,4 +215,4 @@ void dstr_clear_error(dstring_t *dstr)
184 215
 {
185 216
 	if (dstr) dstr->error = 0;
186 217
 }
187
-
218
+*/
... ...
@@ -27,22 +27,26 @@
27 27
 #define __DSTRING_H
28 28
 
29 29
 #include <cds/sstr.h>
30
-#include <cds/dlink.h>
31 30
 
32 31
 #ifdef __cplusplus
33 32
 extern "C" {
34 33
 #endif
35 34
 
36
-typedef struct dstr_buff {
35
+typedef struct _dstr_buff_t {
37 36
 	int len;
38 37
 	int used;
38
+	struct _dstr_buff_t *next; /* pointer to next buffer */
39 39
 	char data[1];
40 40
 } dstr_buff_t;
41 41
 
42 42
 /** Dynamic string structure. It is used
43
- * for muliple appends of any strings. */
43
+ * for muliple appends of any strings. 
44
+ *
45
+ * There was an attempt to add flags for SHM/PKG memory using, ...
46
+ * but it shows that it slows down, thus they were removed and only the
47
+ * "most quick" version is used (rather two functions than one with param) */
44 48
 typedef struct _dstring_t {
45
-	dlink_t buffers;
49
+	dstr_buff_t *first, *last;
46 50
 	/** the length of whole string */
47 51
 	int len;
48 52
 	int buff_size;
... ...
@@ -54,15 +58,20 @@ typedef struct _dstring_t {
54 58
 int dstr_append_zt(dstring_t *dstr, const char *s);
55 59
 int dstr_append(dstring_t *dstr, const char *s, int len);
56 60
 int dstr_append_str(dstring_t *dstr, const str_t *s);
57
-int dstr_get_data_length(dstring_t *dstr);
61
+/* int dstr_get_data_length(dstring_t *dstr); */
58 62
 int dstr_get_data(dstring_t *dstr, char *dst);
59 63
 int dstr_get_str(dstring_t *dstr, str_t *dst);
64
+int dstr_get_str_pkg(dstring_t *dstr, str_t *dst);
60 65
 int dstr_init(dstring_t *dstr, int buff_size);
61 66
 int dstr_destroy(dstring_t *dstr);
62 67
 
63 68
 /* returns nozero if error !!! */
64
-int dstr_error(dstring_t *dstr);
65
-void dstr_clear_error(dstring_t *dstr);
69
+/* int dstr_error(dstring_t *dstr);
70
+void dstr_clear_error(dstring_t *dstr); */
71
+
72
+#define dstr_get_data_length(dstr) (dstr)->len
73
+#define dstr_error(dstr) (dstr)->error
74
+#define dstr_clear_error(dstr) (dstr)->error = 0
66 75
 
67 76
 #ifdef __cplusplus
68 77
 }
... ...
@@ -56,6 +56,8 @@ void cds_memory_trace_init();
56 56
 #define cds_free(p)		debug_free(p,__FILE__, __LINE__)
57 57
 #define cds_free_ptr	debug_free_ex
58 58
 #define cds_malloc_ptr	debug_malloc_ex
59
+#define cds_malloc_pkg(s)	debug_malloc(s,__FILE__, __LINE__)
60
+#define cds_free_pkg(p)		debug_free(p,__FILE__, __LINE__)
59 61
 
60 62
 #else /* !TRACE */
61 63
 
... ...
@@ -71,6 +73,8 @@ void shm_free_x(void *ptr);
71 73
 #define cds_free(p)		shm_free(p)
72 74
 #define cds_malloc_ptr	shm_malloc_x
73 75
 #define cds_free_ptr	shm_free_x
76
+#define cds_malloc_pkg(s)	pkg_malloc(s)
77
+#define cds_free_pkg(p)		pkg_free(p)
74 78
 
75 79
 #else /* !SER */
76 80
 
... ...
@@ -80,6 +84,8 @@ void shm_free_x(void *ptr);
80 84
 #define cds_free(p)		free(p)
81 85
 #define cds_malloc_ptr	malloc
82 86
 #define cds_free_ptr	free
87
+#define cds_malloc_pkg(s)	malloc(s)
88
+#define cds_free_pkg(p)		free(p)
83 89
 
84 90
 #endif /* !SER */
85 91
 
... ...
@@ -25,6 +25,7 @@
25 25
 
26 26
 #include <cds/serialize.h>
27 27
 #include <cds/logger.h>
28
+#include <stdio.h>
28 29
 
29 30
 int init_input_sstream(sstream_t *ss, char *data_in, int data_len)
30 31
 {
... ...
@@ -182,7 +182,7 @@ void str_free(str_t *s)
182 182
 		str_free_content(s);
183 183
 		cds_free(s);
184 184
 	}
185
-}*/
185
+}
186 186
 
187 187
 void str_clear(str_t *s)
188 188
 {
... ...
@@ -190,7 +190,7 @@ void str_clear(str_t *s)
190 190
 		s->s = NULL;
191 191
 		s->len = 0;
192 192
 	}
193
-}
193
+} */
194 194
 
195 195
 char *str_strchr(const str_t *s, char c)
196 196
 {
... ...
@@ -73,18 +73,25 @@ char *zt_strdup(const char*src);
73 73
 
74 74
 /** frees string content if allocated */
75 75
 /* void str_free_content(str_t *s); */
76
-#define str_free_content(str)	if (str) { \
76
+#define str_free_content(str)	do { if (str) { \
77 77
 		if (((str)->len > 0) && ((str)->s)) cds_free((str)->s);\
78 78
 		(str)->len = 0; \
79 79
 		(str)->s = 0; \
80
-	}
80
+	} } while (0)
81 81
 
82 82
 /** frees string content if allocated and then the string itself */
83 83
 /* void str_free(str_t *s); */
84
-#define str_free(str)	if (str) { \
85
-		str_free_content(str); \
84
+#define str_free(str)	do { if (str) { \
85
+		if (((str)->len > 0) && ((str)->s)) cds_free((str)->s);\
86 86
 		cds_free(str); \
87
-	}
87
+	} } while (0)
88
+
89
+/* clears string content */
90
+#define str_clear(str)	do { if (str) { \
91
+		(str)->len = 0; \
92
+		(str)->s = 0; \
93
+	} } while (0)
94
+
88 95
 
89 96
 /** case sensitive comparation - returns 0 if equal, nonzero otherwise */
90 97
 int str_case_equals(const str_t *a, const str_t *b);
... ...
@@ -99,7 +106,7 @@ int str_prefix(const str_t *a, const str_t *b); /* ss_start */
99 106
 
100 107
 /* #define ss_cmp(const str_t *a, const str_t *b) ((a->len == b->len)?sz_cmp(a, b->s):(-1)) */
101 108
 
102
-void str_clear(str_t *s);
109
+/* void str_clear(str_t *s); */
103 110
 
104 111
 /** locate character in string */
105 112
 char *str_strchr(const str_t *s, char c);