Hi,I have to support an old project based on pure MDL. This code uses AVL Tree API even if not fully documented.
I need to change the simpler tree key with a more complex one and this is why I should replace mdlAvlTree_init with mdlAvlTree_initExtended.But no documentation and no examples exist about mdlAvlTree_initExtended.
I just find the api signature below but the use of blockSize and signature arguments is not clear.
AvlTree *mdlAvlTree_initExtended(int keyType,int (*compareFunc)(),int blockSize,int signature);
I did few tests, setting blockSize argument to my key size (or even more) , but my code aborts with a "System fault 5" after the second mdlAvlTree_insertNode.
Did anybody ever use this function ? If so, can anybody explain how to use mdlAvlTree_initExtended or post an example ?
Thanks,
Marco
mark anderson [Bentley]
Visit me at https://communities.bentley.com/communities/other_communities/bentley_innovation/default.aspx
Hi Mark,
I successfully used Bentley AvlTree API in the past but with simple key only (string, long, etc.).
This is the first time i need a more complex key so i wrote a small test program using mdlAvlTree_initExtended and a comparator-function. Comparator function is similar to other comparators used, for example, in mdlStringList_sort, or qsort comparator.
In my tests comparator function is never called, neither in the first call to mdlAvlTree_insertNode (as it should be) nor in the second and aborting call.
Here is the MDL code (.MC):
typedef struct {
Key key;
char value[32];
// other stuff here
} Node;
#define SGN(v) ((v)>0 ? 1 : ((v)<0 ? -1 : 0))
Private int comparatorFunc(void*a, void*b)
{
Key* ka = (Key*)a;
Key* kb = (Key*)b;
int test = strcmp( ka->key1, kb->key1 );
if( test==0) { // string keys have the same value
int test2 = ka->key2-kb->key2;
test = SGN(test2);
}
return test;
.............. test code ......
int status;
Node node;
AvlTree* map = mdlAvlTree_initExtended( AVLKEY_USER, comparatorFunc, sizeof(Key), 0);
strcpy( node.key.key1, "one" );
node.key.key2 = 1;
strcpy( node.value, "value1" );
// node is copied into the avl tree
status = mdlAvlTree_insertNode( map, &node, sizeof(Node) );
printf( "Inserted key %s: status %d\n", node.key.key1, status ); // returned status 0
strcpy( node.key.key1, "two" );
node.key.key2 = 2;
strcpy( node.value, "value2" );
status = mdlAvlTree_insertNode( map, &node, sizeof(Node) ); // <--- HERE! SYSTEM FAULT 5
I hope this can be useful to you to understand where is my fault!
Thanks for your support.
seen it, was just some overlapping between my mail and yours. From what I can say so far I don't see any failure (function signature cor compare is even correct according to the .h file). 3 suggestions nevertheless, just for a test or alternativ. 1. might be you should provide a function for traversal even. I'm not sure (without documentation) if you just don't need to provide all 3 callbacks (compare, traverse, delete) for full functionality. 2. I would try to make the compare function Public, not sure about the access level here, but it's a while since dealing with pure mdl ;) 3. As an alternative couldn't you prepare the key to contain a mix of both values (ie. printf("%s %ld", key1, key2)) if the order is such simple as you showed us (using preceeding zeroes wiht fixed lenght l for the int number) ? And than use the standard version mdlAvlTree_init(AVLKEY_PSTRING) instead of the extended ! HTH Michael
mdlAvlTree_initExtended is expecting a native compare func, it's not doing any of the boiler plate stuff to call out to mdl which is why it's not working for you.
Hi,
you are right!
I made the comparatorFunc native (I moved it in a .dll) and now mdlAvlTree_insertNode doesn't throw any SYSTEM FAULT.
Thanks for your hint.
Unknown said: I agree with you about STL but in this pure MDL module I can't directly use STL
Unknown said:I made the comparatorFunc native (I moved it in a .dll)
So you're writing native code! Why not use C++ and the STL?
Regards, Jon Summers LA Solutions