forked from github/server
Added quicklist, a linked list with better cache characteristics.
This commit is contained in:
parent
0adf7899dd
commit
1cae5e2283
5 changed files with 159 additions and 0 deletions
|
@ -19,6 +19,7 @@
|
||||||
#include <util/goodies.c>
|
#include <util/goodies.c>
|
||||||
#include <util/language.c>
|
#include <util/language.c>
|
||||||
#include <util/lists.c>
|
#include <util/lists.c>
|
||||||
|
#include <util/quicklist.c>
|
||||||
#include <util/log.c>
|
#include <util/log.c>
|
||||||
#include <util/message.c>
|
#include <util/message.c>
|
||||||
#include <util/nrmessage.c>
|
#include <util/nrmessage.c>
|
||||||
|
|
|
@ -109,6 +109,7 @@
|
||||||
<ClInclude Include="util\nrmessage_struct.h" />
|
<ClInclude Include="util\nrmessage_struct.h" />
|
||||||
<ClInclude Include="util\parser.h" />
|
<ClInclude Include="util\parser.h" />
|
||||||
<ClInclude Include="util\patricia.h" />
|
<ClInclude Include="util\patricia.h" />
|
||||||
|
<ClInclude Include="util\quicklist.h" />
|
||||||
<ClInclude Include="util\rand.h" />
|
<ClInclude Include="util\rand.h" />
|
||||||
<ClInclude Include="util\resolve.h" />
|
<ClInclude Include="util\resolve.h" />
|
||||||
<ClInclude Include="util\rng.h" />
|
<ClInclude Include="util\rng.h" />
|
||||||
|
@ -145,6 +146,7 @@
|
||||||
<ClCompile Include="util\nrmessage.c" />
|
<ClCompile Include="util\nrmessage.c" />
|
||||||
<ClCompile Include="util\parser.c" />
|
<ClCompile Include="util\parser.c" />
|
||||||
<ClCompile Include="util\patricia.c" />
|
<ClCompile Include="util\patricia.c" />
|
||||||
|
<ClCompile Include="util\quicklist.c" />
|
||||||
<ClCompile Include="util\rand.c" />
|
<ClCompile Include="util\rand.c" />
|
||||||
<ClCompile Include="util\resolve.c" />
|
<ClCompile Include="util\resolve.c" />
|
||||||
<ClCompile Include="util\sql.c" />
|
<ClCompile Include="util\sql.c" />
|
||||||
|
|
|
@ -107,6 +107,9 @@
|
||||||
<ClInclude Include="util\xml.h">
|
<ClInclude Include="util\xml.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="util\quicklist.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="util\argstack.c">
|
<ClCompile Include="util\argstack.c">
|
||||||
|
@ -199,5 +202,8 @@
|
||||||
<ClCompile Include="util\xml.c">
|
<ClCompile Include="util\xml.c">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="util\quicklist.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
115
src/util/quicklist.c
Normal file
115
src/util/quicklist.c
Normal file
|
@ -0,0 +1,115 @@
|
||||||
|
/*
|
||||||
|
Copyright (c) 2010-2011, Enno Rehling <enno@eressea.de>
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
|
copyright notice and this permission notice appear in all copies.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
**/
|
||||||
|
|
||||||
|
#include "quicklist.h"
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#define QL_MAXSIZE 14 /* total struct is 64 bytes */
|
||||||
|
#define QL_LIMIT 8
|
||||||
|
|
||||||
|
typedef struct quicklist {
|
||||||
|
struct quicklist * next;
|
||||||
|
int num_elements;
|
||||||
|
void * elements[QL_MAXSIZE];
|
||||||
|
} quicklist;
|
||||||
|
|
||||||
|
|
||||||
|
void * ql_get(quicklist * ql, int index) {
|
||||||
|
return (ql && index<ql->num_elements)?ql->elements[index]:ql_get(ql->next, index-ql->num_elements);
|
||||||
|
}
|
||||||
|
|
||||||
|
int ql_length(const quicklist * ql) {
|
||||||
|
return ql?ql->num_elements+ql_length(ql->next):0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ql_push(quicklist ** qlp, void * data) {
|
||||||
|
quicklist * ql = 0;
|
||||||
|
while(*qlp && ((*qlp)->next || (*qlp)->num_elements==QL_MAXSIZE)) {
|
||||||
|
qlp = &(*qlp)->next;
|
||||||
|
}
|
||||||
|
if (!*qlp) {
|
||||||
|
ql = malloc(sizeof(quicklist));
|
||||||
|
ql->num_elements = 0;
|
||||||
|
ql->next = 0;
|
||||||
|
*qlp = ql;
|
||||||
|
} else {
|
||||||
|
ql = *qlp;
|
||||||
|
}
|
||||||
|
ql->elements[ql->num_elements++] = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ql_delete(quicklist ** qlp, int index) {
|
||||||
|
quicklist * ql = *qlp;
|
||||||
|
if (index<0) return EINVAL;
|
||||||
|
if (ql && index>=ql->num_elements) {
|
||||||
|
return ql_delete(&ql->next, index-ql->num_elements);
|
||||||
|
} else if (ql) {
|
||||||
|
if (index+1<ql->num_elements) {
|
||||||
|
memmove(ql->elements+index, ql->elements+index+1, (ql->num_elements-index-1)*sizeof(void*));
|
||||||
|
}
|
||||||
|
--ql->num_elements;
|
||||||
|
if (ql->num_elements==0) {
|
||||||
|
*qlp = ql->next;
|
||||||
|
free(ql);
|
||||||
|
} else if (ql->next && ql->num_elements<QL_LIMIT) {
|
||||||
|
quicklist * qn = ql->next;
|
||||||
|
if (ql->num_elements+qn->num_elements>QL_MAXSIZE) {
|
||||||
|
memcpy(ql->elements+ql->num_elements, qn->elements, sizeof(void*));
|
||||||
|
--qn->num_elements;
|
||||||
|
++ql->num_elements;
|
||||||
|
memmove(qn->elements, qn->elements+1, qn->num_elements*sizeof(void*));
|
||||||
|
} else {
|
||||||
|
memcpy(ql->elements+ql->num_elements, qn->elements, qn->num_elements*sizeof(void*));
|
||||||
|
ql->num_elements += qn->num_elements;
|
||||||
|
ql->next = qn->next;
|
||||||
|
free(qn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ql_insert(quicklist ** qlp, int index, void * data) {
|
||||||
|
quicklist * ql = *qlp;
|
||||||
|
if (ql) {
|
||||||
|
if (index>=QL_MAXSIZE) {
|
||||||
|
return ql_insert(&ql->next, index-ql->num_elements, data);
|
||||||
|
} else if (ql->num_elements<QL_MAXSIZE) {
|
||||||
|
memmove(ql->elements+index+1, ql->elements+index, (ql->num_elements-index)*sizeof(void*));
|
||||||
|
ql->elements[index]=data;
|
||||||
|
++ql->num_elements;
|
||||||
|
} else {
|
||||||
|
quicklist * qn = malloc(sizeof(quicklist));
|
||||||
|
qn->next = ql->next;
|
||||||
|
ql->next = qn;
|
||||||
|
qn->num_elements = QL_LIMIT;
|
||||||
|
ql->num_elements -= QL_LIMIT;
|
||||||
|
memcpy(qn->elements, ql->elements+ql->num_elements-QL_LIMIT, QL_LIMIT*sizeof(void*));
|
||||||
|
if (index<=ql->num_elements) {
|
||||||
|
return ql_insert(qlp, index, data);
|
||||||
|
} else {
|
||||||
|
return ql_insert(&ql->next, index-ql->num_elements, data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (index==0) {
|
||||||
|
ql_push(qlp, data);
|
||||||
|
} else {
|
||||||
|
return EINVAL;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
35
src/util/quicklist.h
Normal file
35
src/util/quicklist.h
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
/*
|
||||||
|
Copyright (c) 2010-2011, Enno Rehling <enno@eressea.de>
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
|
copyright notice and this permission notice appear in all copies.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
**/
|
||||||
|
|
||||||
|
#ifndef _QUICKLIST_H
|
||||||
|
#define _QUICKLIST_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* see http://en.wikipedia.org/wiki/Unrolled_linked_list */
|
||||||
|
struct quicklist;
|
||||||
|
void * ql_get(struct quicklist * ql, int index);
|
||||||
|
int ql_length(const struct quicklist * ql);
|
||||||
|
void ql_push(struct quicklist ** qlp, void * data);
|
||||||
|
int ql_delete(struct quicklist ** qlp, int index);
|
||||||
|
int ql_insert(struct quicklist ** qlp, int index, void * data);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
Loading…
Reference in a new issue