[V8 MDL] How to use mdlAvlTree_initExtended ?

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

  • Marco,

    While I have not used this function I did take a quick look at the implementation. What is your key type? what are you passing in for the compare function? Are you writing your own compare? if so what does it return? What do you get back on the first insert? Is this just plain MDL (.MC ) code?

    Rgds,
  • From what you are describing, it sounds like the error occures when the first time 2 elements where compared. So either the pointer to the compare function is invalid (what even results in 0x0005 errors) or the compare function cannot reserve enough space to store the elements which should be compared.
    A code snippet of the function definition for the compare function, and the variables and types used for that, might be helpfull. I did make a lot of use of the mdlAvlTree stuff (before changing to STL later) but almost found it enough to store a simple key type and use mdlAvlTree_init(i.e. AVLKEY_ELEMENTID). There is no limitation to the stored type, so it was almost enough for me. When the elements become more complex, I switched to STL which should be almost possible if you can switch the app to native code, what will be a better preparation for the next Ustn versions.

    HTH Michael



  • 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" );

       // node is copied into the avl tree

       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.

    Marco

  • Hi Michael,
    I posted a code snippet from my test module.

    I agree with you about STL but in this pure MDL module I can't directly use STL .
    I should move my code in a .dll and then link it to my project via a .dlo. I keep the .dll solution as the last one.
    Thanks,
    Marco
  • 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.

    Marco

  • 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

  • I have to support an old project, a project born in pure MDL and initially made by a different company.
    Of course, I prefer and use C/C++ when developing new modules inside this project.
    The module I'm involved now, just for a small change, is a MDL module.
    Regards,
    Marco