From 0eebf89f35b8d1e5425ce1fe76c694c198a1fb31 Mon Sep 17 00:00:00 2001 From: Tatsuhiro Tsujikawa Date: Wed, 18 Jan 2012 02:10:22 +0900 Subject: [PATCH] Added priority queue --- lib/Makefile.am | 9 +-- lib/includes/spdylay/spdylay.h | 34 ++++++++++ lib/spdylay_pq.c | 117 +++++++++++++++++++++++++++++++++ lib/spdylay_pq.h | 56 ++++++++++++++++ tests/Makefile.am | 12 ++++ tests/spdylay_pq_test.c | 58 ++++++++++++++++ tests/spdylay_pq_test.h | 30 +++++++++ 7 files changed, 312 insertions(+), 4 deletions(-) create mode 100644 lib/includes/spdylay/spdylay.h create mode 100644 lib/spdylay_pq.c create mode 100644 lib/spdylay_pq.h create mode 100644 tests/spdylay_pq_test.c create mode 100644 tests/spdylay_pq_test.h diff --git a/lib/Makefile.am b/lib/Makefile.am index c37f4e28..c3d8e356 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -31,9 +31,10 @@ DISTCLEANFILES = $(pkgconfig_DATA) lib_LTLIBRARIES = libspdylay.la -OBJECTS = -HFILES = +OBJECTS = spdylay_pq.c -libwslay_la_SOURCES = $(HFILES) $(OBJECTS) -libwslay_la_LDFLAGS = -no-undefined \ +HFILES = spdylay_pq.h + +libspdylay_la_SOURCES = $(HFILES) $(OBJECTS) +libspdylay_la_LDFLAGS = -no-undefined \ -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE) diff --git a/lib/includes/spdylay/spdylay.h b/lib/includes/spdylay/spdylay.h new file mode 100644 index 00000000..1de7ab2d --- /dev/null +++ b/lib/includes/spdylay/spdylay.h @@ -0,0 +1,34 @@ +/* + * Spdylay - SPDY Library + * + * Copyright (c) 2012 Tatsuhiro Tsujikawa + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +#ifndef SPDYLAY_H +#define SPDYLAY_H + +#include + +enum spdylay_error { + SPDYLAY_ERR_NOMEM = -500 +}; + +#endif /* SPDYLAY_H */ diff --git a/lib/spdylay_pq.c b/lib/spdylay_pq.c new file mode 100644 index 00000000..4386788d --- /dev/null +++ b/lib/spdylay_pq.c @@ -0,0 +1,117 @@ +/* + * Spdylay - SPDY Library + * + * Copyright (c) 2012 Tatsuhiro Tsujikawa + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +#include "spdylay_pq.h" + +int spdylay_pq_init(spdylay_pq *pq, spdylay_pq_compar compar) +{ + pq->capacity = 4096; + pq->q = malloc(pq->capacity); + if(pq->q == NULL) { + return SPDYLAY_ERR_NOMEM; + } + pq->length = 0; + pq->compar = compar; + return 0; +} + +void spdylay_pq_free(spdylay_pq *pq) +{ + free(pq->q); + pq->q = NULL; +} + +static void swap(spdylay_pq *pq, size_t i, size_t j) +{ + void *t = pq->q[i]; + pq->q[i] = pq->q[j]; + pq->q[j] = t; +} + +static void bubble_up(spdylay_pq *pq, size_t index) +{ + if(index == 0) { + return; + } else { + size_t parent = (index-1)/2; + if(pq->compar(pq->q[parent], pq->q[index]) > 0) { + swap(pq, parent, index); + bubble_up(pq, parent); + } + } +} + +int spdylay_pq_push(spdylay_pq *pq, void *item) +{ + if(pq->capacity <= pq->length) { + void *nq = realloc(pq->q, pq->capacity*2); + if(nq == NULL) { + return SPDYLAY_ERR_NOMEM; + } + pq->capacity *= 2; + pq->q = nq; + } + pq->q[pq->length] = item; + ++pq->length; + bubble_up(pq, pq->length-1); + return 0; +} + +void* spdylay_pq_top(spdylay_pq *pq) +{ + if(pq->length == 0) { + return NULL; + } else { + return pq->q[0]; + } +} + +static void bubble_down(spdylay_pq *pq, size_t index) +{ + size_t lchild = index*2+1; + size_t minindex = index; + int i, j; + for(i = 0; i < 2; ++i) { + j = lchild+i; + if(j >= pq->length) { + break; + } + if(pq->compar(pq->q[minindex], pq->q[j]) > 0) { + minindex = j; + } + } + if(minindex != index) { + swap(pq, index, minindex); + bubble_down(pq, minindex); + } +} + +void spdylay_pq_pop(spdylay_pq *pq) +{ + if(pq->length > 0) { + pq->q[0] = pq->q[pq->length-1]; + --pq->length; + bubble_down(pq, 0); + } +} diff --git a/lib/spdylay_pq.h b/lib/spdylay_pq.h new file mode 100644 index 00000000..78089481 --- /dev/null +++ b/lib/spdylay_pq.h @@ -0,0 +1,56 @@ +/* + * Spdylay - SPDY Library + * + * Copyright (c) 2012 Tatsuhiro Tsujikawa + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +#ifndef SPDYLAY_PQ_H +#define SPDYLAY_PQ_H + +#ifdef HAVE_CONFIG_H +# include +#endif /* HAVE_CONFIG_H */ + +#include + +/* Implementation of priority queue */ + +typedef int (*spdylay_pq_compar)(const void *lhs, const void *rhs); + +typedef struct { + void **q; + size_t length; + size_t capacity; + spdylay_pq_compar compar; +} spdylay_pq; + +int spdylay_pq_init(spdylay_pq *pq, spdylay_pq_compar cmp); + +void spdylay_pq_free(spdylay_pq *pq); + +int spdylay_pq_push(spdylay_pq *pq, void *item); + +void* spdylay_pq_top(spdylay_pq *pq); + +void spdylay_pq_pop(spdylay_pq *pq); + + +#endif /* SPDYLAY_PQ_H */ diff --git a/tests/Makefile.am b/tests/Makefile.am index 269475c4..a362faa7 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -23,5 +23,17 @@ if HAVE_CUNIT +check_PROGRAMS = main + +OBJECTS = main.c spdylay_pq_test.c + +HFILES = spdylay_pq_test.h + +main_SOURCES = $(HFILES) $(OBJECTS) + +main_LDADD = ${top_builddir}/lib/libspdylay.la -lcunit +main_LDFLAGS = -static +AM_CFLAGS = -Wall -g -O2 -I${top_srcdir}/lib -I${top_srcdir}/lib/includes +TESTS = main endif # HAVE_CUNIT diff --git a/tests/spdylay_pq_test.c b/tests/spdylay_pq_test.c new file mode 100644 index 00000000..27e52d31 --- /dev/null +++ b/tests/spdylay_pq_test.c @@ -0,0 +1,58 @@ +/* + * Spdylay - SPDY Library + * + * Copyright (c) 2012 Tatsuhiro Tsujikawa + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +#include "spdylay_pq_test.h" + +#include + +#include "spdylay_pq.h" + +static int pq_compar(const void *lhs, const void *rhs) +{ + return strcmp(lhs, rhs); +} + +void test_spdylay_pq() +{ + spdylay_pq pq; + spdylay_pq_init(&pq, pq_compar); + CU_ASSERT(0 == spdylay_pq_push(&pq, "foo")); + CU_ASSERT(strcmp("foo", spdylay_pq_top(&pq)) == 0); + CU_ASSERT(0 == spdylay_pq_push(&pq, "bar")); + CU_ASSERT(strcmp("bar", spdylay_pq_top(&pq)) == 0); + CU_ASSERT(0 == spdylay_pq_push(&pq, "baz")); + CU_ASSERT(strcmp("bar", spdylay_pq_top(&pq)) == 0); + CU_ASSERT(0 == spdylay_pq_push(&pq, "C")); + CU_ASSERT(strcmp("C", spdylay_pq_top(&pq)) == 0); + spdylay_pq_pop(&pq); + CU_ASSERT(strcmp("bar", spdylay_pq_top(&pq)) == 0); + spdylay_pq_pop(&pq); + CU_ASSERT(strcmp("baz", spdylay_pq_top(&pq)) == 0); + spdylay_pq_pop(&pq); + CU_ASSERT(strcmp("foo", spdylay_pq_top(&pq)) == 0); + spdylay_pq_pop(&pq); + CU_ASSERT(0 == spdylay_pq_top(&pq)); + spdylay_pq_free(&pq); +} + diff --git a/tests/spdylay_pq_test.h b/tests/spdylay_pq_test.h new file mode 100644 index 00000000..1856c042 --- /dev/null +++ b/tests/spdylay_pq_test.h @@ -0,0 +1,30 @@ +/* + * Spdylay - SPDY Library + * + * Copyright (c) 2012 Tatsuhiro Tsujikawa + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +#ifndef SPDYLAY_PQ_TEST_H +#define SPDYLAY_PQ_TEST_H + +void test_spdylay_pq(); + +#endif /* SPDYLAY_PQ_TEST_H */