psblas2-dev:
Changelog base/internals/Makefile base/internals/avltree.c base/internals/avltree.h base/internals/psi_bld_tmphalo.f90 base/internals/psi_fnd_owner.f90 base/internals/psi_idx_cnv.f90 base/internals/psi_idx_ins_cnv.f90 base/internals/srcht.c base/modules/Makefile base/modules/psb_avl_mod.f90 base/modules/psb_desc_type.f90 base/tools/psb_cd_inloc.f90 base/tools/psb_cdals.f90 base/tools/psb_cdalv.f90 base/tools/psb_cdins.f90 base/tools/psb_icdasb.F90 Merged AVL changes.psblas3-type-indexed
parent
44cffb0d36
commit
d616b83f6f
@ -1,822 +0,0 @@
|
|||||||
/*
|
|
||||||
* Parallel Sparse BLAS version 2.2
|
|
||||||
* (C) Copyright 2006/2007/2008
|
|
||||||
* Salvatore Filippone University of Rome Tor Vergata
|
|
||||||
* Alfredo Buttari University of Rome Tor Vergata
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions
|
|
||||||
* are met:
|
|
||||||
* 1. Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions, and the following disclaimer in the
|
|
||||||
* documentation and/or other materials provided with the distribution.
|
|
||||||
* 3. The name of the PSBLAS group or the names of its contributors may
|
|
||||||
* not be used to endorse or promote products derived from this
|
|
||||||
* software without specific written permission.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
|
||||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
|
||||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE PSBLAS GROUP OR ITS CONTRIBUTORS
|
|
||||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
||||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
||||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
||||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
||||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
||||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
||||||
* POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
/*****************************************************************/
|
|
||||||
/* */
|
|
||||||
/* avltree.c: balanced AVL tree search and insertion */
|
|
||||||
/* written by: Salvatore Filippone */
|
|
||||||
/* */
|
|
||||||
/* Last updated: Mar 09 2004 */
|
|
||||||
/* */
|
|
||||||
/* Referrences: [1] D. E. Knuth */
|
|
||||||
/* The Art of Computer Programming */
|
|
||||||
/* Vol. 3: Sorting and Searching, sec. 6.2.3 */
|
|
||||||
/* Addison-Wesley */
|
|
||||||
/* */
|
|
||||||
/* General description: */
|
|
||||||
/* */
|
|
||||||
/* Build and maintain a balanced binary search tree with */
|
|
||||||
/* arbitrary keys. The user is responsible for providing */
|
|
||||||
/* compare functions operating on the keys themselves. */
|
|
||||||
/* Key pointers are stored into nodes that are managed */
|
|
||||||
/* by the subroutine calls; the user should never examine */
|
|
||||||
/* nodes directly. */
|
|
||||||
/* The nodes for user items are allocated in batches, */
|
|
||||||
/* and the batches are kept as a doubly linked list. */
|
|
||||||
/* */
|
|
||||||
/* Data types: */
|
|
||||||
/* AVLTree: structure containing pointers to the list */
|
|
||||||
/* of node batches and to the root of the binary tree */
|
|
||||||
/* structure */
|
|
||||||
/* */
|
|
||||||
/* AVLNode: binary tree node, containing link pointers */
|
|
||||||
/* a reserved field, and a pointer to user data */
|
|
||||||
/* */
|
|
||||||
/* */
|
|
||||||
/* User callable functions: */
|
|
||||||
/* */
|
|
||||||
/* AVLTreePtr GetAVLTree() */
|
|
||||||
/* Purpose: allocate a new tree; */
|
|
||||||
/* Function value: a fresh AVL tree pointer; */
|
|
||||||
/* returns NULL in case of a memory failure*/
|
|
||||||
/* */
|
|
||||||
/* */
|
|
||||||
/* int AVLTreeReInit(AVLTreePtr Tree) */
|
|
||||||
/* Purpose: reinitialize an existing AVL Tree, reusing */
|
|
||||||
/* node batches already allocated. */
|
|
||||||
/* Input: 1. Tree */
|
|
||||||
/* A pointer to an existing tree structure */
|
|
||||||
/* Function value: 0 Normal termination */
|
|
||||||
/* -1 Invalid input pointer */
|
|
||||||
/* -3 Memory allocation failure */
|
|
||||||
/* */
|
|
||||||
/* AVLNodePtr AVLTreeSearch(AVLTreePtr Tree, void *key, */
|
|
||||||
/* int (*comp)(void*, void*)) */
|
|
||||||
/* Purpose: search an existing AVL Tree for a key */
|
|
||||||
/* Input: 1. Tree */
|
|
||||||
/* A valid pointer to a Tree */
|
|
||||||
/* 2. key */
|
|
||||||
/* The item being searched for */
|
|
||||||
/* 3. comp */
|
|
||||||
/* A comparison function: */
|
|
||||||
/* a<b => comp(a,b)<0 */
|
|
||||||
/* a==b => comp(a,b)=0 */
|
|
||||||
/* a>b => comp(a,b)>0 */
|
|
||||||
/* The function is always invoked as: */
|
|
||||||
/* comp(user_key,tree_key); */
|
|
||||||
/* */
|
|
||||||
/* */
|
|
||||||
/* Function value: NULL: input error or item not found */
|
|
||||||
/* valid pointer: pointer to a node */
|
|
||||||
/* containing the key */
|
|
||||||
/* */
|
|
||||||
/* int AVLTreeInsert(AVLTreePtr Tree, void *key, */
|
|
||||||
/* int (*comp)(void*,void*), */
|
|
||||||
/* void (*update)(void*,void*,void*), */
|
|
||||||
/* void *data) */
|
|
||||||
/* Purpose: Insert an item into an existing (possibly */
|
|
||||||
/* empty) tree. */
|
|
||||||
/* */
|
|
||||||
/* Input: 1. Tree */
|
|
||||||
/* The (existing) tree */
|
|
||||||
/* 2. key */
|
|
||||||
/* The (new) item to be inserted */
|
|
||||||
/* 3. comp */
|
|
||||||
/* comparison function (as in AVLTreeSearch) */
|
|
||||||
/* 4. update */
|
|
||||||
/* A user provided function to be called when */
|
|
||||||
/* the key is already present in the tree */
|
|
||||||
/* with the calling sequence: */
|
|
||||||
/* update(new_key,existing_key) */
|
|
||||||
/* enables the user to specify an arbitrary */
|
|
||||||
/* update procedure. */
|
|
||||||
/* */
|
|
||||||
/* */
|
|
||||||
/* */
|
|
||||||
/* AVLNodePtr AVLTreeUserInsert(AVLTreePtr Tree, void *key, */
|
|
||||||
/* int (*comp)(void*,void*)) */
|
|
||||||
/* */
|
|
||||||
/* Purpose: Insert an item into an existing (possibly */
|
|
||||||
/* empty) tree; returns a pointer to a node */
|
|
||||||
/* containing the item, even when that node */
|
|
||||||
/* was already existing; does no update */
|
|
||||||
/* */
|
|
||||||
/* Input: 1. Tree */
|
|
||||||
/* The (existing) tree */
|
|
||||||
/* 2. key */
|
|
||||||
/* The (new) item to be inserted */
|
|
||||||
/* 3. comp */
|
|
||||||
/* comparison function (as in AVLTreeSearch) */
|
|
||||||
/* */
|
|
||||||
/* Function value: Valid pointer: pointer to a node */
|
|
||||||
/* containing the item (possibly */
|
|
||||||
/* was already there) */
|
|
||||||
/* NULL input error or memory failure */
|
|
||||||
/* */
|
|
||||||
/* */
|
|
||||||
/* int HowManyKeys(AVLTreePtr Tree) */
|
|
||||||
/* Purpose: how many keys does Tree contain? */
|
|
||||||
/* Function value: >=0 */
|
|
||||||
/* */
|
|
||||||
/* */
|
|
||||||
/* void AVLTreeInorderTraverse(AVLTreePtr Tree, */
|
|
||||||
/* void (*func)( void*, void*), void *data) */
|
|
||||||
/* */
|
|
||||||
/* Purpose: visit the nodes of the binary tree in their */
|
|
||||||
/* natural order, performing an arbitrary */
|
|
||||||
/* task upon visit. */
|
|
||||||
/* Input: 1. Tree */
|
|
||||||
/* A tree pointer */
|
|
||||||
/* 2. func */
|
|
||||||
/* A function performing a user specified */
|
|
||||||
/* task on each node; the fuction is invoked as */
|
|
||||||
/* func( key,data) */
|
|
||||||
/* where data is parm. 3 */
|
|
||||||
/* 3. data */
|
|
||||||
/* Auxiliary data to be passed to func upon */
|
|
||||||
/* each visit */
|
|
||||||
/* */
|
|
||||||
/* int AVLTreeInorderTraverseWithDelims(AVLTreePtr Tree, */
|
|
||||||
/* void *first, void *last, int (*comp)(void*,void*) */
|
|
||||||
/* void (*func)( void*, void*), void *data) */
|
|
||||||
/* */
|
|
||||||
/* Purpose: visit the nodes of the binary tree in their */
|
|
||||||
/* natural order, performing an arbitrary */
|
|
||||||
/* task upon visit, but only on nodes */
|
|
||||||
/* with their key within a specified range. */
|
|
||||||
/* */
|
|
||||||
/* Input: 1. Tree */
|
|
||||||
/* A tree pointer */
|
|
||||||
/* 2. first */
|
|
||||||
/* Visit nodes with first <= node->key */
|
|
||||||
/* 3. last */
|
|
||||||
/* Visit nodes with node->key <= last */
|
|
||||||
/* 4. comp */
|
|
||||||
/* comparison function (as in AVLTreeSearch) */
|
|
||||||
/* 5. func */
|
|
||||||
/* A function performing a user specified */
|
|
||||||
/* task on each node; the fuction is invoked as */
|
|
||||||
/* func( key,data) */
|
|
||||||
/* where data is parm. 3 */
|
|
||||||
/* 6. data */
|
|
||||||
/* Auxiliary data to be passed to func upon */
|
|
||||||
/* each visit */
|
|
||||||
/* Function value: total number of nodes visited (>=0) */
|
|
||||||
/* */
|
|
||||||
/* */
|
|
||||||
/* */
|
|
||||||
/* void AVLTreeFree(AVLTreePtr Tree, void (*ffree)(void*)) */
|
|
||||||
/* Purpose: free up tree data storage */
|
|
||||||
/* Does NOT free the Tree pointer itself, */
|
|
||||||
/* rather all the structures that it points to */
|
|
||||||
/* Input: 1. Tree */
|
|
||||||
/* A tree pointer */
|
|
||||||
/* 2. ffree */
|
|
||||||
/* A user specified function invoked on each */
|
|
||||||
/* key pointer contained in the tree to free */
|
|
||||||
/* its memory (if necessary). Can be NULL. */
|
|
||||||
/* */
|
|
||||||
/* */
|
|
||||||
/*****************************************************************/
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include "avltree.h"
|
|
||||||
|
|
||||||
#define POOLSIZE 1024
|
|
||||||
#define MAXSTACK 64
|
|
||||||
#define MAX(a,b) ((a)>=(b) ? (a) : (b))
|
|
||||||
|
|
||||||
typedef struct avltvect {
|
|
||||||
AVLNode pool[POOLSIZE];
|
|
||||||
int avail;
|
|
||||||
AVLTVectPtr previous, next;
|
|
||||||
} AVLTVect;
|
|
||||||
|
|
||||||
|
|
||||||
int HowManyItems(AVLTreePtr Tree)
|
|
||||||
{
|
|
||||||
if (Tree==NULL) {
|
|
||||||
return(0);
|
|
||||||
} else {
|
|
||||||
return(Tree->nnodes);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
AVLTreePtr GetAVLTree()
|
|
||||||
{
|
|
||||||
AVLTreePtr tree;
|
|
||||||
if ((tree=(AVLTreePtr) malloc(sizeof(AVLTree)))!=NULL){
|
|
||||||
memset(tree,'\0',sizeof(AVLTree));
|
|
||||||
AVLTreeInit(tree);
|
|
||||||
}
|
|
||||||
return(tree);
|
|
||||||
}
|
|
||||||
|
|
||||||
int AVLTreeInit(AVLTreePtr Tree)
|
|
||||||
{
|
|
||||||
/* AVLTVectPtr current; */
|
|
||||||
if (Tree==NULL) {
|
|
||||||
fprintf(stderr,"Cannot initialize a NULL Tree pointer\n");
|
|
||||||
return(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Tree->first!=NULL) {
|
|
||||||
fprintf(stderr,"Cannot initialize a nonempty Tree: call AVLTreeFree first\n");
|
|
||||||
return(-2);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* if ((current=(AVLTVectPtr)malloc(sizeof(AVLTVect)))==NULL) { */
|
|
||||||
/* fprintf(stderr,"Memory allocation failure\n"); */
|
|
||||||
/* return(-3); */
|
|
||||||
/* } */
|
|
||||||
/* memset(current,'\0',sizeof(AVLTVect)); */
|
|
||||||
Tree->first=Tree->current=NULL;
|
|
||||||
Tree->nnodes=0;
|
|
||||||
Tree->root=NULL;
|
|
||||||
return(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
int AVLTreeReInit(AVLTreePtr Tree)
|
|
||||||
{
|
|
||||||
AVLTVectPtr current /* , next */ ;
|
|
||||||
if (Tree==NULL) {
|
|
||||||
fprintf(stderr,"Cannot ReInitialize a NULL Tree pointer\n");
|
|
||||||
return(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Tree->first!=NULL) {
|
|
||||||
current=Tree->first;
|
|
||||||
while (current!=NULL) {
|
|
||||||
current->avail=0;
|
|
||||||
memset(current->pool,'\0',POOLSIZE*sizeof(AVLNode));
|
|
||||||
current=current->next;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if ((current=(AVLTVectPtr)malloc(sizeof(AVLTVect)))==NULL) {
|
|
||||||
fprintf(stderr,"Memory allocation failure\n");
|
|
||||||
return(-3);
|
|
||||||
}
|
|
||||||
current->avail=0;
|
|
||||||
current->previous=current->next=NULL;
|
|
||||||
Tree->first=current;
|
|
||||||
}
|
|
||||||
Tree->current=Tree->first;
|
|
||||||
Tree->nnodes=0;
|
|
||||||
Tree->root=NULL;
|
|
||||||
return(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
AVLNodePtr AVLTreeSearch(AVLTreePtr Tree, void *key,
|
|
||||||
int (*comp)(void *, void *))
|
|
||||||
{
|
|
||||||
AVLNodePtr current;
|
|
||||||
int icmp;
|
|
||||||
if (Tree==NULL) return(NULL);
|
|
||||||
current = Tree->root;
|
|
||||||
#ifdef PROFILE
|
|
||||||
Tree->nsteps=0;
|
|
||||||
#endif
|
|
||||||
while (current != NULL) {
|
|
||||||
icmp = (*comp)(key,current->key);
|
|
||||||
#ifdef PROFILE
|
|
||||||
Tree->nsteps +=1;
|
|
||||||
#endif
|
|
||||||
if (icmp<0) {
|
|
||||||
current = current->llink;
|
|
||||||
} else if (icmp==0){
|
|
||||||
return(current);
|
|
||||||
} else if (icmp>0) {
|
|
||||||
current = current->rlink;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return(current);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AVLTreeInorderTraverse(AVLTreePtr Tree, void (*func)(void *, void *),
|
|
||||||
void *data)
|
|
||||||
{
|
|
||||||
int lev;
|
|
||||||
AVLNodePtr root;
|
|
||||||
|
|
||||||
AVLNodePtr stack[MAXSTACK+2];
|
|
||||||
int choice[MAXSTACK+2];
|
|
||||||
root=Tree->root;
|
|
||||||
if (root == NULL) return;
|
|
||||||
|
|
||||||
lev=0;
|
|
||||||
stack[lev] = root;
|
|
||||||
choice[lev] = -1;
|
|
||||||
|
|
||||||
while (lev>=0) {
|
|
||||||
if (stack[lev]==NULL) {
|
|
||||||
lev--;
|
|
||||||
} else {
|
|
||||||
if (choice[lev]==-1) {
|
|
||||||
stack[lev+1] = stack[lev]->llink;
|
|
||||||
choice[lev+1] = -1;
|
|
||||||
choice[lev] += 1;
|
|
||||||
lev++;
|
|
||||||
} else if (choice[lev]==0) {
|
|
||||||
(*func)(stack[lev]->key,data);
|
|
||||||
stack[lev+1] = stack[lev]->rlink;
|
|
||||||
choice[lev+1] = -1;
|
|
||||||
choice[lev] += 1;
|
|
||||||
lev++;
|
|
||||||
} else {
|
|
||||||
lev--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int AVLTreeInorderTraverseWithDelims(AVLTreePtr Tree, void *first, void *last,
|
|
||||||
int (*comp)(void*, void*),
|
|
||||||
void (*func)(void *, void *),
|
|
||||||
void *data)
|
|
||||||
{
|
|
||||||
AVLNodePtr root, current;
|
|
||||||
int lev, nvisit, icmp;
|
|
||||||
AVLNodePtr stack[MAXSTACK+2];
|
|
||||||
int choice[MAXSTACK+2];
|
|
||||||
|
|
||||||
root=Tree->root;
|
|
||||||
if (root == NULL) return(0);
|
|
||||||
|
|
||||||
nvisit=0;
|
|
||||||
lev=0;
|
|
||||||
current = root;
|
|
||||||
while (current != NULL) {
|
|
||||||
stack[lev] = current;
|
|
||||||
icmp = (*comp)(first,current->key);
|
|
||||||
if (icmp<=0) {
|
|
||||||
choice[lev]=0;
|
|
||||||
current = current->llink;
|
|
||||||
} else if (icmp>0) {
|
|
||||||
current = current->rlink;
|
|
||||||
choice[lev]=1;
|
|
||||||
}
|
|
||||||
lev++;
|
|
||||||
}
|
|
||||||
lev--;
|
|
||||||
while (lev>=0) {
|
|
||||||
if (stack[lev]==NULL) {
|
|
||||||
lev--;
|
|
||||||
} else {
|
|
||||||
if (choice[lev]==-1) {
|
|
||||||
stack[lev+1] = stack[lev]->llink;
|
|
||||||
choice[lev+1] = -1;
|
|
||||||
choice[lev] += 1;
|
|
||||||
lev++;
|
|
||||||
} else if (choice[lev]==0) {
|
|
||||||
if (((*comp)(last,stack[lev]->key))<0) {
|
|
||||||
lev--;
|
|
||||||
} else {
|
|
||||||
(*func)(stack[lev]->key,data);
|
|
||||||
nvisit++;
|
|
||||||
stack[lev+1] = stack[lev]->rlink;
|
|
||||||
choice[lev+1] = -1;
|
|
||||||
choice[lev] += 1;
|
|
||||||
lev++;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
lev--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return(nvisit);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AVLTreePreorderTraverse(AVLTreePtr Tree, void (*func)(void *, void *),
|
|
||||||
void *data)
|
|
||||||
{
|
|
||||||
AVLNodePtr root;
|
|
||||||
int lev;
|
|
||||||
AVLNodePtr stack[MAXSTACK+2];
|
|
||||||
int choice[MAXSTACK+2];
|
|
||||||
|
|
||||||
root=Tree->root;
|
|
||||||
if (root == NULL) return;
|
|
||||||
lev=0;
|
|
||||||
stack[lev] = root;
|
|
||||||
choice[lev] = -1;
|
|
||||||
|
|
||||||
while (lev>=0) {
|
|
||||||
if (stack[lev]==NULL) {
|
|
||||||
lev--;
|
|
||||||
} else {
|
|
||||||
if (choice[lev]==-1) {
|
|
||||||
(*func)(stack[lev]->key,data);
|
|
||||||
stack[lev+1] = stack[lev]->llink;
|
|
||||||
choice[lev+1] = -1;
|
|
||||||
choice[lev] += 1;
|
|
||||||
lev++;
|
|
||||||
} else if (choice[lev]==0) {
|
|
||||||
stack[lev+1] = stack[lev]->rlink;
|
|
||||||
choice[lev+1] = -1;
|
|
||||||
choice[lev] += 1;
|
|
||||||
lev++;
|
|
||||||
} else {
|
|
||||||
lev--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AVLTreeFree(AVLTreePtr Tree, void (*ffree)(void *))
|
|
||||||
{
|
|
||||||
AVLTVectPtr current, next;
|
|
||||||
int i;
|
|
||||||
if (Tree == NULL) return;
|
|
||||||
|
|
||||||
current=Tree->first;
|
|
||||||
|
|
||||||
while (current != NULL) {
|
|
||||||
next=current->next;
|
|
||||||
if (*ffree != NULL) {
|
|
||||||
for (i=0; i<current->avail; i++)
|
|
||||||
(*ffree)((current->pool[i]).key);
|
|
||||||
}
|
|
||||||
free(current);
|
|
||||||
current=next;
|
|
||||||
}
|
|
||||||
Tree->nnodes=0;
|
|
||||||
Tree->first=Tree->current=NULL;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
AVLNodePtr GetAVLNode(AVLTreePtr Tree)
|
|
||||||
{
|
|
||||||
AVLTVectPtr current, new;
|
|
||||||
AVLNodePtr newnode;
|
|
||||||
|
|
||||||
if (Tree==NULL) {
|
|
||||||
return(NULL);
|
|
||||||
}
|
|
||||||
if ((current=Tree->current)==NULL) {
|
|
||||||
if ((current=(AVLTVectPtr)malloc(sizeof(AVLTVect)))==NULL) {
|
|
||||||
fprintf(stderr,"Memory allocation failure\n");
|
|
||||||
return(NULL);
|
|
||||||
}
|
|
||||||
memset(current,'\0',sizeof(AVLTVect));
|
|
||||||
Tree->first=Tree->current=current;
|
|
||||||
}
|
|
||||||
|
|
||||||
while ((current->avail>=POOLSIZE)&&(current->next!=NULL))
|
|
||||||
current=current->next;
|
|
||||||
|
|
||||||
if (current->avail<POOLSIZE) {
|
|
||||||
newnode=&(current->pool[current->avail]);
|
|
||||||
current->avail += 1;
|
|
||||||
} else {
|
|
||||||
if ((new=(AVLTVectPtr)malloc(sizeof(AVLTVect)))==NULL) {
|
|
||||||
fprintf(stderr,"Memory allocation failure\n");
|
|
||||||
return(NULL);
|
|
||||||
}
|
|
||||||
memset(new,'\0',sizeof(AVLTVect));
|
|
||||||
newnode=&(new->pool[0]);
|
|
||||||
new->avail = 1;
|
|
||||||
current->next=new;
|
|
||||||
new->previous=current;
|
|
||||||
new->next=NULL;
|
|
||||||
Tree->current=new;
|
|
||||||
}
|
|
||||||
return(newnode);
|
|
||||||
}
|
|
||||||
|
|
||||||
int AVLTreeInsert(AVLTreePtr Tree, void *key,int (*comp)(void *, void *),
|
|
||||||
void (*update)(void *, void *, void *), void *data)
|
|
||||||
{
|
|
||||||
AVLNodePtr root, t, s, p, q, r;
|
|
||||||
int search, bal, icmp;
|
|
||||||
|
|
||||||
if (Tree==NULL) {
|
|
||||||
fprintf(stderr,"Fatal error: null tree pointer\n");
|
|
||||||
return(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((root = Tree->root) == NULL) {
|
|
||||||
if ((t=GetAVLNode(Tree))==NULL) {
|
|
||||||
return(-2);
|
|
||||||
}
|
|
||||||
t->key = key;
|
|
||||||
t->rlink=t->llink=NULL;
|
|
||||||
t->bal=0;
|
|
||||||
Tree->root = t;
|
|
||||||
Tree->nnodes=1;
|
|
||||||
return(0);
|
|
||||||
}
|
|
||||||
t = NULL;
|
|
||||||
s = root;
|
|
||||||
p = root;
|
|
||||||
search=1;
|
|
||||||
while (search) {
|
|
||||||
icmp = (*comp)(key,p->key);
|
|
||||||
if (icmp<0) {
|
|
||||||
if ((q=p->llink)==NULL) {
|
|
||||||
if ((q=GetAVLNode(Tree))==NULL) {
|
|
||||||
return(-2);
|
|
||||||
}
|
|
||||||
p->llink=q;
|
|
||||||
search=0;
|
|
||||||
} else {
|
|
||||||
if (q->bal != 0) {
|
|
||||||
t=p;
|
|
||||||
s=q;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (icmp == 0) {
|
|
||||||
(*update)(key,p->key,data);
|
|
||||||
return(1);
|
|
||||||
} else {
|
|
||||||
if ((q=p->rlink)==NULL) {
|
|
||||||
if ((q=GetAVLNode(Tree))==NULL) {
|
|
||||||
return(-2);
|
|
||||||
}
|
|
||||||
p->rlink=q;
|
|
||||||
search=0;
|
|
||||||
} else {
|
|
||||||
if (q->bal != 0) {
|
|
||||||
t=p;
|
|
||||||
s=q;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
p=q;
|
|
||||||
}
|
|
||||||
q->key=key;
|
|
||||||
q->llink=q->rlink=NULL;
|
|
||||||
q->bal=0;
|
|
||||||
Tree->nnodes += 1;
|
|
||||||
|
|
||||||
if ((*comp)(key,s->key)<0) {
|
|
||||||
r=p=s->llink;
|
|
||||||
} else {
|
|
||||||
r=p=s->rlink;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (p!=q) {
|
|
||||||
if ((*comp)(key,p->key)<0) {
|
|
||||||
p->bal=-1;
|
|
||||||
p = p->llink;
|
|
||||||
} else {
|
|
||||||
p->bal=1;
|
|
||||||
p=p->rlink;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((*comp)(key,s->key)<0) {
|
|
||||||
bal=-1;
|
|
||||||
} else {
|
|
||||||
bal=1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (s->bal == 0) {
|
|
||||||
s->bal=bal;
|
|
||||||
return (0);
|
|
||||||
} else if (s->bal == -bal) {
|
|
||||||
s->bal=0;
|
|
||||||
return (0);
|
|
||||||
} else if (s->bal == bal) {
|
|
||||||
|
|
||||||
if (r->bal == bal) {
|
|
||||||
/* single rotation */
|
|
||||||
p=r;
|
|
||||||
if (bal>0) {
|
|
||||||
s->rlink=r->llink;
|
|
||||||
r->llink=s;
|
|
||||||
} else {
|
|
||||||
s->llink=r->rlink;
|
|
||||||
r->rlink=s;
|
|
||||||
}
|
|
||||||
s->bal=r->bal=0;
|
|
||||||
} else if (r->bal == -bal) {
|
|
||||||
/* double rotation */
|
|
||||||
if (bal>0) {
|
|
||||||
p=r->llink;
|
|
||||||
r->llink=p->rlink;
|
|
||||||
p->rlink=r;
|
|
||||||
s->rlink=p->llink;
|
|
||||||
p->llink=s;
|
|
||||||
} else {
|
|
||||||
p=r->rlink;
|
|
||||||
r->rlink=p->llink;
|
|
||||||
p->llink=r;
|
|
||||||
s->llink=p->rlink;
|
|
||||||
p->rlink=s;
|
|
||||||
}
|
|
||||||
if (p->bal == bal) {
|
|
||||||
s->bal=-bal;
|
|
||||||
r->bal=0;
|
|
||||||
} else if (p->bal==0) {
|
|
||||||
s->bal=r->bal=0;
|
|
||||||
} else {
|
|
||||||
r->bal=bal;
|
|
||||||
s->bal=0;
|
|
||||||
}
|
|
||||||
p->bal=0;
|
|
||||||
}
|
|
||||||
if (t==NULL) {
|
|
||||||
root=p;
|
|
||||||
} else {
|
|
||||||
if (t->rlink==s) {
|
|
||||||
t->rlink=p;
|
|
||||||
} else {
|
|
||||||
t->llink=p;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Tree->root=root;
|
|
||||||
return(0);
|
|
||||||
}
|
|
||||||
return(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
AVLNodePtr AVLTreeUserInsert(AVLTreePtr Tree, void *key,
|
|
||||||
int (*comp)(void *, void *))
|
|
||||||
{
|
|
||||||
AVLNodePtr root, t, s, p, q, r;
|
|
||||||
int search, bal, icmp;
|
|
||||||
|
|
||||||
if (Tree==NULL) {
|
|
||||||
fprintf(stderr,"Fatal error: null tree pointer\n");
|
|
||||||
return(NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((root = Tree->root) == NULL) {
|
|
||||||
if ((t=GetAVLNode(Tree))==NULL) {
|
|
||||||
return(NULL);
|
|
||||||
}
|
|
||||||
t->key = key;
|
|
||||||
t->rlink=t->llink=NULL;
|
|
||||||
t->bal=0;
|
|
||||||
Tree->root = t;
|
|
||||||
Tree->nnodes=1;
|
|
||||||
return(t);
|
|
||||||
}
|
|
||||||
t = NULL;
|
|
||||||
s = root;
|
|
||||||
p = root;
|
|
||||||
search=1;
|
|
||||||
while (search) {
|
|
||||||
icmp = (*comp)(key,p->key);
|
|
||||||
if (icmp<0) {
|
|
||||||
if ((q=p->llink)==(AVLNodePtr) NULL) {
|
|
||||||
if ((q=GetAVLNode(Tree))==NULL) {
|
|
||||||
return(NULL);
|
|
||||||
}
|
|
||||||
p->llink=q;
|
|
||||||
search=0;
|
|
||||||
} else {
|
|
||||||
if (q->bal != 0) {
|
|
||||||
t=p;
|
|
||||||
s=q;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (icmp == 0) {
|
|
||||||
return(p);
|
|
||||||
} else {
|
|
||||||
if ((q=p->rlink)==NULL) {
|
|
||||||
if ((q=GetAVLNode(Tree))==NULL) {
|
|
||||||
return(NULL);
|
|
||||||
}
|
|
||||||
p->rlink=q;
|
|
||||||
search=0;
|
|
||||||
} else {
|
|
||||||
if (q->bal != 0) {
|
|
||||||
t=p;
|
|
||||||
s=q;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
p=q;
|
|
||||||
}
|
|
||||||
q->key=key;
|
|
||||||
q->llink=q->rlink=NULL;
|
|
||||||
q->bal=0;
|
|
||||||
Tree->nnodes += 1;
|
|
||||||
|
|
||||||
if ((*comp)(key,s->key)<0) {
|
|
||||||
r=p=s->llink;
|
|
||||||
} else {
|
|
||||||
r=p=s->rlink;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (p!=q) {
|
|
||||||
if ((*comp)(key,p->key)<0) {
|
|
||||||
p->bal=-1;
|
|
||||||
p = p->llink;
|
|
||||||
} else {
|
|
||||||
p->bal=1;
|
|
||||||
p=p->rlink;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((*comp)(key,s->key)<0) {
|
|
||||||
bal=-1;
|
|
||||||
} else {
|
|
||||||
bal=1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (s->bal == 0) {
|
|
||||||
s->bal=bal;
|
|
||||||
return (q);
|
|
||||||
} else if (s->bal == -bal) {
|
|
||||||
s->bal=0;
|
|
||||||
return (q);
|
|
||||||
} else if (s->bal == bal) {
|
|
||||||
|
|
||||||
if (r->bal == bal) {
|
|
||||||
/* single rotation */
|
|
||||||
p=r;
|
|
||||||
if (bal>0) {
|
|
||||||
s->rlink=r->llink;
|
|
||||||
r->llink=s;
|
|
||||||
} else {
|
|
||||||
s->llink=r->rlink;
|
|
||||||
r->rlink=s;
|
|
||||||
}
|
|
||||||
s->bal=r->bal=0;
|
|
||||||
} else if (r->bal == -bal) {
|
|
||||||
/* double rotation */
|
|
||||||
if (bal>0) {
|
|
||||||
p=r->llink;
|
|
||||||
r->llink=p->rlink;
|
|
||||||
p->rlink=r;
|
|
||||||
s->rlink=p->llink;
|
|
||||||
p->llink=s;
|
|
||||||
} else {
|
|
||||||
p=r->rlink;
|
|
||||||
r->rlink=p->llink;
|
|
||||||
p->llink=r;
|
|
||||||
s->llink=p->rlink;
|
|
||||||
p->rlink=s;
|
|
||||||
}
|
|
||||||
if (p->bal == bal) {
|
|
||||||
s->bal=-bal;
|
|
||||||
r->bal=0;
|
|
||||||
} else if (p->bal==0) {
|
|
||||||
s->bal=r->bal=0;
|
|
||||||
} else {
|
|
||||||
r->bal=bal;
|
|
||||||
s->bal=0;
|
|
||||||
}
|
|
||||||
p->bal=0;
|
|
||||||
}
|
|
||||||
if (t==NULL) {
|
|
||||||
root=p;
|
|
||||||
} else {
|
|
||||||
if (t->rlink==s) {
|
|
||||||
t->rlink=p;
|
|
||||||
} else {
|
|
||||||
t->llink=p;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Tree->root=root;
|
|
||||||
return(q);
|
|
||||||
}
|
|
||||||
return(q);
|
|
||||||
}
|
|
||||||
|
|
@ -1,71 +0,0 @@
|
|||||||
/*
|
|
||||||
* Parallel Sparse BLAS version 2.2
|
|
||||||
* (C) Copyright 2006/2007/2008
|
|
||||||
* Salvatore Filippone University of Rome Tor Vergata
|
|
||||||
* Alfredo Buttari University of Rome Tor Vergata
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions
|
|
||||||
* are met:
|
|
||||||
* 1. Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions, and the following disclaimer in the
|
|
||||||
* documentation and/or other materials provided with the distribution.
|
|
||||||
* 3. The name of the PSBLAS group or the names of its contributors may
|
|
||||||
* not be used to endorse or promote products derived from this
|
|
||||||
* software without specific written permission.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
|
||||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
|
||||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE PSBLAS GROUP OR ITS CONTRIBUTORS
|
|
||||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
||||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
||||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
||||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
||||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
||||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
||||||
* POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
/* Type definitions for balanced AVL tree search and insertion */
|
|
||||||
/* See avltree.c for a full definition of the subroutines */
|
|
||||||
/* */
|
|
||||||
|
|
||||||
typedef struct avlnode *AVLNodePtr;
|
|
||||||
typedef struct avlnode {
|
|
||||||
AVLNodePtr llink,rlink;
|
|
||||||
int bal;
|
|
||||||
void *key;
|
|
||||||
} AVLNode;
|
|
||||||
|
|
||||||
typedef struct avltvect *AVLTVectPtr;
|
|
||||||
|
|
||||||
typedef struct avltree *AVLTreePtr;
|
|
||||||
typedef struct avltree {
|
|
||||||
AVLTVectPtr first, current;
|
|
||||||
AVLNodePtr root;
|
|
||||||
int nnodes;
|
|
||||||
#ifdef PROFILE
|
|
||||||
int nsteps;
|
|
||||||
#endif
|
|
||||||
} AVLTree;
|
|
||||||
|
|
||||||
|
|
||||||
AVLNodePtr AVLTreeSearch(AVLTreePtr, void *, int (*)(void *, void *));
|
|
||||||
AVLNodePtr GetAVLNode(AVLTreePtr);
|
|
||||||
int AVLTreeInit(AVLTreePtr);
|
|
||||||
int AVLTreeReInit(AVLTreePtr);
|
|
||||||
AVLTreePtr GetAVLTree();
|
|
||||||
int AVLTreeInsert(AVLTreePtr, void *, int (*)(void *, void *),
|
|
||||||
void (*)(void *, void *, void *), void *);
|
|
||||||
AVLNodePtr AVLTreeUserInsert(AVLTreePtr, void *, int (*)(void *, void *));
|
|
||||||
void AVLTreeInorderTraverse(AVLTreePtr, void (*)(void *, void *), void *);
|
|
||||||
void AVLTreePreorderTraverse(AVLTreePtr, void (*)(void *, void *), void *);
|
|
||||||
void AVLTreeFree(AVLTreePtr, void (*)(void *));
|
|
||||||
int HowManyItems(AVLTreePtr);
|
|
||||||
int AVLTreeInorderTraverseWithDelims(AVLTreePtr,void*, void*, int (*)(void*,void*),
|
|
||||||
void (*)(void *, void *), void *);
|
|
||||||
|
|
||||||
|
|
@ -1,446 +0,0 @@
|
|||||||
/*
|
|
||||||
* Parallel Sparse BLAS version 2.2
|
|
||||||
* (C) Copyright 2006/2007/2008
|
|
||||||
* Salvatore Filippone University of Rome Tor Vergata
|
|
||||||
* Alfredo Buttari University of Rome Tor Vergata
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions
|
|
||||||
* are met:
|
|
||||||
* 1. Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions, and the following disclaimer in the
|
|
||||||
* documentation and/or other materials provided with the distribution.
|
|
||||||
* 3. The name of the PSBLAS group or the names of its contributors may
|
|
||||||
* not be used to endorse or promote products derived from this
|
|
||||||
* software without specific written permission.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
|
||||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
|
||||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE PSBLAS GROUP OR ITS CONTRIBUTORS
|
|
||||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
||||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
||||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
||||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
||||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
||||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
||||||
* POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
/*****************************************************************/
|
|
||||||
/* */
|
|
||||||
/* srcht.c : specialized insert/search for (key,val) integer */
|
|
||||||
/* pairs. Written by: Salvatore Filippone */
|
|
||||||
/* */
|
|
||||||
/* Last updated: Mar 09 2004 */
|
|
||||||
/* */
|
|
||||||
/* Uses: avltree */
|
|
||||||
/* */
|
|
||||||
/* Data types: */
|
|
||||||
/* */
|
|
||||||
/* KeyType: struct with two integer fields, key and val. */
|
|
||||||
/* */
|
|
||||||
/* */
|
|
||||||
/* User callable functions: */
|
|
||||||
/* */
|
|
||||||
/* void InitPairSearchTree(int *iret) */
|
|
||||||
/* Purpose: initialize a search structure; */
|
|
||||||
/* Function value: 0: OK */
|
|
||||||
/* -1: failure */
|
|
||||||
/* */
|
|
||||||
/* */
|
|
||||||
/* void SearchInsKeyVal(int *key, int *val, int *res, */
|
|
||||||
/* int *iret) */
|
|
||||||
/* Purpose: Search for a key, insert it if not present. */
|
|
||||||
/* */
|
|
||||||
/* Input: 1. key */
|
|
||||||
/* Key to be searched for. */
|
|
||||||
/* 2. val */
|
|
||||||
/* Value to form a (key,val) pair to be */
|
|
||||||
/* inserted if key not already present. */
|
|
||||||
/* Output: 3. res */
|
|
||||||
/* The val part of the pair with key; if the */
|
|
||||||
/* key was freshly inserted then res=val */
|
|
||||||
/* Function value: 0 Normal termination */
|
|
||||||
/* 1 Key was already present. */
|
|
||||||
/* -1 Invalid input pointer */
|
|
||||||
/* -3 Memory allocation failure */
|
|
||||||
/* */
|
|
||||||
/* */
|
|
||||||
/* void FreePairSearchTree() */
|
|
||||||
/* Purpose: free up tree data storage */
|
|
||||||
/* */
|
|
||||||
/* */
|
|
||||||
/*****************************************************************/
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include "avltree.h"
|
|
||||||
|
|
||||||
#define POOLSIZE 4096
|
|
||||||
#define CACHESIZE 16
|
|
||||||
#ifdef LowerUnderscore
|
|
||||||
#define InitPairSearchTree initpairsearchtree_
|
|
||||||
#define FreePairSearchTree freepairsearchtree_
|
|
||||||
#define ClonePairSearchTree clonepairsearchtree_
|
|
||||||
#define SizeofPairSearchTree sizeofpairsearchtree_
|
|
||||||
#define SearchInsKeyVal searchinskeyval_
|
|
||||||
#define SearchKeyVal searchkeyval_
|
|
||||||
#define NPairs npairs_
|
|
||||||
#endif
|
|
||||||
#ifdef LowerDoubleUnderscore
|
|
||||||
#define InitPairSearchTree initpairsearchtree_
|
|
||||||
#define FreePairSearchTree freepairsearchtree_
|
|
||||||
#define ClonePairSearchTree clonepairsearchtree_
|
|
||||||
#define SizeofPairSearchTree sizeofpairsearchtree_
|
|
||||||
#define SearchInsKeyVal searchinskeyval_
|
|
||||||
#define SearchKeyVal searchkeyval_
|
|
||||||
#define NPairs npairs_
|
|
||||||
#endif
|
|
||||||
#ifdef LowerCase
|
|
||||||
#define InitPairSearchTree initpairsearchtree
|
|
||||||
#define FreePairSearchTree freepairsearchtree
|
|
||||||
#define ClonePairSearchTree clonepairsearchtree
|
|
||||||
#define SizeofPairSearchTree sizeofpairsearchtree
|
|
||||||
#define SearchInsKeyVal searchinskeyval
|
|
||||||
#define SearchKeyVal searchkeyval
|
|
||||||
#define NPairs npairs
|
|
||||||
#endif
|
|
||||||
#ifdef UpperUnderscore
|
|
||||||
#define InitPairSearchTree INITPAIRSEARCHTREE_
|
|
||||||
#define FreePairSearchTree FREEPAIRSEARCHTREE_
|
|
||||||
#define ClonePairSearchTree CLONEPAIRSEARCHTREE_
|
|
||||||
#define SizeofPairSearchTree SIZEOFPAIRSEARCHTREE_
|
|
||||||
#define SearchInsKeyVal SEARCHINSKEYVAL_
|
|
||||||
#define SearchKeyVal SEARCHKEYVAL_
|
|
||||||
#define NPairs NPAIRS_
|
|
||||||
#endif
|
|
||||||
#ifdef UpperDoubleUnderscore
|
|
||||||
#define InitPairSearchTree INITPAIRSEARCHTREE_
|
|
||||||
#define FreePairSearchTree FREEPAIRSEARCHTREE_
|
|
||||||
#define ClonePairSearchTree CLONEPAIRSEARCHTREE_
|
|
||||||
#define SizeofPairSearchTree SIZEOFPAIRSEARCHTREE_
|
|
||||||
#define SearchInsKeyVal SEARCHINSKEYVAL_
|
|
||||||
#define SearchKeyVal SEARCHKEYVAL_
|
|
||||||
#define NPairs NPAIRS_
|
|
||||||
#endif
|
|
||||||
#ifdef UpperCase
|
|
||||||
#define InitPairSearchTree INITPAIRSEARCHTREE
|
|
||||||
#define FreePairSearchTree FREEPAIRSEARCHTREE
|
|
||||||
#define ClonePairSearchTree CLONEPAIRSEARCHTREE
|
|
||||||
#define SizeofPairSearchTree SIZEOFPAIRSEARCHTREE
|
|
||||||
#define SearchInsKeyVal SEARCHINSKEYVAL
|
|
||||||
#define SearchKeyVal SEARCHKEYVAL
|
|
||||||
#define NPairs NPAIRS
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct keypair *KeyPairPtr;
|
|
||||||
typedef struct keypair {
|
|
||||||
int key,val;
|
|
||||||
} KeyPair;
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct pairvect *PairVectPtr;
|
|
||||||
typedef struct pairvect {
|
|
||||||
KeyPair pool[POOLSIZE];
|
|
||||||
int avail;
|
|
||||||
PairVectPtr previous, next;
|
|
||||||
} PairVect;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct pairtree *PairTreePtr;
|
|
||||||
typedef struct pairtree {
|
|
||||||
int retval;
|
|
||||||
int cache[2][CACHESIZE], cpnt;
|
|
||||||
PairVectPtr PairPoolRoot,PairPoolCrt;
|
|
||||||
AVLTreePtr tree;
|
|
||||||
} PairTree;
|
|
||||||
|
|
||||||
#ifdef Ptr64Bits
|
|
||||||
typedef long long fptr;
|
|
||||||
#else
|
|
||||||
typedef int fptr; /* 32-bit by default */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* fptr *f_factors, */
|
|
||||||
/* *f_factors = (fptr) LUfactors; */
|
|
||||||
|
|
||||||
/* static int retval; */
|
|
||||||
/* static PairVectPtr PairPoolRoot=NULL,PairPoolCrt=NULL; */
|
|
||||||
/* static AVLTreePtr tree=NULL; */
|
|
||||||
|
|
||||||
int CompareKeys(void *key1, void *key2)
|
|
||||||
{
|
|
||||||
if (((KeyPairPtr) key1)->key < ((KeyPairPtr) key2)->key){
|
|
||||||
return(-1);
|
|
||||||
} else if (((KeyPairPtr)key1)->key == ((KeyPairPtr)key2)->key){
|
|
||||||
return(0);
|
|
||||||
} else {
|
|
||||||
return(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void InitPairSearchTree(fptr *ftree, int *iret)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
PairTreePtr PTree;
|
|
||||||
|
|
||||||
*iret = 0;
|
|
||||||
|
|
||||||
if ((PTree = malloc(sizeof(PairTree)))==NULL) {
|
|
||||||
*iret=-1; return;
|
|
||||||
}
|
|
||||||
PTree->retval=0;
|
|
||||||
for (i=0; i<CACHESIZE; i++) {
|
|
||||||
PTree->cache[0][i]=PTree->cache[1][i] = -1;
|
|
||||||
}
|
|
||||||
PTree->cpnt=0;
|
|
||||||
if ((PTree->tree = GetAVLTree())==NULL) {
|
|
||||||
*iret=-1; return;
|
|
||||||
}
|
|
||||||
if ((PTree->PairPoolRoot=(PairVectPtr)malloc(sizeof(PairVect)))==NULL) {
|
|
||||||
*iret=-3; return;
|
|
||||||
} else {
|
|
||||||
PTree->PairPoolRoot->avail=0;
|
|
||||||
PTree->PairPoolRoot->previous=PTree->PairPoolRoot->next=NULL;
|
|
||||||
PTree->PairPoolCrt=PTree->PairPoolRoot;
|
|
||||||
}
|
|
||||||
*ftree = (fptr) PTree;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int NPairs(fptr *ftree)
|
|
||||||
{
|
|
||||||
PairTreePtr PTree;
|
|
||||||
|
|
||||||
PTree = (PairTreePtr) *ftree;
|
|
||||||
|
|
||||||
return(HowManyItems(PTree->tree));
|
|
||||||
}
|
|
||||||
|
|
||||||
void KeyUpdate( void *key1, void *key2, void *data)
|
|
||||||
{
|
|
||||||
*((int *) data)=((KeyPairPtr) key2)->val;
|
|
||||||
}
|
|
||||||
|
|
||||||
int SizeofPairSearchTree(fptr *ftree)
|
|
||||||
{
|
|
||||||
PairTreePtr PTree;
|
|
||||||
PairVectPtr current,next;
|
|
||||||
int sz;
|
|
||||||
PTree = (PairTreePtr) *ftree;
|
|
||||||
|
|
||||||
sz = 0;
|
|
||||||
if (PTree==NULL) return(sz);
|
|
||||||
current=PTree->PairPoolRoot;
|
|
||||||
|
|
||||||
while (current != NULL) {
|
|
||||||
sz += sizeof(PairVect);
|
|
||||||
next=current->next;
|
|
||||||
current=next;
|
|
||||||
}
|
|
||||||
return(sz);
|
|
||||||
}
|
|
||||||
|
|
||||||
void FreePairSearchTree(fptr *ftree)
|
|
||||||
{
|
|
||||||
PairTreePtr PTree;
|
|
||||||
PairVectPtr current,next;
|
|
||||||
|
|
||||||
PTree = (PairTreePtr) *ftree;
|
|
||||||
|
|
||||||
AVLTreeFree(PTree->tree,NULL);
|
|
||||||
|
|
||||||
current=PTree->PairPoolRoot;
|
|
||||||
|
|
||||||
while (current != NULL) {
|
|
||||||
next=current->next;
|
|
||||||
free(current);
|
|
||||||
current=next;
|
|
||||||
}
|
|
||||||
free(PTree->tree);
|
|
||||||
free(PTree);
|
|
||||||
*ftree = (fptr) NULL;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
int AdvanceKeyPair(PairVectPtr current)
|
|
||||||
{
|
|
||||||
if (current!=NULL) {
|
|
||||||
current->avail +=1;
|
|
||||||
return(current->avail);
|
|
||||||
}
|
|
||||||
return(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
KeyPairPtr GetKeyPair(PairVectPtr *current)
|
|
||||||
{
|
|
||||||
PairVectPtr new, crt;
|
|
||||||
KeyPairPtr newnode;
|
|
||||||
|
|
||||||
crt=*current;
|
|
||||||
if (crt==NULL) {
|
|
||||||
return(NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (crt->avail<POOLSIZE) {
|
|
||||||
newnode=&(crt->pool[crt->avail]);
|
|
||||||
} else {
|
|
||||||
if ((new=(PairVectPtr)malloc(sizeof(PairVect)))==NULL) {
|
|
||||||
fprintf(stderr,"Memory allocation failure\n");
|
|
||||||
return(NULL);
|
|
||||||
}
|
|
||||||
memset(new,'\0',sizeof(PairVect));
|
|
||||||
newnode=&(new->pool[0]);
|
|
||||||
crt->next=new;
|
|
||||||
new->previous=crt;
|
|
||||||
new->next=NULL;
|
|
||||||
*current=new;
|
|
||||||
}
|
|
||||||
return(newnode);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* */
|
|
||||||
/* void SearchInsKeyVal(int *key, int *val, int *res, */
|
|
||||||
/* int *iret) */
|
|
||||||
/* Purpose: Search for a key, insert it if not present. */
|
|
||||||
/* */
|
|
||||||
/* Input: 1. key */
|
|
||||||
/* Key to be searched for. */
|
|
||||||
/* 2. val */
|
|
||||||
/* Value to form a (key,val) pair to be */
|
|
||||||
/* inserted if key not already present. */
|
|
||||||
/* Output: 3. res */
|
|
||||||
/* The val part of the pair with key; if the */
|
|
||||||
/* key was freshly inserted then res=val */
|
|
||||||
/* Function value: 0 Normal termination */
|
|
||||||
/* -1 Invalid input pointer */
|
|
||||||
/* -3 Memory allocation failure */
|
|
||||||
/* */
|
|
||||||
|
|
||||||
void SearchInsKeyVal(fptr *ftree, int *key, int *val, int *res, int *iret)
|
|
||||||
{
|
|
||||||
PairTreePtr PTree;
|
|
||||||
KeyPairPtr node;
|
|
||||||
int info,i;
|
|
||||||
|
|
||||||
PTree = (PairTreePtr) *ftree;
|
|
||||||
node = GetKeyPair(&(PTree->PairPoolCrt));
|
|
||||||
node->key = *key;
|
|
||||||
node->val = *val;
|
|
||||||
if ((i=PTree->cpnt)<CACHESIZE) {
|
|
||||||
PTree->cache[0][i] = *key;
|
|
||||||
PTree->cache[1][i] = *val;
|
|
||||||
PTree->cpnt=i+1;
|
|
||||||
}
|
|
||||||
|
|
||||||
info = AVLTreeInsert(PTree->tree,node,CompareKeys,KeyUpdate,&(PTree->retval));
|
|
||||||
*iret = info;
|
|
||||||
|
|
||||||
if (info==0) {
|
|
||||||
*res = node->val;
|
|
||||||
AdvanceKeyPair(PTree->PairPoolCrt);
|
|
||||||
} else if (info == 1) {
|
|
||||||
*res = PTree->retval;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#define USECACHE 0
|
|
||||||
void SearchKeyVal(fptr *ftree, int *key, int *res, int *iret)
|
|
||||||
{
|
|
||||||
PairTreePtr PTree;
|
|
||||||
KeyPair node;
|
|
||||||
AVLNodePtr noderes;
|
|
||||||
KeyPairPtr result;
|
|
||||||
#if USECACHE
|
|
||||||
int i,sv[2];
|
|
||||||
int info;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
*iret = 0;
|
|
||||||
|
|
||||||
PTree = (PairTreePtr) *ftree;
|
|
||||||
#if USECACHE
|
|
||||||
for (i=0; i<CACHESIZE; i++) {
|
|
||||||
if (PTree->cache[0][i] == *key) {
|
|
||||||
*res=PTree->cache[1][i];
|
|
||||||
sv[0]=PTree->cache[0][i];
|
|
||||||
sv[1]=PTree->cache[1][i];
|
|
||||||
PTree->cache[0][i]=PTree->cache[0][0];
|
|
||||||
PTree->cache[1][i]=PTree->cache[1][0];
|
|
||||||
PTree->cache[0][0]=sv[0];
|
|
||||||
PTree->cache[1][0]=sv[1];
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
node.key=*key;
|
|
||||||
if ((noderes = AVLTreeSearch(PTree->tree,&node,CompareKeys))==NULL) {
|
|
||||||
*res = -1;
|
|
||||||
*iret = 0;
|
|
||||||
} else {
|
|
||||||
result = (KeyPairPtr) noderes->key;
|
|
||||||
*res = result->val;
|
|
||||||
#if USECACHE
|
|
||||||
for (i=CACHESIZE-1; i>0; i--) {
|
|
||||||
PTree->cache[0][i]=PTree->cache[0][i-1];
|
|
||||||
PTree->cache[0][i]=PTree->cache[1][i-1];
|
|
||||||
}
|
|
||||||
PTree->cache[0][0]=*key;
|
|
||||||
PTree->cache[1][0]=result->val;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
#ifdef PROFILE
|
|
||||||
*iret = 1;
|
|
||||||
*iret = PTree->tree->nsteps;
|
|
||||||
#endif
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
void PairTreeVisit(AVLNodePtr current, PairTreePtr PTree)
|
|
||||||
{
|
|
||||||
KeyPairPtr node,inode;
|
|
||||||
int info;
|
|
||||||
|
|
||||||
if (current==NULL) return;
|
|
||||||
inode = (KeyPairPtr) current->key;
|
|
||||||
node = GetKeyPair(&(PTree->PairPoolCrt));
|
|
||||||
node->key = inode->key;
|
|
||||||
node->val = inode->val;
|
|
||||||
info = AVLTreeInsert(PTree->tree,node,CompareKeys,KeyUpdate,&(PTree->retval));
|
|
||||||
if (info==0) {
|
|
||||||
AdvanceKeyPair(PTree->PairPoolCrt);
|
|
||||||
}
|
|
||||||
PairTreeVisit(current->llink,PTree);
|
|
||||||
PairTreeVisit(current->rlink,PTree);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ClonePairSearchTree(fptr *ftreein, fptr *ftreeout)
|
|
||||||
{
|
|
||||||
PairTreePtr PTreein, PTreeout;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
PTreein = (PairTreePtr) *ftreein;
|
|
||||||
|
|
||||||
if (PTreein == NULL) {
|
|
||||||
*ftreeout = (fptr) NULL;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
InitPairSearchTree(ftreeout,&i);
|
|
||||||
PTreeout = (PairTreePtr) *ftreeout;
|
|
||||||
PairTreeVisit(PTreein->tree->root,PTreeout);
|
|
||||||
}
|
|
@ -0,0 +1,618 @@
|
|||||||
|
!!$
|
||||||
|
!!$ Parallel Sparse BLAS v2.0
|
||||||
|
!!$ (C) Copyright 2006 Salvatore Filippone University of Rome Tor Vergata
|
||||||
|
!!$ Alfredo Buttari University of Rome Tor Vergata
|
||||||
|
!!$
|
||||||
|
!!$ Redistribution and use in source and binary forms, with or without
|
||||||
|
!!$ modification, are permitted provided that the following conditions
|
||||||
|
!!$ are met:
|
||||||
|
!!$ 1. Redistributions of source code must retain the above copyright
|
||||||
|
!!$ notice, this list of conditions and the following disclaimer.
|
||||||
|
!!$ 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
!!$ notice, this list of conditions, and the following disclaimer in the
|
||||||
|
!!$ documentation and/or other materials provided with the distribution.
|
||||||
|
!!$ 3. The name of the PSBLAS group or the names of its contributors may
|
||||||
|
!!$ not be used to endorse or promote products derived from this
|
||||||
|
!!$ software without specific written permission.
|
||||||
|
!!$
|
||||||
|
!!$ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
!!$ ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||||
|
!!$ TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
!!$ PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE PSBLAS GROUP OR ITS CONTRIBUTORS
|
||||||
|
!!$ BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
!!$ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
!!$ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
!!$ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
!!$ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
!!$ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
!!$ POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
!!$
|
||||||
|
!!$
|
||||||
|
|
||||||
|
module psb_item_mod
|
||||||
|
type psb_item_int2
|
||||||
|
integer :: key, val
|
||||||
|
end type psb_item_int2
|
||||||
|
interface psb_sizeof
|
||||||
|
module procedure psb_item_int2_size
|
||||||
|
end interface
|
||||||
|
contains
|
||||||
|
function psb_item_int2_size(node)
|
||||||
|
use psb_const_mod
|
||||||
|
type(psb_item_int2) :: node
|
||||||
|
psb_item_int2_size = psb_sizeof_int * 2
|
||||||
|
end function psb_item_int2_size
|
||||||
|
|
||||||
|
subroutine psb_print_item_key_val(iout,item)
|
||||||
|
integer, intent(in) :: iout
|
||||||
|
type(psb_item_int2), intent(in) :: item
|
||||||
|
write(iout,*) 'Value: ',item%key,item%val
|
||||||
|
call flush(iout)
|
||||||
|
end subroutine psb_print_item_key_val
|
||||||
|
end module psb_item_mod
|
||||||
|
|
||||||
|
module psb_avl_mod
|
||||||
|
|
||||||
|
use psb_item_mod
|
||||||
|
|
||||||
|
integer, parameter :: LeftHigh = -1, EqualHeight=0, RightHigh=1
|
||||||
|
integer, parameter :: AVLTreeDuplicate = -123, AVLTreeOK=0, &
|
||||||
|
& AVLTreeOutOfMemory=-512, AVLTreeFatalError=-1024
|
||||||
|
integer :: level,outlev
|
||||||
|
integer, parameter :: poolsize = 1024
|
||||||
|
|
||||||
|
type psb_treenode_int2
|
||||||
|
type(psb_item_int2) :: item
|
||||||
|
type(psb_treenode_int2), pointer :: left=>null(), right=>null()
|
||||||
|
integer :: balance
|
||||||
|
end type psb_treenode_int2
|
||||||
|
|
||||||
|
type psb_treevect_int2
|
||||||
|
type(psb_treenode_int2) :: pool(poolsize)
|
||||||
|
integer :: avail
|
||||||
|
type(psb_treevect_int2), pointer :: next=>null(), prev=>null()
|
||||||
|
end type psb_treevect_int2
|
||||||
|
|
||||||
|
type psb_tree_int2
|
||||||
|
type(psb_treevect_int2), pointer :: head=>null(), current=>null()
|
||||||
|
type(psb_treenode_int2), pointer :: root=>null()
|
||||||
|
integer :: nnodes
|
||||||
|
end type psb_tree_int2
|
||||||
|
|
||||||
|
interface psb_sizeof
|
||||||
|
module procedure psb_Sizeof_Tree_int2, psb_sizeof_node_int2
|
||||||
|
end interface
|
||||||
|
|
||||||
|
interface InitSearchTree
|
||||||
|
module procedure InitSearchTree_int2
|
||||||
|
end interface
|
||||||
|
|
||||||
|
interface FreeSearchTree
|
||||||
|
module procedure FreeSearchTree_int2
|
||||||
|
end interface
|
||||||
|
|
||||||
|
interface SearchKey
|
||||||
|
module procedure SearchKey_int2
|
||||||
|
end interface
|
||||||
|
|
||||||
|
interface SearchInsKey
|
||||||
|
module procedure SearchInsKey_int2
|
||||||
|
end interface
|
||||||
|
|
||||||
|
interface GetAVLTree
|
||||||
|
module procedure GetAVLTree_int2
|
||||||
|
end interface
|
||||||
|
|
||||||
|
interface CloneSearchTree
|
||||||
|
module procedure CloneSearchTree_int2
|
||||||
|
end interface
|
||||||
|
|
||||||
|
interface CloneAVLTree
|
||||||
|
module procedure CloneAVLTree_int2
|
||||||
|
end interface
|
||||||
|
|
||||||
|
interface GetAVLNode
|
||||||
|
module procedure GetAVLNode_int2
|
||||||
|
end interface
|
||||||
|
interface UnGetAVLNode
|
||||||
|
module procedure UnGetAVLNode_int2
|
||||||
|
end interface
|
||||||
|
|
||||||
|
interface VisitAVLTree
|
||||||
|
module procedure VisitAVLTree_int2, VisitAVLTreeNode_int2
|
||||||
|
end interface
|
||||||
|
|
||||||
|
interface VisitAVLTreeLev
|
||||||
|
module procedure VisitAVLTreeLev_int2, VisitAVLTreeNodeLev_int2
|
||||||
|
end interface
|
||||||
|
|
||||||
|
interface AVLTreeLeftBalance
|
||||||
|
module procedure AVLTreeLeftBalance_int2
|
||||||
|
end interface
|
||||||
|
|
||||||
|
interface AVLTreeRightBalance
|
||||||
|
module procedure AVLTreeRightBalance_int2
|
||||||
|
end interface
|
||||||
|
|
||||||
|
interface AVLTreeRotateLeft
|
||||||
|
module procedure AVLTreeRotateLeft_int2
|
||||||
|
end interface
|
||||||
|
|
||||||
|
interface AVLTreeRotateRight
|
||||||
|
module procedure AVLTreeRotateRight_int2
|
||||||
|
end interface
|
||||||
|
|
||||||
|
interface AVLSearchKey
|
||||||
|
module procedure AVLSearchKey_int2
|
||||||
|
end interface
|
||||||
|
|
||||||
|
interface AVLSearchInsKey
|
||||||
|
module procedure AVLSearchInsKey_int2
|
||||||
|
end interface
|
||||||
|
|
||||||
|
interface AVLSearchInsNode
|
||||||
|
module procedure AVLSearchInsNode_int2
|
||||||
|
end interface
|
||||||
|
|
||||||
|
contains
|
||||||
|
|
||||||
|
subroutine InitSearchTree_int2(tree, info)
|
||||||
|
type(psb_tree_int2), pointer :: tree
|
||||||
|
integer :: info
|
||||||
|
|
||||||
|
if (associated(tree)) then
|
||||||
|
call FreeSearchTree(tree,info)
|
||||||
|
end if
|
||||||
|
call GetAVLTree(tree,info)
|
||||||
|
|
||||||
|
end subroutine InitSearchTree_int2
|
||||||
|
|
||||||
|
subroutine CloneSearchTree_int2(treein, treeout)
|
||||||
|
type(psb_tree_int2), pointer :: treein,treeout
|
||||||
|
integer :: info
|
||||||
|
if (.not.associated(treein)) then
|
||||||
|
treeout => null()
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
call GetAVLTree(treeout,info)
|
||||||
|
call CloneAVLTree(treein%root,treeout)
|
||||||
|
|
||||||
|
end subroutine CloneSearchTree_int2
|
||||||
|
|
||||||
|
subroutine CloneAVLTree_int2(root, tree)
|
||||||
|
type(psb_treenode_int2), pointer :: root
|
||||||
|
type(psb_tree_int2), pointer :: tree
|
||||||
|
integer :: info, key,val,next
|
||||||
|
if (.not.associated(root)) return
|
||||||
|
key = root%item%key
|
||||||
|
next = root%item%val
|
||||||
|
call SearchInsKey(tree,key,val,next,info)
|
||||||
|
call CloneAVLTree(root%left,tree)
|
||||||
|
call CloneAVLTree(root%right,tree)
|
||||||
|
end subroutine CloneAVLTree_int2
|
||||||
|
|
||||||
|
subroutine FreeSearchTree_int2(tree, info)
|
||||||
|
type(psb_tree_int2), pointer :: tree
|
||||||
|
integer :: info
|
||||||
|
type(psb_treevect_int2), pointer :: current,next
|
||||||
|
|
||||||
|
if (.not.associated(tree)) return
|
||||||
|
current => tree%head
|
||||||
|
do
|
||||||
|
if (.not.associated(current)) exit
|
||||||
|
next => current%next
|
||||||
|
deallocate(current,stat=info)
|
||||||
|
if (info /= 0) then
|
||||||
|
info = AVLTreeFatalError
|
||||||
|
return
|
||||||
|
end if
|
||||||
|
current => next
|
||||||
|
end do
|
||||||
|
deallocate(tree,stat=info)
|
||||||
|
if (info /= 0) then
|
||||||
|
info = AVLTreeFatalError
|
||||||
|
return
|
||||||
|
end if
|
||||||
|
|
||||||
|
end subroutine FreeSearchTree_int2
|
||||||
|
|
||||||
|
function psb_Sizeof_Tree_int2(tree)
|
||||||
|
use psb_const_mod
|
||||||
|
type(psb_tree_int2), pointer :: tree
|
||||||
|
integer :: psb_Sizeof_Tree_int2
|
||||||
|
integer :: val
|
||||||
|
type(psb_treevect_int2), pointer :: current,next
|
||||||
|
|
||||||
|
val = 0
|
||||||
|
if (associated(tree)) then
|
||||||
|
current => tree%head
|
||||||
|
do
|
||||||
|
if (.not.associated(current)) exit
|
||||||
|
val = val + 3*psb_sizeof_int + poolsize*psb_sizeof(current%pool(1))
|
||||||
|
current => current%next
|
||||||
|
end do
|
||||||
|
end if
|
||||||
|
psb_Sizeof_Tree_int2 = val
|
||||||
|
end function psb_Sizeof_Tree_int2
|
||||||
|
|
||||||
|
function psb_sizeof_node_int2(node)
|
||||||
|
|
||||||
|
use psb_const_mod
|
||||||
|
type(psb_treenode_int2) :: node
|
||||||
|
integer :: psb_sizeof_node_int2
|
||||||
|
integer :: val
|
||||||
|
|
||||||
|
|
||||||
|
psb_sizeof_node_int2 = 3*psb_sizeof_int + psb_sizeof(node%item)
|
||||||
|
|
||||||
|
end function psb_sizeof_node_int2
|
||||||
|
|
||||||
|
subroutine SearchKey_int2(tree,key,val,info)
|
||||||
|
type(psb_tree_int2), target :: tree
|
||||||
|
integer :: key,val,info
|
||||||
|
type(psb_item_int2), pointer :: retval
|
||||||
|
info = 0
|
||||||
|
call AVLSearchKey(tree,key,retval,info)
|
||||||
|
if (associated(retval)) then
|
||||||
|
val = retval%val
|
||||||
|
else
|
||||||
|
val = -1
|
||||||
|
end if
|
||||||
|
end subroutine SearchKey_int2
|
||||||
|
|
||||||
|
subroutine SearchInsKey_int2(tree,key,val, nextval,info)
|
||||||
|
type(psb_tree_int2), target :: tree
|
||||||
|
integer :: key,val,nextval,info
|
||||||
|
|
||||||
|
call AVLSearchInsKey(tree,key,val,nextval,info)
|
||||||
|
|
||||||
|
end subroutine SearchInsKey_int2
|
||||||
|
|
||||||
|
subroutine GetAVLTree_int2(tree, info)
|
||||||
|
type(psb_tree_int2), pointer :: tree
|
||||||
|
integer :: info
|
||||||
|
|
||||||
|
allocate(tree, stat=info)
|
||||||
|
if (info == 0) allocate(tree%head,stat=info)
|
||||||
|
if (info == 0) then
|
||||||
|
tree%current => tree%head
|
||||||
|
tree%head%avail = 0
|
||||||
|
tree%nnodes=0
|
||||||
|
end if
|
||||||
|
|
||||||
|
if (info /= 0) then
|
||||||
|
write(0,*) 'Failed allocation 1 GetAVLTree '
|
||||||
|
info = AVLTreeOutOfMemory
|
||||||
|
|
||||||
|
return
|
||||||
|
end if
|
||||||
|
|
||||||
|
end subroutine GetAVLTree_int2
|
||||||
|
|
||||||
|
subroutine VisitAVLTree_int2(tree, info,iout)
|
||||||
|
type(psb_tree_int2), pointer :: tree
|
||||||
|
integer :: info
|
||||||
|
integer, optional :: iout
|
||||||
|
|
||||||
|
info = 0
|
||||||
|
if (.not.associated(tree)) return
|
||||||
|
call VisitAVLTree(tree%root,iout)
|
||||||
|
|
||||||
|
end subroutine VisitAVLTree_int2
|
||||||
|
|
||||||
|
recursive subroutine VisitAVLTreeNode_int2(root,iout)
|
||||||
|
type(psb_treenode_int2), pointer :: root
|
||||||
|
integer, optional :: iout
|
||||||
|
integer :: info
|
||||||
|
|
||||||
|
if (.not.associated(root)) return
|
||||||
|
call VisitAVLTree(root%left,iout)
|
||||||
|
if (present(iout)) then
|
||||||
|
call psb_print_item_key_val(iout,root%item)
|
||||||
|
else
|
||||||
|
call psb_print_item_key_val(6,root%item)
|
||||||
|
end if
|
||||||
|
call VisitAVLTree(root%right,iout)
|
||||||
|
end subroutine VisitAVLTreeNode_int2
|
||||||
|
|
||||||
|
subroutine VisitAVLTreeLev_int2(tree, info)
|
||||||
|
type(psb_tree_int2), pointer :: tree
|
||||||
|
integer :: info
|
||||||
|
|
||||||
|
if (.not.associated(tree)) return
|
||||||
|
do outlev = 0, 3
|
||||||
|
write(6,*) 'Tree level : ',outlev
|
||||||
|
call VisitAVLTreeLev(tree%root,0)
|
||||||
|
end do
|
||||||
|
|
||||||
|
end subroutine VisitAVLTreeLev_int2
|
||||||
|
|
||||||
|
recursive subroutine VisitAVLTreeNodeLev_int2(root,level)
|
||||||
|
type(psb_treenode_int2), pointer :: root
|
||||||
|
integer :: info,level
|
||||||
|
|
||||||
|
if (.not.associated(root)) return
|
||||||
|
call VisitAVLTreeLev(root%left,level+1)
|
||||||
|
if (level == outlev) call psb_print_item_key_val(6,root%item)
|
||||||
|
call VisitAVLTreeLev(root%right,level+1)
|
||||||
|
end subroutine VisitAVLTreeNodeLev_int2
|
||||||
|
|
||||||
|
|
||||||
|
function GetAVLNode_int2(tree, info)
|
||||||
|
type(psb_tree_int2), target :: tree
|
||||||
|
type(psb_treenode_int2), pointer :: GetAVLNode_int2
|
||||||
|
integer :: info
|
||||||
|
type(psb_treevect_int2), pointer :: current, temp
|
||||||
|
|
||||||
|
GetAVLNode_int2 => null()
|
||||||
|
|
||||||
|
if (.not.associated(tree%current)) then
|
||||||
|
allocate(tree%head,stat=info)
|
||||||
|
if (info /= 0) then
|
||||||
|
info = AVLTreeOutOfMemory
|
||||||
|
return
|
||||||
|
end if
|
||||||
|
tree%current => tree%head
|
||||||
|
tree%current%avail = 0
|
||||||
|
end if
|
||||||
|
current => tree%current
|
||||||
|
do
|
||||||
|
if (current%avail < poolsize) exit
|
||||||
|
if (.not.(associated(current%next))) then
|
||||||
|
allocate(temp,stat=info)
|
||||||
|
if (info /= 0) then
|
||||||
|
info = AVLTreeOutOfMemory
|
||||||
|
return
|
||||||
|
end if
|
||||||
|
temp%avail = 0
|
||||||
|
temp%prev => current
|
||||||
|
current%next => temp
|
||||||
|
end if
|
||||||
|
current => current%next
|
||||||
|
end do
|
||||||
|
tree%current => current
|
||||||
|
current%avail = current%avail + 1
|
||||||
|
GetAVLNode_int2 => current%pool(current%avail)
|
||||||
|
|
||||||
|
end function GetAVLNode_int2
|
||||||
|
|
||||||
|
subroutine UnGetAVLNode_int2(tree, info)
|
||||||
|
type(psb_tree_int2), target :: tree
|
||||||
|
integer :: info
|
||||||
|
|
||||||
|
|
||||||
|
if (.not.associated(tree%current)) then
|
||||||
|
return
|
||||||
|
end if
|
||||||
|
if (tree%current%avail > 0) &
|
||||||
|
& tree%current%avail = tree%current%avail - 1
|
||||||
|
return
|
||||||
|
end subroutine UnGetAVLNode_int2
|
||||||
|
|
||||||
|
subroutine AVLSearchKey_int2(tree,key,retval,info)
|
||||||
|
type(psb_tree_int2), target :: tree
|
||||||
|
integer :: key,info
|
||||||
|
type(psb_item_int2), pointer :: retval
|
||||||
|
type(psb_treenode_int2), pointer :: root
|
||||||
|
|
||||||
|
retval => null()
|
||||||
|
root => tree%root
|
||||||
|
do
|
||||||
|
if (.not.associated(root)) exit
|
||||||
|
if (key < root%item%key) then
|
||||||
|
root => root%left
|
||||||
|
else if (key == root%item%key) then
|
||||||
|
retval => root%item
|
||||||
|
exit
|
||||||
|
else if (key > root%item%key) then
|
||||||
|
root => root%right
|
||||||
|
end if
|
||||||
|
end do
|
||||||
|
|
||||||
|
end subroutine AVLSearchKey_int2
|
||||||
|
|
||||||
|
subroutine AVLSearchInsKey_int2(tree,key,val,nextval,info)
|
||||||
|
type(psb_tree_int2), target :: tree
|
||||||
|
integer :: key,val,nextval,info
|
||||||
|
type(psb_treenode_int2), pointer :: itemp
|
||||||
|
logical :: taller
|
||||||
|
|
||||||
|
itemp => GetAVLNode(tree,info)
|
||||||
|
if (info /=0) then
|
||||||
|
return
|
||||||
|
end if
|
||||||
|
if (.not.associated(itemp)) then
|
||||||
|
info = -5
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
itemp%item%key = key
|
||||||
|
itemp%item%val = nextval
|
||||||
|
itemp%left => null()
|
||||||
|
itemp%right => null()
|
||||||
|
|
||||||
|
call AVLSearchInsNode(tree%root,itemp,taller,info)
|
||||||
|
val = itemp%item%val
|
||||||
|
if (info == AVLTreeDuplicate) then
|
||||||
|
call UnGetAVLNode(tree,info)
|
||||||
|
!!$ write(0,*) 'From searchInsNode ',key,val,nextval
|
||||||
|
info = 0
|
||||||
|
return
|
||||||
|
else if (info == AVLTreeOK) then
|
||||||
|
tree%nnodes = tree%nnodes + 1
|
||||||
|
info = 0
|
||||||
|
return
|
||||||
|
else
|
||||||
|
write(0,*) 'Error from inner SearchInsNode '
|
||||||
|
endif
|
||||||
|
|
||||||
|
end subroutine AVLSearchInsKey_int2
|
||||||
|
|
||||||
|
|
||||||
|
recursive subroutine AVLSearchInsNode_int2(root,node,taller,info)
|
||||||
|
type(psb_treenode_int2), pointer :: root, node
|
||||||
|
integer :: info
|
||||||
|
logical :: taller
|
||||||
|
|
||||||
|
info = AVLTreeOK
|
||||||
|
taller = .false.
|
||||||
|
if (.not.associated(root)) then
|
||||||
|
root => node
|
||||||
|
node%balance = EqualHeight
|
||||||
|
node%left => null()
|
||||||
|
node%right => null()
|
||||||
|
taller = .true.
|
||||||
|
else if (node%item%key == root%item%key) then
|
||||||
|
!!$ write(0,*) 'SearchInsNode : found key',node%item%key,node%item%val,&
|
||||||
|
!!$ &root%item%key,root%item%val
|
||||||
|
info = AVLTreeDuplicate
|
||||||
|
node%item%val = root%item%val
|
||||||
|
return
|
||||||
|
|
||||||
|
else if (node%item%key < root%item%key) then
|
||||||
|
|
||||||
|
call AVLSearchInsNode(root%left,node,taller,info)
|
||||||
|
if (info == AVLTreeDuplicate) return
|
||||||
|
if (info == AVLTreeFatalError) return
|
||||||
|
if (taller) then
|
||||||
|
select case(root%balance)
|
||||||
|
case(LeftHigh)
|
||||||
|
call AVLTreeLeftBalance(root,taller)
|
||||||
|
case(EqualHeight)
|
||||||
|
root%balance = LeftHigh
|
||||||
|
case(RightHigh)
|
||||||
|
root%balance = EqualHeight
|
||||||
|
taller = .false.
|
||||||
|
case default
|
||||||
|
info = AVLTreeFatalError
|
||||||
|
end select
|
||||||
|
end if
|
||||||
|
else if (node%item%key > root%item%key) then
|
||||||
|
call AVLSearchInsNode(root%right,node,taller,info)
|
||||||
|
if (info == AVLTreeDuplicate) return
|
||||||
|
if (info == AVLTreeFatalError) return
|
||||||
|
if (taller) then
|
||||||
|
select case(root%balance)
|
||||||
|
case(LeftHigh)
|
||||||
|
root%balance = EqualHeight
|
||||||
|
taller = .false.
|
||||||
|
case(EqualHeight)
|
||||||
|
root%balance = RightHigh
|
||||||
|
case(RightHigh)
|
||||||
|
call AVLTreeRightBalance(root,taller)
|
||||||
|
case default
|
||||||
|
info = AVLTreeFatalError
|
||||||
|
end select
|
||||||
|
end if
|
||||||
|
end if
|
||||||
|
|
||||||
|
end subroutine AVLSearchInsNode_int2
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
recursive subroutine AVLTreeLeftBalance_int2(root,taller)
|
||||||
|
type(psb_treenode_int2), pointer :: root
|
||||||
|
logical :: taller
|
||||||
|
|
||||||
|
type(psb_treenode_int2), pointer :: rs, ls
|
||||||
|
|
||||||
|
ls => root%left
|
||||||
|
select case (ls%balance)
|
||||||
|
case(LeftHigh)
|
||||||
|
root%balance = EqualHeight
|
||||||
|
ls%balance = EqualHeight
|
||||||
|
call AVLTreeRotateRight(root)
|
||||||
|
taller = .false.
|
||||||
|
case(EqualHeight)
|
||||||
|
write(0,*) 'Warning: balancing and already balanced left tree? '
|
||||||
|
case(RightHigh)
|
||||||
|
rs => ls%right
|
||||||
|
select case(rs%balance)
|
||||||
|
case(LeftHigh)
|
||||||
|
root%balance = RightHigh
|
||||||
|
ls%balance = EqualHeight
|
||||||
|
case(EqualHeight)
|
||||||
|
root%balance = EqualHeight
|
||||||
|
ls%balance = EqualHeight
|
||||||
|
case(RightHigh)
|
||||||
|
root%balance = EqualHeight
|
||||||
|
ls%balance = LeftHigh
|
||||||
|
end select
|
||||||
|
rs%balance = EqualHeight
|
||||||
|
call AVLTreeRotateLeft(root%left)
|
||||||
|
call AVLTreeRotateRight(root)
|
||||||
|
taller = .false.
|
||||||
|
end select
|
||||||
|
|
||||||
|
end subroutine AVLTreeLeftBalance_int2
|
||||||
|
|
||||||
|
|
||||||
|
recursive subroutine AVLTreeRightBalance_int2(root,taller)
|
||||||
|
type(psb_treenode_int2), pointer :: root
|
||||||
|
logical :: taller
|
||||||
|
type(psb_treenode_int2), pointer :: rs, ls
|
||||||
|
|
||||||
|
rs => root%right
|
||||||
|
select case (rs%balance)
|
||||||
|
case(RightHigh)
|
||||||
|
root%balance = EqualHeight
|
||||||
|
rs%balance = EqualHeight
|
||||||
|
call AVLTreeRotateLeft(root)
|
||||||
|
taller = .false.
|
||||||
|
case(EqualHeight)
|
||||||
|
write(0,*) 'Warning: balancing and already balanced right tree? '
|
||||||
|
case(LeftHigh)
|
||||||
|
ls => rs%left
|
||||||
|
select case(ls%balance)
|
||||||
|
case(RightHigh)
|
||||||
|
root%balance = LeftHigh
|
||||||
|
rs%balance = EqualHeight
|
||||||
|
case(EqualHeight)
|
||||||
|
root%balance = EqualHeight
|
||||||
|
rs%balance = EqualHeight
|
||||||
|
case(LeftHigh)
|
||||||
|
root%balance = EqualHeight
|
||||||
|
rs%balance = RightHigh
|
||||||
|
end select
|
||||||
|
ls%balance = EqualHeight
|
||||||
|
call AVLTreeRotateRight(root%right)
|
||||||
|
call AVLTreeRotateLeft(root)
|
||||||
|
taller = .false.
|
||||||
|
end select
|
||||||
|
end subroutine AVLTreeRightBalance_int2
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
subroutine AVLTreeRotateLeft_int2(root)
|
||||||
|
type(psb_treenode_int2), pointer :: root
|
||||||
|
type(psb_treenode_int2), pointer :: temp
|
||||||
|
if (.not.associated(root)) then
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
if (.not.associated(root%right)) then
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
temp => root%right
|
||||||
|
root%right => temp%left
|
||||||
|
temp%left => root
|
||||||
|
root => temp
|
||||||
|
|
||||||
|
end subroutine AVLTreeRotateLeft_int2
|
||||||
|
|
||||||
|
subroutine AVLTreeRotateRight_int2(root)
|
||||||
|
type(psb_treenode_int2), pointer :: root
|
||||||
|
type(psb_treenode_int2), pointer :: temp
|
||||||
|
if (.not.associated(root)) then
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
if (.not.associated(root%left)) then
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
temp => root%left
|
||||||
|
root%left => temp%right
|
||||||
|
temp%right => root
|
||||||
|
root => temp
|
||||||
|
|
||||||
|
end subroutine AVLTreeRotateRight_int2
|
||||||
|
|
||||||
|
|
||||||
|
end module psb_avl_mod
|
Loading…
Reference in New Issue