Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 6308
b: refs/heads/master
c: 2f80b3c
h: refs/heads/master
v: v3
  • Loading branch information
Robert Olsson authored and David S. Miller committed Aug 29, 2005
1 parent cadfa0a commit 9d99351
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 63 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 91b9a277fc4d207249e459a455abf804ebb5499d
refs/heads/master: 2f80b3c8262d0d646812f776db024d88d569a0c1
119 changes: 57 additions & 62 deletions trunk/net/ipv4/fib_trie.c
Original file line number Diff line number Diff line change
Expand Up @@ -167,8 +167,8 @@ static void put_child(struct trie *t, struct tnode *tn, int i, struct node *n);
static void tnode_put_child_reorg(struct tnode *tn, int i, struct node *n, int wasfull);
static int tnode_child_length(struct tnode *tn);
static struct node *resize(struct trie *t, struct tnode *tn);
static struct tnode *inflate(struct trie *t, struct tnode *tn, int *err);
static struct tnode *halve(struct trie *t, struct tnode *tn, int *err);
static struct tnode *inflate(struct trie *t, struct tnode *tn);
static struct tnode *halve(struct trie *t, struct tnode *tn);
static void tnode_free(struct tnode *tn);
static void trie_dump_seq(struct seq_file *seq, struct trie *t);
extern struct fib_alias *fib_find_alias(struct list_head *fah, u8 tos, u32 prio);
Expand Down Expand Up @@ -457,6 +457,7 @@ static struct node *resize(struct trie *t, struct tnode *tn)
{
int i;
int err = 0;
struct tnode *old_tn;

if (!tn)
return NULL;
Expand Down Expand Up @@ -559,9 +560,10 @@ static struct node *resize(struct trie *t, struct tnode *tn)
50 * (tn->full_children + tnode_child_length(tn) - tn->empty_children) >=
inflate_threshold * tnode_child_length(tn))) {

tn = inflate(t, tn, &err);

if (err) {
old_tn = tn;
tn = inflate(t, tn);
if (IS_ERR(tn)) {
tn = old_tn;
#ifdef CONFIG_IP_FIB_TRIE_STATS
t->stats.resize_node_skipped++;
#endif
Expand All @@ -581,9 +583,10 @@ static struct node *resize(struct trie *t, struct tnode *tn)
100 * (tnode_child_length(tn) - tn->empty_children) <
halve_threshold * tnode_child_length(tn)) {

tn = halve(t, tn, &err);

if (err) {
old_tn = tn;
tn = halve(t, tn);
if (IS_ERR(tn)) {
tn = old_tn;
#ifdef CONFIG_IP_FIB_TRIE_STATS
t->stats.resize_node_skipped++;
#endif
Expand Down Expand Up @@ -618,7 +621,7 @@ static struct node *resize(struct trie *t, struct tnode *tn)
return (struct node *) tn;
}

static struct tnode *inflate(struct trie *t, struct tnode *tn, int *err)
static struct tnode *inflate(struct trie *t, struct tnode *tn)
{
struct tnode *inode;
struct tnode *oldtnode = tn;
Expand All @@ -629,10 +632,8 @@ static struct tnode *inflate(struct trie *t, struct tnode *tn, int *err)

tn = tnode_new(oldtnode->key, oldtnode->pos, oldtnode->bits + 1);

if (!tn) {
*err = -ENOMEM;
return oldtnode;
}
if (!tn)
return ERR_PTR(-ENOMEM);

/*
* Preallocate and store tnodes before the actual work so we
Expand All @@ -653,39 +654,22 @@ static struct tnode *inflate(struct trie *t, struct tnode *tn, int *err)

left = tnode_new(inode->key&(~m), inode->pos + 1,
inode->bits - 1);

if (!left) {
*err = -ENOMEM;
break;
}
if (!left)
goto nomem;

right = tnode_new(inode->key|m, inode->pos + 1,
inode->bits - 1);

if (!right) {
*err = -ENOMEM;
break;
}
if (!right) {
tnode_free(left);
goto nomem;
}

put_child(t, tn, 2*i, (struct node *) left);
put_child(t, tn, 2*i+1, (struct node *) right);
}
}

if (*err) {
int size = tnode_child_length(tn);
int j;

for (j = 0; j < size; j++)
if (tn->child[j])
tnode_free((struct tnode *)tn->child[j]);

tnode_free(tn);

*err = -ENOMEM;
return oldtnode;
}

for (i = 0; i < olen; i++) {
struct node *node = tnode_get_child(oldtnode, i);
struct tnode *left, *right;
Expand Down Expand Up @@ -763,9 +747,22 @@ static struct tnode *inflate(struct trie *t, struct tnode *tn, int *err)
}
tnode_free(oldtnode);
return tn;
nomem:
{
int size = tnode_child_length(tn);
int j;

for(j = 0; j < size; j++)
if (tn->child[j])
tnode_free((struct tnode *)tn->child[j]);

tnode_free(tn);

return ERR_PTR(-ENOMEM);
}
}

static struct tnode *halve(struct trie *t, struct tnode *tn, int *err)
static struct tnode *halve(struct trie *t, struct tnode *tn)
{
struct tnode *oldtnode = tn;
struct node *left, *right;
Expand All @@ -776,10 +773,8 @@ static struct tnode *halve(struct trie *t, struct tnode *tn, int *err)

tn = tnode_new(oldtnode->key, oldtnode->pos, oldtnode->bits - 1);

if (!tn) {
*err = -ENOMEM;
return oldtnode;
}
if (!tn)
return ERR_PTR(-ENOMEM);

/*
* Preallocate and store tnodes before the actual work so we
Expand All @@ -794,29 +789,16 @@ static struct tnode *halve(struct trie *t, struct tnode *tn, int *err)

/* Two nonempty children */
if (left && right) {
struct tnode *newBinNode =
tnode_new(left->key, tn->pos + tn->bits, 1);

if (!newBinNode) {
*err = -ENOMEM;
break;
}
put_child(t, tn, i/2, (struct node *)newBinNode);
struct tnode *newn;
newn = tnode_new(left->key, tn->pos + tn->bits, 1);
if (!newn)
goto nomem;
put_child(t, tn, i/2, (struct node *)newn);
}
}

if (*err) {
int size = tnode_child_length(tn);
int j;

for (j = 0; j < size; j++)
if (tn->child[j])
tnode_free((struct tnode *)tn->child[j]);

tnode_free(tn);

*err = -ENOMEM;
return oldtnode;
}

for (i = 0; i < olen; i += 2) {
Expand Down Expand Up @@ -850,6 +832,19 @@ static struct tnode *halve(struct trie *t, struct tnode *tn, int *err)
}
tnode_free(oldtnode);
return tn;
nomem:
{
int size = tnode_child_length(tn);
int j;

for(j = 0; j < size; j++)
if (tn->child[j])
tnode_free((struct tnode *)tn->child[j]);

tnode_free(tn);

return ERR_PTR(-ENOMEM);
}
}

static void trie_init(struct trie *t)
Expand Down

0 comments on commit 9d99351

Please sign in to comment.