TwoKeyAVLTree: Add FindFirstClosest()
This commit is contained in:
parent
46368f46f3
commit
a058fbe8a1
@ -279,6 +279,8 @@ public:
|
|||||||
|
|
||||||
Value* FindFirst(const PrimaryKey& key,
|
Value* FindFirst(const PrimaryKey& key,
|
||||||
Iterator* iterator = NULL);
|
Iterator* iterator = NULL);
|
||||||
|
Value* FindFirstClosest(const PrimaryKey& key,
|
||||||
|
bool less, Iterator* iterator = NULL);
|
||||||
Value* FindLast(const PrimaryKey& key,
|
Value* FindLast(const PrimaryKey& key,
|
||||||
Iterator* iterator = NULL);
|
Iterator* iterator = NULL);
|
||||||
inline Value* Find(const PrimaryKey& primaryKey,
|
inline Value* Find(const PrimaryKey& primaryKey,
|
||||||
@ -296,6 +298,10 @@ public:
|
|||||||
const SecondaryKey& secondaryKey);
|
const SecondaryKey& secondaryKey);
|
||||||
inline status_t Remove(Node* node);
|
inline status_t Remove(Node* node);
|
||||||
|
|
||||||
|
private:
|
||||||
|
Node* _FindFirst(const PrimaryKey& key,
|
||||||
|
Node** _parent) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TreeMap fTreeMap;
|
TreeMap fTreeMap;
|
||||||
PrimaryKeyCompare fPrimaryKeyCompare;
|
PrimaryKeyCompare fPrimaryKeyCompare;
|
||||||
@ -432,35 +438,58 @@ TWO_KEY_AVL_TREE_CLASS_NAME::FindFirst(const PrimaryKey& key,
|
|||||||
Iterator* iterator)
|
Iterator* iterator)
|
||||||
{
|
{
|
||||||
const NodeStrategy& strategy = fTreeMap.GetNodeStrategy();
|
const NodeStrategy& strategy = fTreeMap.GetNodeStrategy();
|
||||||
Node* node = fTreeMap.RootNode();
|
|
||||||
|
|
||||||
while (node) {
|
Node* node = _FindFirst(key, NULL);
|
||||||
int cmp = fPrimaryKeyCompare(key, fGetPrimaryKey(
|
if (node == NULL)
|
||||||
strategy.GetValue(node)));
|
return NULL;
|
||||||
if (cmp == 0) {
|
|
||||||
// found a matching node, now get the left-most node with that key
|
|
||||||
while (node->left && fPrimaryKeyCompare(key,
|
|
||||||
fGetPrimaryKey(strategy.GetValue(
|
|
||||||
strategy.GetNode(node->left)))) == 0) {
|
|
||||||
node = strategy.GetNode(node->left);
|
|
||||||
}
|
|
||||||
if (iterator)
|
|
||||||
iterator->_SetTo(fTreeMap.GetIterator(node));
|
|
||||||
return &strategy.GetValue(node);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cmp < 0)
|
if (iterator != NULL)
|
||||||
node = strategy.GetNode(node->left);
|
iterator->_SetTo(fTreeMap.GetIterator(node));
|
||||||
else
|
|
||||||
node = strategy.GetNode(node->right);
|
return &strategy.GetValue(node);
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
TWO_KEY_AVL_TREE_TEMPLATE_LIST
|
TWO_KEY_AVL_TREE_TEMPLATE_LIST
|
||||||
Value*
|
Value*
|
||||||
TWO_KEY_AVL_TREE_CLASS_NAME::FindLast(const PrimaryKey& key, Iterator* iterator)
|
TWO_KEY_AVL_TREE_CLASS_NAME::FindFirstClosest(const PrimaryKey& key, bool less,
|
||||||
|
Iterator* iterator)
|
||||||
|
{
|
||||||
|
const NodeStrategy& strategy = fTreeMap.GetNodeStrategy();
|
||||||
|
|
||||||
|
Node* parent;
|
||||||
|
Node* node = _FindFirst(key, &parent);
|
||||||
|
if (node == NULL) {
|
||||||
|
// not found -- try to get the closest node
|
||||||
|
if (parent == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
node = parent;
|
||||||
|
int expectedCmp = less ? 1 : -1;
|
||||||
|
int cmp = fPrimaryKeyCompare(key,
|
||||||
|
fGetPrimaryKey(strategy.GetValue(strategy.GetNode(node))));
|
||||||
|
|
||||||
|
if (cmp != expectedCmp) {
|
||||||
|
// The node's value is less although we were asked for a greater
|
||||||
|
// value, or the other way around. We need to iterate to the next
|
||||||
|
// node in the respective direction. If there is no node, we fail.
|
||||||
|
node = less ? Previous(node) : Next(node);
|
||||||
|
if (node == NULL)
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (iterator != NULL)
|
||||||
|
iterator->_SetTo(fTreeMap.GetIterator(node));
|
||||||
|
|
||||||
|
return &strategy.GetValue(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
TWO_KEY_AVL_TREE_TEMPLATE_LIST
|
||||||
|
Value*
|
||||||
|
TWO_KEY_AVL_TREE_CLASS_NAME::FindLast(const PrimaryKey& key,
|
||||||
|
Iterator* iterator)
|
||||||
{
|
{
|
||||||
const NodeStrategy& strategy = fTreeMap.GetNodeStrategy();
|
const NodeStrategy& strategy = fTreeMap.GetNodeStrategy();
|
||||||
Node* node = fTreeMap.RootNode();
|
Node* node = fTreeMap.RootNode();
|
||||||
@ -565,4 +594,42 @@ TWO_KEY_AVL_TREE_CLASS_NAME::Remove(Node* node)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
TWO_KEY_AVL_TREE_TEMPLATE_LIST
|
||||||
|
TWO_KEY_AVL_TREE_CLASS_NAME::Node*
|
||||||
|
TWO_KEY_AVL_TREE_CLASS_NAME::_FindFirst(const PrimaryKey& key,
|
||||||
|
Node** _parent) const
|
||||||
|
{
|
||||||
|
const NodeStrategy& strategy = fTreeMap.GetNodeStrategy();
|
||||||
|
Node* node = fTreeMap.RootNode();
|
||||||
|
Node* parent = NULL;
|
||||||
|
|
||||||
|
while (node) {
|
||||||
|
int cmp = fPrimaryKeyCompare(key, fGetPrimaryKey(
|
||||||
|
strategy.GetValue(node)));
|
||||||
|
if (cmp == 0) {
|
||||||
|
// found a matching node, now get the left-most node with that key
|
||||||
|
while (node->left && fPrimaryKeyCompare(key,
|
||||||
|
fGetPrimaryKey(strategy.GetValue(
|
||||||
|
strategy.GetNode(node->left)))) == 0) {
|
||||||
|
node = strategy.GetNode(node->left);
|
||||||
|
}
|
||||||
|
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
parent = node;
|
||||||
|
|
||||||
|
if (cmp < 0)
|
||||||
|
node = strategy.GetNode(node->left);
|
||||||
|
else
|
||||||
|
node = strategy.GetNode(node->right);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_parent != NULL)
|
||||||
|
*_parent = parent;
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif // _KERNEL_UTIL_TWO_KEY_AVL_TREE_H
|
#endif // _KERNEL_UTIL_TWO_KEY_AVL_TREE_H
|
||||||
|
Loading…
Reference in New Issue
Block a user