UltraGrid
UltraGrid Low-Latency High-Resolution Transmission System
Loading...
Searching...
No Matches
pdb.c
Go to the documentation of this file.
1/*
2 * FILE: pdb.c - Participant database
3 * AUTHOR: Colin Perkins <csp@csperkins.org>
4 * Orion Hodson
5 * Martin Benes <martinbenesh@gmail.com>
6 * Lukas Hejtmanek <xhejtman@ics.muni.cz>
7 * Petr Holub <hopet@ics.muni.cz>
8 * Milos Liska <xliska@fi.muni.cz>
9 * Jiri Matela <matela@ics.muni.cz>
10 * Dalibor Matura <255899@mail.muni.cz>
11 * Ian Wesley-Smith <iwsmith@cct.lsu.edu>
12 *
13 * Copyright (c) 2004 University of Glasgow
14 * Copyright (c) 2002-2003 University of Southern California
15 * Copyright (c) 1999-2000 University College London
16 * Copyright (c) 2005-2016 CESNET z.s.p.o.
17 *
18 * Largely based on common/src/btree.c revision 1.7 from the UCL
19 * Robust-Audio Tool v4.2.25. Code is based on the algorithm in:
20 *
21 * Introduction to Algorithms by Corman, Leisserson, and Rivest,
22 * MIT Press / McGraw Hill, 1990.
23 *
24 * Redistribution and use in source and binary forms, with or without
25 * modification, is permitted provided that the following conditions
26 * are met:
27 *
28 * 1. Redistributions of source code must retain the above copyright
29 * notice, this list of conditions and the following disclaimer.
30 *
31 * 2. Redistributions in binary form must reproduce the above copyright
32 * notice, this list of conditions and the following disclaimer in the
33 * documentation and/or other materials provided with the distribution.
34 *
35 * 3. All advertising materials mentioning features or use of this software
36 * must display the following acknowledgement:
37 *
38 * This product includes software developed by the University of Southern
39 * California Information Sciences Institute. This product also includes
40 * software developed by CESNET z.s.p.o.
41 *
42 * 4. Neither the name of the University, Institute, CESNET nor the names of
43 * its contributors may be used to endorse or promote products derived from
44 * this software without specific prior written permission.
45 *
46 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS
47 * "AS IS" AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING,
48 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
49 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
50 * EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
51 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
52 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
53 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
54 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
55 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
56 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
57 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
58 *
59 * $Revision: 1.4 $
60 * $Date: 2009/12/11 15:29:39 $
61 */
62
63#include "config.h"
64#include "config_unix.h"
65#include "config_win32.h"
66#include "debug.h"
67#include "rtp/rtp.h" /* Needed by pbuf.h */
68#include "rtp/pbuf.h"
69#include "tfrc.h"
70#include "pdb.h"
71
72#define PDB_MAGIC 0x10101010
73#define PDB_NODE_MAGIC 0x01010101
74
75typedef struct s_pdb_node {
76 uint32_t key;
77 void *data;
81 uint32_t magic;
83
84struct pdb {
86 uint32_t magic;
87 int count;
88 volatile int *delay_ms;
89};
90
91/*****************************************************************************/
92/* Debugging functions... */
93/*****************************************************************************/
94
95#define BTREE_MAGIC 0x10101010
96#define BTREE_NODE_MAGIC 0x01010101
97
98#ifdef DEBUG
99static
100#ifndef __APPLE__
101__thread
102#endif
103int pdb_count;
104
105static void pdb_validate_node(pdb_node_t * node, pdb_node_t * parent)
106{
107 assert(node->magic == BTREE_NODE_MAGIC);
108 assert(node->parent == parent);
109 pdb_count++;
110 if (node->left != NULL) {
111 pdb_validate_node(node->left, node);
112 }
113 if (node->right != NULL) {
114 pdb_validate_node(node->right, node);
115 }
116}
117#endif
118
119static void pdb_validate(struct pdb *t)
120{
121 assert(t->magic == BTREE_MAGIC);
122#ifdef DEBUG
123 pdb_count = 0;
124 if (t->root != NULL) {
125 pdb_validate_node(t->root, NULL);
126 }
127 assert(pdb_count == t->count);
128#endif
129}
130
131/*****************************************************************************/
132/* Utility functions */
133/*****************************************************************************/
134
136{
137 if (x == NULL) {
138 return NULL;
139 }
140 while (x->left) {
141 x = x->left;
142 }
143 return x;
144}
145
147{
148 pdb_node_t *y;
149
150 if (x->right != NULL) {
151 return pdb_min(x->right);
152 }
153
154 y = x->parent;
155 while (y != NULL && x == y->right) {
156 x = y;
157 y = y->parent;
158 }
159
160 return y;
161}
162
163static pdb_node_t *pdb_search(pdb_node_t * x, uint32_t key)
164{
165 while (x != NULL && key != x->key) {
166 if (key < x->key) {
167 x = x->left;
168 } else {
169 x = x->right;
170 }
171 }
172 return x;
173}
174
175static void pdb_insert_node(struct pdb *tree, pdb_node_t * z)
176{
177 pdb_node_t *x, *y;
178
179 pdb_validate(tree);
180 y = NULL;
181 x = tree->root;
182 while (x != NULL) {
183 y = x;
184 assert(z->key != x->key);
185 if (z->key < x->key) {
186 x = x->left;
187 } else {
188 x = x->right;
189 }
190 }
191
192 z->parent = y;
193 if (y == NULL) {
194 tree->root = z;
195 } else if (z->key < y->key) {
196 y->left = z;
197 } else {
198 y->right = z;
199 }
200 tree->count++;
201 pdb_validate(tree);
202}
203
204static pdb_node_t *pdb_delete_node(struct pdb *tree, pdb_node_t * z)
205{
206 pdb_node_t *x, *y;
207
208 pdb_validate(tree);
209 if (z->left == NULL || z->right == NULL) {
210 y = z;
211 } else {
212 y = pdb_successor(z);
213 }
214
215 if (y->left != NULL) {
216 x = y->left;
217 } else {
218 x = y->right;
219 }
220
221 if (x != NULL) {
222 x->parent = y->parent;
223 }
224
225 if (y->parent == NULL) {
226 tree->root = x;
227 } else if (y == y->parent->left) {
228 y->parent->left = x;
229 } else {
230 y->parent->right = x;
231 }
232
233 z->key = y->key;
234 z->data = y->data;
235
236 tree->count--;
237
238 pdb_validate(tree);
239 return y;
240}
241
242/*****************************************************************************/
243
244struct pdb *pdb_init(volatile int *delay_ms)
245{
246 struct pdb *db = malloc(sizeof(struct pdb));
247 if (db != NULL) {
248 db->magic = PDB_MAGIC;
249 db->count = 0;
250 db->root = NULL;
251 db->delay_ms = delay_ms;
252 }
253 return db;
254}
255
256void pdb_destroy(struct pdb **db_p)
257{
258 struct pdb *db = *db_p;
259
260 pdb_validate(db);
261 if (db->root != NULL) {
262 pdb_iter_t it;
263 struct pdb_e *cp = pdb_iter_init(db, &it);
264 while (cp != NULL) {
265 struct pdb_e *item = NULL;
266 pdb_remove(db, cp->ssrc, &item);
267 cp = pdb_iter_next(&it);
269 }
270 pdb_iter_done(&it);
271 }
272
273 free(db);
274 *db_p = NULL;
275}
276
277static struct pdb_e *pdb_create_item(uint32_t ssrc, volatile int *delay_ms)
278{
279 struct pdb_e *p = malloc(sizeof(struct pdb_e));
280 if (p != NULL) {
282 p->ssrc = ssrc;
283 p->sdes_cname = NULL;
284 p->sdes_name = NULL;
285 p->sdes_email = NULL;
286 p->sdes_phone = NULL;
287 p->sdes_loc = NULL;
288 p->sdes_tool = NULL;
289 p->sdes_note = NULL;
290 p->decoder_state = NULL;
291 p->decoder_state_deleter = NULL;
292 p->pt = 255;
293 p->playout_buffer = pbuf_init(delay_ms);
295 }
296 return p;
297}
298
299int pdb_add(struct pdb *db, uint32_t ssrc)
300{
301 /* Add an item to the participant database, indexed by ssrc. */
302 /* Returns 0 on success, 1 if the participant is already in */
303 /* the database, 2 for other failures. */
304 pdb_node_t *x;
305 struct pdb_e *i;
306
307 pdb_validate(db);
308 x = pdb_search(db->root, ssrc);
309 if (x != NULL) {
310 debug_msg("Item already exists - ssrc %x\n", ssrc);
311 return 1;
312 }
313
314 i = pdb_create_item(ssrc, db->delay_ms);
315 if (i == NULL) {
316 debug_msg("Unable to create database entry - ssrc %x\n", ssrc);
317 return 2;
318 }
319
320 x = (pdb_node_t *) malloc(sizeof(pdb_node_t));
321 x->key = ssrc;
322 x->data = i;
323 x->parent = NULL;
324 x->left = NULL;
325 x->right = NULL;
327 pdb_insert_node(db, x);
328 debug_msg("Added participant %x\n", ssrc);
329 return 0;
330}
331
332struct pdb_e *pdb_get(struct pdb *db, uint32_t ssrc)
333{
334 /* Return a pointer to the item indexed by ssrc, or NULL if */
335 /* the item is not present in the database. */
336 pdb_node_t *x;
337
338 pdb_validate(db);
339 x = pdb_search(db->root, ssrc);
340 if (x != NULL) {
341 return x->data;
342 }
343 return NULL;
344}
345
346int pdb_remove(struct pdb *db, uint32_t ssrc, struct pdb_e **item)
347{
348 /* Remove the item indexed by ssrc. Return zero on success. */
349 pdb_node_t *x;
350
351 pdb_validate(db);
352 x = pdb_search(db->root, ssrc);
353 if (x == NULL) {
354 debug_msg("Item not on tree - ssrc %ul\n", ssrc);
355 *item = NULL;
356 return 1;
357 }
358
359 /* Note value that gets freed is not necessarily the the same as node
360 * that gets removed from tree since there is an optimization to avoid
361 * pointer updates in tree which means sometimes we just copy key and
362 * data from one node to another.
363 */
364 *item = x->data;
365 x = pdb_delete_node(db, x);
366 free(x);
367 return 0;
368}
369
371{
372 if (item) {
373 free(item->sdes_cname);
374 free(item->sdes_name);
375 free(item->sdes_email);
376 free(item->sdes_phone);
377 free(item->sdes_loc);
378 free(item->sdes_tool);
379 free(item->sdes_note);
380 if (item->decoder_state_deleter && item->decoder_state) {
381 item->decoder_state_deleter(item->decoder_state);
382 }
383 pbuf_destroy(item->playout_buffer);
384 tfrc_done(item->tfrc_state);
385 free(item);
386 }
387}
388
389/*
390 * Iterator functions
391 */
392
393struct pdb_e *pdb_iter_init(struct pdb *db, pdb_iter_t *it)
394{
395 if (db->root == NULL) {
396 return NULL; /* The database is empty */
397 }
398 *it = (pdb_node_t *) pdb_min(db->root);
399 return ((pdb_node_t *) *it)->data;
400}
401
403{
404 assert(*it != NULL);
405 *it = (pdb_node_t *)pdb_successor((pdb_node_t *)*it);
406 if (*it == NULL) {
407 return NULL;
408 }
409 return ((pdb_node_t *) *it)->data;
410}
411
413{
414 *it = NULL;
415}
416
#define debug_msg(...)
#define debug_msg(...) log_msg(LOG_LEVEL_DEBUG, "[pid/%d +%d %s] ", getpid(), LINE,...
Definition debug.h:92
void pbuf_destroy(struct pbuf *playout_buf)
Definition pbuf.c:195
struct pbuf * pbuf_init(volatile int *delay_ms)
Definition pbuf.c:174
void pdb_iter_done(pdb_iter_t *it)
Definition pdb.c:412
struct pdb_e * pdb_iter_next(pdb_iter_t *it)
Definition pdb.c:402
struct s_pdb_node pdb_node_t
static struct pdb_e * pdb_create_item(uint32_t ssrc, volatile int *delay_ms)
Definition pdb.c:277
struct pdb_e * pdb_iter_init(struct pdb *db, pdb_iter_t *it)
Definition pdb.c:393
#define BTREE_NODE_MAGIC
Definition pdb.c:96
#define BTREE_MAGIC
Definition pdb.c:95
static void pdb_validate(struct pdb *t)
Definition pdb.c:119
static pdb_node_t * pdb_delete_node(struct pdb *tree, pdb_node_t *z)
Definition pdb.c:204
struct pdb * pdb_init(volatile int *delay_ms)
Definition pdb.c:244
int pdb_add(struct pdb *db, uint32_t ssrc)
Definition pdb.c:299
void pdb_destroy_item(struct pdb_e *item)
Definition pdb.c:370
static pdb_node_t * pdb_min(pdb_node_t *x)
Definition pdb.c:135
void pdb_destroy(struct pdb **db_p)
Definition pdb.c:256
static pdb_node_t * pdb_search(pdb_node_t *x, uint32_t key)
Definition pdb.c:163
static pdb_node_t * pdb_successor(pdb_node_t *x)
Definition pdb.c:146
static void pdb_insert_node(struct pdb *tree, pdb_node_t *z)
Definition pdb.c:175
#define PDB_MAGIC
Definition pdb.c:72
int pdb_remove(struct pdb *db, uint32_t ssrc, struct pdb_e **item)
Definition pdb.c:346
struct pdb_e * pdb_get(struct pdb *db, uint32_t ssrc)
Definition pdb.c:332
void * pdb_iter_t
Definition pdb.h:106
const char * parent
Definition settings.cpp:198
Definition hd-rum.c:27
Definition pdb.h:72
time_ns_t creation_time
Definition pdb.h:86
char * sdes_name
Definition pdb.h:75
char * sdes_loc
Definition pdb.h:78
decoder_state_deleter_t decoder_state_deleter
decoder state deleter
Definition pdb.h:82
char * sdes_note
Definition pdb.h:80
struct tfrc * tfrc_state
Definition pdb.h:85
void * decoder_state
state of decoder for participant
Definition pdb.h:81
char * sdes_tool
Definition pdb.h:79
char * sdes_email
Definition pdb.h:76
uint32_t ssrc
Definition pdb.h:73
char * sdes_phone
Definition pdb.h:77
uint8_t pt
Definition pdb.h:83
char * sdes_cname
Definition pdb.h:74
struct pbuf * playout_buffer
Definition pdb.h:84
Definition pdb.c:84
int count
Definition pdb.c:87
uint32_t magic
Definition pdb.c:86
volatile int * delay_ms
Definition pdb.c:88
pdb_node_t * root
Definition pdb.c:85
struct s_pdb_node * left
Definition pdb.c:79
uint32_t key
Definition pdb.c:76
struct s_pdb_node * parent
Definition pdb.c:78
struct s_pdb_node * right
Definition pdb.c:80
void * data
Definition pdb.c:77
uint32_t magic
Definition pdb.c:81
struct tfrc * tfrc_init(time_ns_t curr_time)
Definition tfrc.c:365
void tfrc_done(struct tfrc *state)
Definition tfrc.c:415
static time_ns_t get_time_in_ns()
Definition tv.h:101
const char * key
Definition cineform.cpp:125