Judy Logo
   Error Handeling

Error Handling

A lot of thought (and time) went into making error handling in Judy simple, while maintaining flexibility and capability. Error handling is a very boring subject even to write about. So read this short section and use the recommended second method. It generates the fastest code, uses the least amount of memory and requires you to write extra code only for insert/deletes functions. Also it is compatible with the other two methods. This method is for production code that may want to handle malloc() fails differently than the Judy default. If the Judy default method of handling malloc() fails are OK, then use the first method.

There are two (2) categories of Judy error returns, (or for any dynamic ADT):

1) User programming errors (bugs) such as memory corruption or invalid pointers.
2) Out-of-memory (malloc() failure) with Insert (Set) or Delete (Unset) when modifying a Judy array. Not all calls to insert and delete call malloc(), so they may succeed even when a call to malloc() would fail.

There are roughly three (3) methods of handling errors when using the macros:

1) Default Error Handling Method
The default is to print error messages to stderr, for example:

File 'YourCfile.c', line 1234: JudyLIns(), JU_ERRNO_* == 2, ID == 321

This indicates that an error occurred in the JudyLIns() function at line 321. Line 1234 is the line in 'YourCfile.c' where the JLI() call failed. JU_ERRNO_* == 2 is equal to JU_ERRNO_NOMEM (as defined in the Judy.h file). The ID number indicates the source line number in the function where the error originated. Your program then terminates with an exit(1);. By default, both categories of Judy error returns are printed this way. (The 'ID == 321' is for die hards that want more detail or for debugging Judy itself.)

2) Disable Macro Error Handling
When your program is "bug free", the only errors returned should be malloc() failures. Therefore all error returns can be treated as a malloc() failure. By using the below #define, all error testing and printing is turned off. Additional code needs to be added to the code that can have malloc() failures. Judy was designed to leave the same data in the array before the call if a malloc() fail occurs. (During testing of Judy, we found very few malloc()/OS's that were bug free after a malloc() failure. Sometimes it took weeks to discover because most systems go into a paging frenzy before running out of memory).
(in your program code), or
cc -DJUDYERROR_NOTEST sourcefile -lJudy
(on your command line).
// This is an example of how to program using method two (2).
JLI(PValue, PLArray, Index);
if (PValue == PJERR) goto out_of_memory_handling;

JLD(RC_int, PLArray, Index);
if (RC_int == JERR) goto out_of_memory_handling;

J1S(RC_int, P1Array, Index);
if (RC_int == JERR) goto out_of_memory_handling;

J1U(RC_int, P1Array, Index);
if (RC_int == JERR) goto out_of_memory_handling;

Note: Without 'JUDYERROR_NOTEST' defined, the 'goto out_of_memory_handling' will never be executed and will be optimized out by the compiler. The default method will be used -- Macro will print error information if an error occurs as explained above.

With 'JUDYERROR_NOTEST' defined, the 'goto out_of_memory_handling' will be executed when an error occurs -- which should only happen when malloc() fails.

3) User-Specified JUDYERROR() Macro Method
The JUDYERROR() macro (in Judy.h) provides flexibility for handling error returns as needed to suit your program while still using the Judy array macros instead of function calls. You can use a different JUDYERROR() macro to suit your needs. The following example is a possible alternative to the default. It is used to distinguish between the two types of errors (described above), and explicitly test for the remaining JU_ERRNO_NOMEM errors possible in your program.

// This is an example of Judy macro API to continue when out of memory 
// and print and exit(1) when any other error occurs.

#include <stdio.h>  // needed for fprintf()

// This is the macro that the Judy macro APIs use for return codes of -1:

#define JUDYERROR(CallerFile, CallerLine, JudyFunc, JudyErrno, JudyErrID) \
{                                                                         \
    if ((JudyErrno) != JU_ERRNO_NOMEM) /* ! a malloc() failure */         \
    {                                                                     \
        (void) fprintf(stderr, "File '%s', line %d: %s(), "               \
            "JU_ERRNO_* == %d, ID == %d\n",                               \
            CallerFile, CallerLine,                                       \
            JudyFunc, JudyErrno, JudyErrID);                              \
        exit(1);                                                          \
    }                                                                     \
#endif // JUDYERROR_NOTEST not defined

This error handling macro must be included before the #include <Judy.h> statement in your program.

Modified: 11/10/04 08:00:46 AM SourceForge.net Logo © 2004 Judy Team