about the "ar" module

crux-00006: $SRC/utils/README.ar

* "ar": dynamically allocated buffers

  The "ar" functions provide resizable buffers.

  A resizable buffer is a dynamically allocated 
  array.


* The "ar" interface

  The interface is easily explained by an example.

  Suppose that we want to have a buffer of "point" structures,
  declared somewhere as:

    struct point
    {
      int x, y;
    };


  A buffer of these is declared this way:


    #include "utils/ar.h"

    struct point * point_buffer = 0;
    int point_buffer_n = 0;


  The function ar_ref:

    void * ar_ref (void ** ar, int * arn, int sz, int at);

  is used to access elements in the array.   For example:

    struct point * elt;

    elt = (struct point *)ar_ref ((void **)&point_buffer,
                                  &point_buffer_n,
                                  sizeof (struct point),
                                  13);

    elt->x = 1;
    elt->y = 3;

  The call to "ar_ref" ensures that the buffer is large enough
  to contain an element at index 13.  It returns the address of
  that element.

  After this call, "point_buffer" is no longer a null pointer.
  It points to a buffer.   This code has equivalent effect:

    (void)ar_ref ((void **)&point_buffer,
                  &point_buffer_n,
                  sizeof (struct point),
                  13);

    point_buffer[13].x = 1;
    point_buffer[13].y = 3;

  When new elements are added to to a buffer, they are
  initialized with 0 bytes.

  The integer "pointer_n" tracks the size of the buffer.  After
  a call to "ar_ref", it's value will always be greater than or
  equal to the index passed to "ar_ref".

  In the current implementation, small buffers are rounded up to
  a multiple of 256 elements.  Medium size buffers are rounded
  up to a multiple of 1K elements.  Large buffers to a multiple
  of 4K elements.

  The function "ar_trim" can be used to reduce the size of
  an earlier allocated buffer:

    void ar_trim (void ** ar, int * arn, int sz, int len);

  For example, if the point buffer contains 1,000 elements,
  then the call:

	ar_trim ((void **)&point_buffer,
                 &point_buffer_n,
                 sizeof (struct point),
                 10);

  will reduce the size of the buffer.

  A buffer and can entirely freed by passing a length of 0 
  to "ar_trim".  After the call:

	ar_trim ((void **)&point_buffer,
                 &point_buffer_n,
                 sizeof (struct point),
                 0);

  "point_buffer" is a null pointer and "point_buffer_n" is 0.






/*

    This file is part of Crux.

    Crux is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    Crux is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with Crux.  If not, see <http://www.gnu.org/licenses/>.

*/