220 lines
3.2 KiB
C++
220 lines
3.2 KiB
C++
|
/*++
|
||
|
|
||
|
Copyright (c) 1993 Microsoft Corporation
|
||
|
|
||
|
Module Name:
|
||
|
|
||
|
treemap.cxx
|
||
|
|
||
|
Abstract:
|
||
|
|
||
|
Author:
|
||
|
|
||
|
Matthew Bradburn (mattbr) 01-Dec-1993
|
||
|
|
||
|
Environment:
|
||
|
|
||
|
ULIB, User Mode
|
||
|
|
||
|
--*/
|
||
|
|
||
|
#include "treemap.hxx"
|
||
|
|
||
|
BOOLEAN
|
||
|
TREE_MAP::Initialize(
|
||
|
USHORT size
|
||
|
)
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
This routine ...
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
TRUE - Success.
|
||
|
FALSE - Failure.
|
||
|
|
||
|
--*/
|
||
|
{
|
||
|
_map = (PTREE_MAP_ENTRY) MALLOC(size * sizeof(TREE_MAP_ENTRY));
|
||
|
if (NULL == _map) {
|
||
|
return FALSE;
|
||
|
}
|
||
|
memset(_map, 0, size * sizeof(TREE_MAP_ENTRY));
|
||
|
_size = 0;
|
||
|
_max_size = size;
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
VOID
|
||
|
TREE_MAP::SetEntry(USHORT child, USHORT parent)
|
||
|
{
|
||
|
USHORT i;
|
||
|
|
||
|
i = QueryEntry(child);
|
||
|
if (0 != i) {
|
||
|
_map[i].parent = parent;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// There is no such child in the map. Stick it in, making room
|
||
|
// if necessary.
|
||
|
//
|
||
|
|
||
|
for (i = 0; i < _size; ++i) {
|
||
|
if (_map[i].child > child) {
|
||
|
// insert the new entry here
|
||
|
|
||
|
DbgAssert(_size < _max_size);
|
||
|
_size++;
|
||
|
|
||
|
memmove(&_map[i + 1], &_map[i], (_size - i)*sizeof(TREE_MAP_ENTRY));
|
||
|
_map[i].child = child;
|
||
|
_map[i].parent = parent;
|
||
|
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// the new entry goes after all the existing entries.
|
||
|
|
||
|
DbgAssert(_size < _max_size);
|
||
|
|
||
|
_map[_size].child = child;
|
||
|
_map[_size].parent = parent;
|
||
|
|
||
|
_size++;
|
||
|
}
|
||
|
|
||
|
USHORT
|
||
|
TREE_MAP::DeleteEntry(
|
||
|
USHORT child
|
||
|
)
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
This routine deletes the entry that points from the given
|
||
|
child to it's parent.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
The child to delete.
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
The dead child's parent. 0 is returned if there was no entry
|
||
|
for the given child.
|
||
|
|
||
|
--*/
|
||
|
{
|
||
|
USHORT i;
|
||
|
USHORT parent;
|
||
|
|
||
|
for (i = 0; i < _size; ++i) {
|
||
|
if (_map[i].child == child) {
|
||
|
break;
|
||
|
}
|
||
|
if (_map[i].child > child) {
|
||
|
return 0;
|
||
|
}
|
||
|
}
|
||
|
if (i == _size) {
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
_size--;
|
||
|
|
||
|
if (i == _size) {
|
||
|
//
|
||
|
// Deleting the last entry.
|
||
|
//
|
||
|
return _map[i].parent;
|
||
|
}
|
||
|
|
||
|
parent = _map[i].parent;
|
||
|
|
||
|
memmove(&_map[i], &_map[i + 1], (_size - i)*sizeof(TREE_MAP_ENTRY));
|
||
|
|
||
|
return parent;
|
||
|
}
|
||
|
|
||
|
|
||
|
USHORT
|
||
|
TREE_MAP::QueryEntry(
|
||
|
USHORT child
|
||
|
) CONST
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
This routine does a binary search for the given child, and returns
|
||
|
the corresponding parent.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
0 - if there is no mapping for the child
|
||
|
otherwise - the corresponding parent.
|
||
|
|
||
|
--*/
|
||
|
{
|
||
|
int bottom, top, middle;
|
||
|
|
||
|
if (0 == _size) {
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
bottom = 0;
|
||
|
top = _size - 1;
|
||
|
|
||
|
for (;;) {
|
||
|
if (bottom > top) {
|
||
|
// not found
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
middle = (bottom + top) / 2;
|
||
|
|
||
|
if (_map[middle].child < child) {
|
||
|
// go to the high side
|
||
|
|
||
|
bottom = middle + 1;
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
if (_map[middle].child > child) {
|
||
|
// go to the low side
|
||
|
|
||
|
top = middle - 1;
|
||
|
|
||
|
if (top < 0) {
|
||
|
return 0;
|
||
|
}
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
// bingo
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
return _map[middle].parent;
|
||
|
}
|
||
|
|
||
|
VOID
|
||
|
TREE_MAP::ReplaceParent(
|
||
|
USHORT OldParent,
|
||
|
USHORT NewParent
|
||
|
)
|
||
|
{
|
||
|
for (ULONG i = 0; i < _size; ++i) {
|
||
|
if (_map[i].parent == OldParent) {
|
||
|
_map[i].parent = NewParent;
|
||
|
}
|
||
|
}
|
||
|
}
|