Open Source on IBM i

Linked List Release 1.4.0

The Linked List service program has been a very stable service program with a stable API.

The only thing that was a little bit clumsy was the sort function. The API design of the function offered great flexibility. You could implement your own sorting with your own sort implementation. The base sort algorithm used is the insertion sort. But the API offered the possiblity to use any other sort algorithm (if implemented).

That was all nice and good. But the more simple use case got more complicated:

Sorting the list in a user defined way (using the base sort algorithm).

For example you if you add some data structure to the list and you want to sort the list on a subfield of the data structure. In the previous version you would copy the whole existing sort procedure and change the part where the values are compared. I consider this copy & paste development style a really bad style and it leads to many errors.

The new API makes it a lot easier to sort the list entries by just writing a compare procedure.

The prototype for such a procedure looks like this:

dcl-pr compare int(10) extproc(*dclcase);
  value1 pointer const;
  length1 int(10) const;
  value2 pointer const;
  length2 int(10) const;
end-pr;

The result of the compare procedure is inspired by the way most implementations handle this (C, Java, ...).

  • 0 means the values are equal (and the order of the list probably won't change)
  • less than 0 means that the first value of the compare function should be higher in the list than the second value
  • greater than 0 means that the second value should be higher in the list than the first value

This makes comparing numbers fairly easy. For example the comparision of two integers.

dcl-proc compareIntegers export;
  dcl-pi *n int(10);
    value1 pointer const;
    length1 int(10) const;
    value2 pointer const;
    length2 int(10) const;
  end-pi;

  dcl-s x1 int(10) based(value1);
  dcl-s x2 int(10) based(value2);

  return x1 - x2;
end-proc;

But in the current implementations the pointer to the values can also be *null. So we must handle *null values in our compare procedure which bloats it a little bit.

dcl-proc compareIntegers export;
  dcl-pi *n int(10);
    value1 pointer const;
    length1 int(10) const;
    value2 pointer const;
    length2 int(10) const;
  end-pi;

  dcl-s x1 int(10) based(value1);
  dcl-s x2 int(10) based(value2);

  if (value1 = *null and value2 = *null);
    return 0;
  elseif (value1 = *null);
    return 1;
  elseif (value2 = *null);
    return -1;
  else;
    return x1 - x2;
  endif;  
end-proc;

And if you would like to have a descending order than just flip the expression to

return x2 - x1;

Another change is the way escape message are sent (or more precisely where they are sent to). Up until now they were sent to the boundary of the current program. This is not always very practicle and has now been changed to the be sent to the current call stack entry.

The API change can be viewed in the new release and the documentation has been updated on the ILEDocs website.

Happy sorting!

Mihael

Tags : linkedlist