Commit 849269e1 authored by Siddharth Aggarwal's avatar Siddharth Aggarwal

merge bug fixed by Jon

parent 9429160e
...@@ -20,18 +20,20 @@ static int getBlockSize(TrieKey key, int size); ...@@ -20,18 +20,20 @@ static int getBlockSize(TrieKey key, int size);
static int insertWeak(Trie * triePtr, TrieNode * node, TrieKey key, static int insertWeak(Trie * triePtr, TrieNode * node, TrieKey key,
int maxDepth); int maxDepth);
static int insertStrong(Trie * triePtr, TrieNode * node, TrieKey key, static int insertStrong(Trie * triePtr, TrieNode * node, TrieKey key,
int maxDepth, TrieValue value); int maxDepth, TrieValue value, OverlapT overlap);
static int addChild(Trie * triePtr, TrieNode * parent, TrieKey key, static int addChild(Trie * triePtr, TrieNode * parent, TrieKey key,
int maxDepth, TrieValue value); int maxDepth, TrieValue value);
static int replace(TrieNode * node, TrieKey key, int maxDepth, static int replace(Trie * triePtr, TrieNode * node, TrieKey key,
TrieValue value); int maxDepth, TrieValue value, OverlapT overlap);
static void freeChildren(Trie * triePtr, TrieNode * node, OverlapT overlap);
static int strongOverlap(Trie * triePtr, TrieNode * node, TrieKey key, static int strongOverlap(Trie * triePtr, TrieNode * node, TrieKey key,
int maxDepth, TrieValue value); int maxDepth, TrieValue value, OverlapT overlap);
static int weakOverlap(Trie * triePtr, TrieNode * node, TrieKey key, static int weakOverlap(Trie * triePtr, TrieNode * node, TrieKey key,
int maxDepth); int maxDepth);
static TrieNode * search(TrieNode * node, TrieKey key, int maxDepth); static TrieNode * search(TrieNode * node, TrieKey key, int maxDepth);
static TrieNode * pushDown(Trie * triePtr, TrieNode * node); static TrieNode * pushDown(Trie * triePtr, TrieNode * node);
static void addToList(Trie * triePtr, TrieNode * node); static void addToList(Trie * triePtr, TrieNode * node);
static void removeFromList(Trie * triePtr, TrieNode * node);
TrieKey getDefaultTrieKey(void) TrieKey getDefaultTrieKey(void)
{ {
...@@ -135,6 +137,7 @@ static void TrieNodeInit(TrieNode * node) ...@@ -135,6 +137,7 @@ static void TrieNodeInit(TrieNode * node)
node->value = getDefaultTrieValue(); node->value = getDefaultTrieValue();
node->parent = 0; node->parent = 0;
node->next = 0; node->next = 0;
node->prev = 0;
for (i = 0; i < CHILD_COUNT; i++) for (i = 0; i < CHILD_COUNT; i++)
{ {
node->child[i] = 0; node->child[i] = 0;
...@@ -157,19 +160,14 @@ void TrieCleanup(Trie * triePtr) ...@@ -157,19 +160,14 @@ void TrieCleanup(Trie * triePtr)
static void TrieNodeCleanup(TrieNode * node) static void TrieNodeCleanup(TrieNode * node)
{ {
int i = 0; if (node->next != 0)
/*assert(node != 0); */
for (i = 0; i < CHILD_COUNT; i++)
{ {
if (node->child[i] != 0) TrieNodeCleanup(node->next);
{ free(node->next
TrieNodeCleanup(node->child[i]);
free(node->child[i]
#ifdef KERNEL #ifdef KERNEL
, M_DEVBUF , M_DEVBUF
#endif #endif
); );
}
} }
} }
...@@ -281,7 +279,8 @@ int TrieInsertWeak(Trie * triePtr, TrieKey key, int size, FirstPtrT first, ...@@ -281,7 +279,8 @@ int TrieInsertWeak(Trie * triePtr, TrieKey key, int size, FirstPtrT first,
return copyCount; return copyCount;
} }
int TrieInsertStrong(Trie * triePtr, TrieKey key, int size, TrieValue value) int TrieInsertStrong(Trie * triePtr, TrieKey key, int size, TrieValue value,
OverlapT overlap)
{ {
int insertCount = -1; int insertCount = -1;
if (triePtr != 0 && size > 0) if (triePtr != 0 && size > 0)
...@@ -294,7 +293,8 @@ int TrieInsertStrong(Trie * triePtr, TrieKey key, int size, TrieValue value) ...@@ -294,7 +293,8 @@ int TrieInsertStrong(Trie * triePtr, TrieKey key, int size, TrieValue value)
{ {
blockSize = getBlockSize(key, size); blockSize = getBlockSize(key, size);
insertCount += insertStrong(triePtr, &(triePtr->root), key, insertCount += insertStrong(triePtr, &(triePtr->root), key,
sizeToDepth(blockSize), value); sizeToDepth(blockSize), value,
overlap);
key += blockSize; key += blockSize;
size -= blockSize; size -= blockSize;
value += blockSize; value += blockSize;
...@@ -357,7 +357,7 @@ static int insertWeak(Trie * triePtr, TrieNode * node, TrieKey key, ...@@ -357,7 +357,7 @@ static int insertWeak(Trie * triePtr, TrieNode * node, TrieKey key,
} }
static int insertStrong(Trie * triePtr, TrieNode * node, TrieKey key, static int insertStrong(Trie * triePtr, TrieNode * node, TrieKey key,
int maxDepth, TrieValue value) int maxDepth, TrieValue value, OverlapT overlap)
{ {
int total = 0; int total = 0;
int done = 0; int done = 0;
...@@ -379,7 +379,7 @@ static int insertStrong(Trie * triePtr, TrieNode * node, TrieKey key, ...@@ -379,7 +379,7 @@ static int insertStrong(Trie * triePtr, TrieNode * node, TrieKey key,
/* We don't want to go below this level. /* We don't want to go below this level.
We are strong, just replace whatever is here because We are strong, just replace whatever is here because
it must be a subset of this level. */ it must be a subset of this level. */
total = replace(node, key, maxDepth, value); total = replace(triePtr, node, key, maxDepth, value, overlap);
done = 1; done = 1;
} }
else if (node->depth == node->maxDepth) else if (node->depth == node->maxDepth)
...@@ -387,7 +387,8 @@ static int insertStrong(Trie * triePtr, TrieNode * node, TrieKey key, ...@@ -387,7 +387,8 @@ static int insertStrong(Trie * triePtr, TrieNode * node, TrieKey key,
/* If the target node is already at its lowest level /* If the target node is already at its lowest level
We need to over-ride just our portion and divide the rest up to We need to over-ride just our portion and divide the rest up to
be inserted seperately */ be inserted seperately */
total = strongOverlap(triePtr, node, key, maxDepth, value); total = strongOverlap(triePtr, node, key, maxDepth, value,
overlap);
done = 1; done = 1;
} }
else else
...@@ -428,23 +429,57 @@ static int addChild(Trie * triePtr, TrieNode * parent, TrieKey key, ...@@ -428,23 +429,57 @@ static int addChild(Trie * triePtr, TrieNode * parent, TrieKey key,
return result; return result;
} }
static int replace(TrieNode * node, TrieKey key, int maxDepth, TrieValue value) static int replace(Trie * triePtr, TrieNode * node, TrieKey key,
int maxDepth, TrieValue value, OverlapT overlap)
{ {
int depth = node->depth; if (isLeaf(node))
TrieNode * parent = node->parent; {
TrieNodeCleanup(node); if (overlap == FREE_OVERLAP)
TrieNodeInit(node); {
node->depth = depth; (triePtr->blockFree)(node->value, depthToSize(node->maxDepth));
}
}
else
{
freeChildren(triePtr, node, overlap);
}
/* depth is already set correctly */
node->maxDepth = maxDepth; node->maxDepth = maxDepth;
setLeaf(node); setLeaf(node);
node->key = key; node->key = key;
node->value = value; node->value = value;
node->parent = parent; /* parent is already set correctly */
/* next is already set correctly */
/* prev is already set correctly */
return depthToSize(maxDepth); return depthToSize(maxDepth);
} }
static void freeChildren(Trie * triePtr, TrieNode * node, OverlapT overlap)
{
int i = 0;
for ( ; i < CHILD_COUNT; i++)
{
if (node->child[i] != 0)
{
freeChildren(triePtr, node->child[i], overlap);
removeFromList(triePtr, node->child[i]);
if (isLeaf(node->child[i]) && overlap == FREE_OVERLAP)
{
(triePtr->blockFree)(node->child[i]->value,
depthToSize(node->child[i]->maxDepth));
}
free(node->child[i]
#ifdef KERNEL
, M_DEVBUF
#endif
);
}
}
}
static int strongOverlap(Trie * triePtr, TrieNode * node, TrieKey key, static int strongOverlap(Trie * triePtr, TrieNode * node, TrieKey key,
int maxDepth, TrieValue value) int maxDepth, TrieValue value, OverlapT overlap)
{ {
/* the old key range starts before the new one and ends after it. */ /* the old key range starts before the new one and ends after it. */
TrieKey oldKey = node->key; TrieKey oldKey = node->key;
...@@ -454,12 +489,18 @@ static int strongOverlap(Trie * triePtr, TrieNode * node, TrieKey key, ...@@ -454,12 +489,18 @@ static int strongOverlap(Trie * triePtr, TrieNode * node, TrieKey key,
TrieKey limit = key; TrieKey limit = key;
TrieValue currentValue = oldValue; TrieValue currentValue = oldValue;
if (overlap == FREE_OVERLAP)
{
(triePtr->blockFree)(oldValue, depthToSize(oldMaxDepth));
}
node->key = key; node->key = key;
node->maxDepth = maxDepth; node->maxDepth = maxDepth;
node->value = value; node->value = value;
for ( ; i < limit; ++i, ++currentValue) for ( ; i < limit; ++i, ++currentValue)
{ {
insertStrong(triePtr, &(triePtr->root), i, TOTAL_LEVELS, currentValue); insertStrong(triePtr, &(triePtr->root), i, TOTAL_LEVELS,
currentValue, overlap);
} }
i = node->key + depthToSize(node->maxDepth); i = node->key + depthToSize(node->maxDepth);
...@@ -467,7 +508,8 @@ static int strongOverlap(Trie * triePtr, TrieNode * node, TrieKey key, ...@@ -467,7 +508,8 @@ static int strongOverlap(Trie * triePtr, TrieNode * node, TrieKey key,
currentValue += depthToSize(node->maxDepth); currentValue += depthToSize(node->maxDepth);
for ( ; i < limit; ++i, ++currentValue) for ( ; i < limit; ++i, ++currentValue)
{ {
insertStrong(triePtr, &(triePtr->root), i, TOTAL_LEVELS, currentValue); insertStrong(triePtr, &(triePtr->root), i, TOTAL_LEVELS,
currentValue, overlap);
} }
return depthToSize(maxDepth); return depthToSize(maxDepth);
} }
...@@ -653,11 +695,32 @@ int TrieIteratorIsValid(TrieIterator iterator) ...@@ -653,11 +695,32 @@ int TrieIteratorIsValid(TrieIterator iterator)
static void addToList(Trie * triePtr, TrieNode * node) static void addToList(Trie * triePtr, TrieNode * node)
{ {
node->next = 0; node->next = 0;
node->prev = triePtr->tail;
triePtr->tail->next = node; triePtr->tail->next = node;
triePtr->tail = node; triePtr->tail = node;
} }
int merge(Trie * dest, Trie * source) static void removeFromList(Trie * triePtr, TrieNode * node)
{
if (node->prev != 0)
{
node->prev->next = node->next;
}
if (node->next != 0)
{
node->next->prev = node->prev;
}
else
{
triePtr->tail = node->prev;
}
node->next = 0;
node->prev = 0;
}
int merge(Trie * dest, Trie * source, OverlapT overlap)
{ {
if (dest != 0 && source != 0) if (dest != 0 && source != 0)
{ {
...@@ -668,7 +731,7 @@ int merge(Trie * dest, Trie * source) ...@@ -668,7 +731,7 @@ int merge(Trie * dest, Trie * source)
for ( ; TrieIteratorIsValid(pos); TrieIteratorAdvance(&pos)) for ( ; TrieIteratorIsValid(pos); TrieIteratorAdvance(&pos))
{ {
TrieInsertStrong(dest, pos->key, depthToSize(pos->maxDepth), TrieInsertStrong(dest, pos->key, depthToSize(pos->maxDepth),
pos->value); pos->value, overlap);
} }
TrieIteratorCleanup(&pos); TrieIteratorCleanup(&pos);
} }
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
#ifndef TRIE_H_TRIE_1 #ifndef TRIE_H_TRIE_1
#define TRIE_H_TRIE_1 #define TRIE_H_TRIE_1
#define KERNEL /*#define KERNEL */
#ifdef KERNEL #ifdef KERNEL
...@@ -35,9 +35,7 @@ ...@@ -35,9 +35,7 @@
-------------- --------------
The insertion functions are currently not transactional.*/ The insertion functions are currently not transactional.*/
/* To change what the TrieKey and TrieValue types are, change the two /* Do not change the typdefs for TrieKey and TrieValue */
typedefs and then change the definition of the two functions.
TrieKey must not have a sign-extending shift.*/
typedef unsigned int TrieKey; typedef unsigned int TrieKey;
TrieKey getDefaultTrieKey(void); TrieKey getDefaultTrieKey(void);
...@@ -63,6 +61,12 @@ enum ...@@ -63,6 +61,12 @@ enum
TOTAL_LEVELS = TOTAL_BITS / BITS_PER_LEVEL TOTAL_LEVELS = TOTAL_BITS / BITS_PER_LEVEL
}; };
typedef enum OverlapTag
{
FREE_OVERLAP,
DEFAULT_OVERLAP
} OverlapT;
typedef struct TrieNodeTag typedef struct TrieNodeTag
{ {
char depth; char depth;
...@@ -71,6 +75,7 @@ typedef struct TrieNodeTag ...@@ -71,6 +75,7 @@ typedef struct TrieNodeTag
TrieKey key; TrieKey key;
TrieValue value; TrieValue value;
struct TrieNodeTag * next; struct TrieNodeTag * next;
struct TrieNodeTag * prev;
/* Don't touch these */ /* Don't touch these */
struct TrieNodeTag * parent; struct TrieNodeTag * parent;
struct TrieNodeTag * child[CHILD_COUNT]; struct TrieNodeTag * child[CHILD_COUNT];
...@@ -82,9 +87,8 @@ typedef void * ThirdPtrT; ...@@ -82,9 +87,8 @@ typedef void * ThirdPtrT;
typedef int (*BlockAllocateFunction)(int); typedef int (*BlockAllocateFunction)(int);
typedef int (*BlockFreeFunction)(int, int); typedef int (*BlockFreeFunction)(int, int);
typedef int (*BlockCopyFunction)(FirstPtrT, SecondPtrT, typedef int (*BlockCopyFunction)(FirstPtrT, SecondPtrT,
TrieKey source, TrieValue dest, TrieKey source, TrieValue dest, int size, int direction);
int size, int type);
typedef struct typedef struct
{ {
...@@ -138,15 +142,17 @@ int TrieInsertWeak(Trie * triePtr, TrieKey key, int size, FirstPtrT first, ...@@ -138,15 +142,17 @@ int TrieInsertWeak(Trie * triePtr, TrieKey key, int size, FirstPtrT first,
/* Inserts every key in [key, key+size) and overwrites any of these /* Inserts every key in [key, key+size) and overwrites any of these
keys which are already inserted. This inserts 'value' at key, 'value+1' keys which are already inserted. This inserts 'value' at key, 'value+1'
at key+1, etc. up to size. This is transactional. If any of the inserts at key+1, etc. up to size. This is transactional. If any of the inserts
fail, they all fail. fail, they all fail. overlap determines whether blockFree is called
when an insert overlaps an existing block.
Returns the number of new keys inserted (non-overwrite inserts). Returns the number of new keys inserted (non-overwrite inserts).
Returns <0 on failure. */ Returns <0 on failure. */
int TrieInsertStrong(Trie * triePtr, TrieKey key, int size, TrieValue value); int TrieInsertStrong(Trie * triePtr, TrieKey key, int size, TrieValue value,
OverlapT overlap);
/* This is not transactional. /* This is not transactional.
The return value determines whether it succeeded or not. The return value determines whether it succeeded or not.
1 for success, 0 for failure. */ 1 for success, 0 for failure. */
int merge(Trie * dest, Trie * source); int merge(Trie * dest, Trie * source, OverlapT overlap);
/* This is not transactional. */ /* This is not transactional. */
void freeAllBlocks(Trie * trie); void freeAllBlocks(Trie * trie);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment