aboutsummaryrefslogtreecommitdiff
path: root/libkmod
diff options
context:
space:
mode:
authorGustavo Sverzut Barbieri <barbieri@profusion.mobi>2011-12-10 13:04:43 -0200
committerGustavo Sverzut Barbieri <barbieri@profusion.mobi>2011-12-10 13:04:43 -0200
commitd09154644814b6f013ce24b6eb7fed076230c916 (patch)
tree07cf0148e91e9c3bf4f351d3220ca6b3cf2513b5 /libkmod
parent148226ed92077527ccfc9f38eff6e7771714449e (diff)
downloadkmod-d09154644814b6f013ce24b6eb7fed076230c916.tar.gz
index-mm: allocate values inline into node, strings points to mmap.
For mmap mode, we can avoid allocating and copying strings from the mmap'ed memory. With that we have fixed length "struct index_mm_value" that can be allocated inline with "struct index_mm_node".
Diffstat (limited to 'libkmod')
-rw-r--r--libkmod/libkmod-index.c94
1 files changed, 58 insertions, 36 deletions
diff --git a/libkmod/libkmod-index.c b/libkmod/libkmod-index.c
index 40b223c..8424271 100644
--- a/libkmod/libkmod-index.c
+++ b/libkmod/libkmod-index.c
@@ -587,10 +587,21 @@ struct index_mm {
size_t size;
};
+struct index_mm_value {
+ unsigned int priority;
+ unsigned int len;
+ const char *value;
+};
+
+struct index_mm_value_array {
+ struct index_mm_value *values;
+ unsigned int len;
+};
+
struct index_mm_node {
struct index_mm *idx;
const char *prefix; /* mmape'd value */
- struct index_value *values;
+ struct index_mm_value_array values;
unsigned char first;
unsigned char last;
uint32_t children[];
@@ -629,8 +640,9 @@ static struct index_mm_node *index_mm_read_node(struct index_mm *idx,
void *p = idx->mm;
struct index_mm_node *node;
const char *prefix;
- int i, child_count = 0;
-
+ int i, child_count, value_count, children_padding;
+ uint32_t children[INDEX_CHILDMAX];
+ char first, last;
if ((offset & INDEX_NODE_MASK) == 0)
return NULL;
@@ -644,48 +656,56 @@ static struct index_mm_node *index_mm_read_node(struct index_mm *idx,
prefix = _idx_empty_str;
if (offset & INDEX_NODE_CHILDS) {
- char first = read_char_mm(&p);
- char last = read_char_mm(&p);
+ first = read_char_mm(&p);
+ last = read_char_mm(&p);
child_count = last - first + 1;
-
- node = malloc(sizeof(*node) + sizeof(uint32_t) * child_count);
-
- node->first = first;
- node->last = last;
-
for (i = 0; i < child_count; i++)
- node->children[i] = read_long_mm(&p);
+ children[i] = read_long_mm(&p);
} else {
- node = malloc(sizeof(*node));
- node->first = INDEX_CHILDMAX;
- node->last = 0;
+ first = INDEX_CHILDMAX;
+ last = 0;
+ child_count = 0;
}
- node->values = NULL;
-
- if (offset & INDEX_NODE_VALUES) {
- uint32_t j;
+ children_padding = (offsetof(struct index_mm_node, children) +
+ (sizeof(uint32_t) * child_count)) % sizeof(void *);
- for (j = read_long_mm(&p); j > 0; j--) {
- unsigned int priority;
- const char *value;
- unsigned len;
+ if (offset & INDEX_NODE_VALUES)
+ value_count = read_long_mm(&p);
+ else
+ value_count = 0;
- priority = read_long_mm(&p);
- value = read_chars_mm(&p, &len);
- add_value(&node->values, value, len, priority);
- }
- }
+ node = malloc(sizeof(struct index_mm_node)
+ + sizeof(uint32_t) * child_count + children_padding
+ + sizeof(struct index_mm_value) * value_count);
+ if (node == NULL)
+ return NULL;
- node->prefix = prefix;
node->idx = idx;
+ node->prefix = prefix;
+ if (value_count == 0)
+ node->values.values = NULL;
+ else {
+ node->values.values = (struct index_mm_value *)
+ ((char *)node + sizeof(struct index_mm_node) +
+ sizeof(uint32_t) * child_count + children_padding);
+ }
+ node->values.len = value_count;
+ node->first = first;
+ node->last = last;
+ memcpy(node->children, children, sizeof(uint32_t) * child_count);
+
+ for (i = 0; i < value_count; i++) {
+ struct index_mm_value *v = node->values.values + i;
+ v->priority = read_long_mm(&p);
+ v->value = read_chars_mm(&p, &v->len);
+ }
return node;
}
static void index_mm_free_node(struct index_mm_node *node)
{
- index_values_free(node->values);
free(node);
}
@@ -803,8 +823,8 @@ static char *index_mm_search_node(struct index_mm_node *node, const char *key,
i += j;
if (key[i] == '\0') {
- if (node->values) {
- value = strdup(node->values[0].value);
+ if (node->values.len > 0) {
+ value = strdup(node->values.values[0].value);
index_mm_free_node(node);
return value;
} else {
@@ -843,10 +863,12 @@ char *index_mm_search(struct index_mm *idx, const char *key)
static void index_mm_searchwild_allvalues(struct index_mm_node *node,
struct index_value **out)
{
- struct index_value *v;
+ struct index_mm_value *itr, *itr_end;
- for (v = node->values; v != NULL; v = v->next)
- add_value(out, v->value, v->len, v->priority);
+ itr = node->values.values;
+ itr_end = itr + node->values.len;
+ for (; itr < itr_end; itr++)
+ add_value(out, itr->value, itr->len, itr->priority);
index_mm_free_node(node);
}
@@ -882,7 +904,7 @@ static void index_mm_searchwild_all(struct index_mm_node *node, int j,
buf_popchar(buf);
}
- if (node->values) {
+ if (node->values.len > 0) {
if (fnmatch(buf_str(buf), subkey, 0) == 0)
index_mm_searchwild_allvalues(node, out);
} else {