PINT_Process_request interface

Requests and distributions are processed using the interface described here. The caller allocates an array of SEGMAX offsets and an array of SEGMAX segment sizes. These are passed to the PINT_Process_request function allong with an initialized PINT_Request_state, a PVFS_Request, a PVFS_Request_file_data struct which includes distribution, distribution parameters, metadata, and an EXTEND_FLAG that indicates if the routine should stop at the current end of file (if the value is zero) or should extend the local file to the size needed to complete the request (if the value is non-zero) in the even that the file ends before the end of the request. A read will typically have a zero value and a write will typically have a one value. Other arguments to PINT_Process_request include the maximum number of segments to process SEGMAX, a maximum number of bytes to transfer BYTEMAX, and a starting offset START_OFFSET, and EOF_FLAG argument returns whether the end of the request is at or beyond the end of file.

   typedef struct PINT_Request_file_data {
      PVFS_size    fsize;     /* actual size of local storage object */
      int32_t server_nr;   /* ordinal number of THIS server for this file */
      int32_t server_ct; /* number of servers for this file */
      PVFS_Distribution *dist;
      PVFS_Dist_parm    *dparm;
      PVFS_boolean      extend_flag;
   } PINT_Request_file_data;

PINT_Process_request fills in up to SEGMAX array entries, updates SEGMAX to indicate the number of segments processed, updates BYTEMAX to indicate the number of bytes processed, and updates START_OFFSET and the PINT_Reqest_state to indicate the last point in the request procssed. The function attempts to process BYTEMAX bytes, but cannot process more than SEGMAX contiguous regions. The code is expected to be optimized for the case where START_OFFSET is equal to the value returned the last time the function was called with the same PINT_Request_state.

   int PINT_Process_request(PINT_Request_state *req,
      PINT_Request_file_data *rfdata, int32_t *segmax,
      PVFS_offset *offset_array, PVFS_size *size_array,
      PVFS_offset *start_offset, PVFS_size *bytemax,
      PVFS_boolean *eof_flag, int mode);

The MODE tells the request processor whether to process the request in terms of the local file offsets on a server or local buffer offsets on a client. Clients should set this to PVFS_CLIENT to indicate that the data will be read into a contiguous buffer. Servers should set to PVFS_SERVER to indicate that the offsets computed by the distribution module should be used as the local file offsets. A third mode PVFS_CKSIZE indicates that the routine should count how many bytes up to BYTEMAX are left in the request, but does not alter the requset state or update the SIZE_ARRAY or OFFSET_ARRAY.

Before calling PINT_Process_request for a given request for the first time, the caller needs to allocate a PINT_Request_state structure. This is done by calling PINT_New_request passing in a pointer to the request. Theoretically multiple request states can exist for the same request, thought there is really no need to do such a thing.

struct PINT_Request_state *PINT_New_request_state (PINT_Request *request);

The new request state is positioned at the beginning of the request. The caller must also allocate a 64-bit start_offset, as well as the offset and size arrays, eof_flag, segmax, and bytemax. Each time PINT_Process_request is called, the segmax, bytemax, and eof_flag should be reset to the proper values, as the function returns results in these variables as well as taking inputs from them. The offset and size arrays are overwritten each time PINT_Process_state is called. The start_offset variable is normally NOT reset between calls as the caller normally wishes to continue translating the request from the point left off previously. After completing the processing of the request, the caller is also responsible for freeing the request state structure with a call to PINT_Free_request.

void PINT_Free_request_state (PINT_Request_state *req);

The following is a sample of code calling the request processing routines. It processes an entire request using no more than SEGMAX contiguous sements at a time and no more than BYTEMAX bytes at a time.

#include <pvfs-types.h>
#include <pint_distribution.h>

#define SEGMAX 32
#define BYTEMAX 250

do_a_request(PINT_Request *req,
      PVFS_Distribution *dist,
      PVFS_Dist_parm *dparm,
      PVFS_Meta meta)
{
   int i;

   // PVFS_Process_request arguments
   PINT_Request_state *reqs;
	PINT_Request_file_data rfdata;
   PVFS_offset offset_array[SEGMAX];
   PVFS_size size_array[SEGMAX];
   PVFS_offset offset;
   PVFS_size bytemax;
   int32_t segmax;
   PVFS_boolean extend_flag;
   PVFS_boolean eof_flag;

   reqs = PINT_New_request_state(req);
   rfdata.server_nr = 0;
   rfdata.server_ct = 1;
   rfdata.fsize = 10000000;
   rfdata.dist = dist
   rfdata.dparm = dparm
   rfdata.extend_flag = 0;
   eof_flag = 0;
   offset = 0;
   do {
      segmax = SEGMAX;
      bytemax = BYTEMAX;
      PINT_Process_request(reqs, &rfdata, &segmax, offset_array,
            size_array, &offset, &bytemax, &eof_flag, PINT_SERVER);
      printf("processed %lld bytes in %d segments\n", bytemax, segmax);
      for (i = 0; i < segmax; i++)
      {
         printf("segment %d: offset=%lld size=%lld\n", i,
               offset_array[i], size_array[i]);
      }
   } while (offset != -1);
}