psi::PSIO Class Reference

#include <psio.hpp>


Public Member Functions

int state ()
 return 1 if activated
void filecfg_kwd (const char *kwdgrp, const char *kwd, int unit, const char *kwdval)
const std::string & filecfg_kwd (const char *kwdgrp, const char *kwd, int unit)
 returns the keyword value. If not defined, returns empty string.
void open (unsigned int unit, int status)
 open unit. status can be PSIO_OPEN_OLD (if existing file is to be opened) or PSIO_OPEN_NEW if new file should be open
void close (unsigned int unit, int keep)
 close unit. if keep == 0, will remove the file, else keep it
void rehash (unsigned int unit)
 sync up the object to the file on disk by closing and opening the file, if necessary
int open_check (unsigned int unit)
 return 1 if unit is open
void read (unsigned int unit, char *key, char *buffer, ULI size, psio_address start, psio_address *end)
void write (unsigned int unit, char *key, char *buffer, ULI size, psio_address start, psio_address *end)
void read_entry (unsigned int unit, char *key, char *buffer, ULI size)
void write_entry (unsigned int unit, char *key, char *buffer, ULI size)
void rw (unsigned int unit, char *buffer, psio_address address, ULI size, int wrt)
void tocclean (unsigned int unit, char *key)
 Delete all TOC entries after the given key. If a blank key is given, the entire TOC will be wiped.
void tocprint (unsigned int unit, FILE *output)
 Print the table of contents for the given unit.
psio_tocentry * tocscan (unsigned int unit, char *key)
 Scans the TOC for a particular keyword and returns either a pointer to the entry or NULL to the caller.
void tocwrite (unsigned int unit)
 Write the table of contents for file number 'unit'. NB: This function should NOT call psio_error because the latter calls it!

Static Public Attributes

static int _error_exit_code_ = 1
 Upon catastrophic failure, the library will exit() with this code. The default is 1, but can be overridden.


Detailed Description

PSIO is an instance of libpsio library. Multiple instances of PSIO are supported.

Each instance can be configured using filecfg_kwd(). The following example best demonstrates how to configure a PSIO instance Lib: Lib->filecfg_kwd("DEFAULT","NAME",-1,"newwfn") // all modules will set filename prefix to newwfn for all units Lib->filecfg_kwd("DEFAULT","NVOLUME",34,"2") // all modules will stripe unit 34 over 2 volumes Lib->filecfg_kwd("CINTS","VOLUME1",-1,"/scratch1/") // module CINTS will access volume 1 of all units under /scratch etc.

Definition at line 22 of file psio.hpp.


Member Function Documentation

void PSIO::filecfg_kwd ( const char *  kwdgrp,
const char *  kwd,
int  unit,
const char *  kwdval 
)

set keyword kwd describing some aspect of configuration of PSIO file unit to value kwdval. kwdgrp specifies the keyword group (useful values are: "DEFAULT", "PSI", and the name of the current executable). If unit is set to -1, this keyword will set the default for all units (this keyword can be further overridden for some units). To specify a keyword that works for a specific unit, set unit to the appropriate number between 0 to PSIO_MAXUNIT.

PSIO understands the following keywords: "name" (specifies the prefix for the filename, i.e. if name is set to "psi" then unit 35 will be named "psi.35"), "nvolume" (number of files over which to stripe this unit, cannot be greater than PSIO_MAXVOL), "volumeX", where X is a positive integer less than or equal to the value of "nvolume".

Definition at line 32 of file filescfg.cc.

Referenced by psi::psirb::Task::prefix(), psio_get_filename_default(), psio_get_numvols_default(), psi::psirb::Task::scratch(), and psi::psirb::Task::Task().

00033                                            {
00034   std::string fkwd = fullkwd(kwdgrp, kwd, unit);
00035   files_keywords_[fkwd] = kwdval;
00036 }

void PSIO::read ( unsigned int  unit,
char *  key,
char *  buffer,
ULI  size,
psio_address  start,
psio_address *  end 
)

Reads data from within a TOC entry from a PSI file.

Parameters:
unit = The PSI unit number used to identify the file to all read and write functions.
key = The TOC keyword identifying the desired entry.
buffer = The buffer to store the data as it is read.
size = The number of bytes to read.
start = The entry-relative starting page/offset of the desired data.
end = A pointer to the entry-relative page/offset for the next byte after the end of the read request.

Definition at line 14 of file read.cc.

References psio_error(), psio_get_address(), psio_get_global_address(), rw(), and tocscan().

Referenced by psio_read(), and rw().

00015                                                        {
00016   psio_ud *this_unit;
00017   psio_tocentry *this_entry;
00018   psio_address start_toc, start_data, end_data; /* global addresses */
00019   ULI tocentry_size;
00020   
00021   this_unit = &(psio_unit[unit]);
00022   
00023   /* Find the entry in the TOC */
00024   this_entry = tocscan(unit, key);
00025   
00026   tocentry_size = sizeof(psio_tocentry) - 2*sizeof(psio_tocentry *);
00027   
00028   if (this_entry == NULL) {
00029     fprintf(stderr, "PSIO_ERROR: Can't find TOC Entry %s\n", key);
00030     psio_error(unit, PSIO_ERROR_NOTOCENT);
00031   } else {
00032     
00033     /* Compute the global starting page and offset for the data */
00034     start_toc = this_entry->sadd;
00035     start_data = psio_get_address(start_toc, tocentry_size);
00036     start_data = psio_get_global_address(start_data, start);
00037     
00038     /* Make sure the block starts and ends within the entry */
00039     if (start_data.page > this_entry->eadd.page)
00040       psio_error(unit, PSIO_ERROR_BLKSTART);
00041     else if ((start_data.page == this_entry->eadd.page) &&(start_data.offset
00042         > this_entry->eadd.offset))
00043       psio_error(unit, PSIO_ERROR_BLKSTART);
00044     
00045     end_data = psio_get_address(start_data, size);
00046     if ((end_data.page > this_entry->eadd.page))
00047       psio_error(unit, PSIO_ERROR_BLKEND);
00048     else if ((end_data.page == this_entry->eadd.page) &&(end_data.offset
00049         > this_entry->eadd.offset))
00050       psio_error(unit, PSIO_ERROR_BLKEND);
00051     
00052     /* Update end (an entry-relative address) for the caller */
00053     *end = psio_get_address(start, size);
00054   }
00055   
00056   /* Now read the actual data from the unit */
00057   rw(unit, buffer, start_data, size, 0);
00058   
00059 #ifdef PSIO_STATS
00060   psio_readlen[unit] += size;
00061 #endif  
00062 }

void PSIO::write ( unsigned int  unit,
char *  key,
char *  buffer,
ULI  size,
psio_address  start,
psio_address *  end 
)

Writes data to a TOC entry in a PSI file.

Parameters:
unit = The PSI unit number used to identify the file to all read and write functions.
key = The TOC keyword identifying the desired entry.
buffer = The buffer from which the data is written.
size = The number of bytes to write.
start = The entry-relative starting page/offset to write the data.
end = A pointer to the entry-relative page/offset for the next byte after the end of the write request.

Definition at line 13 of file write.cc.

References psio_error(), psio_get_address(), psio_get_global_address(), rw(), and tocscan().

Referenced by psio_write(), and rw().

00014                                                         {
00015   psio_ud *this_unit;
00016   psio_tocentry *this_entry, *last_entry;
00017   psio_address start_toc, start_data, end_data; /* global addresses */
00018   ULI tocentry_size;
00019   int dirty = 0;
00020   
00021   this_unit = &(psio_unit[unit]);
00022   
00023   /* Find the entry in the TOC */
00024   this_entry = tocscan(unit, key);
00025   
00026   tocentry_size = sizeof(psio_tocentry) - 2*sizeof(psio_tocentry *);
00027   
00028   if (this_entry == NULL) { /* New TOC entry */
00029     if (start.page||start.offset)
00030       psio_error(unit, PSIO_ERROR_BLKSTART);
00031     
00032     dirty = 1; /* set flag for writing the TOC header */
00033     
00034     this_entry = (psio_tocentry *) malloc(sizeof(psio_tocentry));
00035     ::strncpy(this_entry->key, key, PSIO_KEYLEN);
00036     this_entry->key[PSIO_KEYLEN-1] = '\0';
00037     this_entry->next = NULL;
00038     this_entry->last = NULL;
00039     
00040     /* Compute the global address of the new entry */
00041     if (!(this_unit->toclen)) { /* First TOC entry */
00042       this_entry->sadd.page = 0;
00043       this_entry->sadd.offset = sizeof(ULI); /* offset for the toclen value stored first */
00044       this_unit->toc = this_entry;
00045     } else { /* Use ending address from last TOC entry */
00046       last_entry = toclast(unit);
00047       this_entry->sadd = last_entry->eadd;
00048       last_entry->next = this_entry;
00049       this_entry->last = last_entry;
00050     }
00051     
00052     /* compute important global addresses for the entry */
00053     start_toc = this_entry->sadd;
00054     start_data = psio_get_address(start_toc, tocentry_size);
00055     start_data = psio_get_global_address(start_data, start);
00056     end_data = psio_get_address(start_data, size);
00057     
00058     /* Set the end address for this_entry */
00059     this_entry->eadd = end_data;
00060     
00061     /* Update the unit's TOC stats */
00062     this_unit->toclen++;
00063     wt_toclen(unit, this_unit->toclen);
00064     
00065     /* Update end (an entry-relative address) for the caller */
00066     *end = psio_get_address(start, size);
00067   } else { /* Old TOC entry */
00068     
00069     /* Compute the global starting page and offset for the block */
00070     start_toc = this_entry->sadd;
00071     start_data = psio_get_address(start_toc, tocentry_size);
00072     start_data = psio_get_global_address(start_data, start);
00073     
00074     /* Make sure this block doesn't start past the end of the entry */
00075     if (start_data.page > this_entry->eadd.page)
00076       psio_error(unit, PSIO_ERROR_BLKSTART);
00077     else if ((start_data.page == this_entry->eadd.page) &&(start_data.offset
00078         > this_entry->eadd.offset))
00079       psio_error(unit, PSIO_ERROR_BLKSTART);
00080     
00081     /* Compute the new global ending address for the entry, if necessary */
00082     end_data = psio_get_address(start_data, size);
00083     if (end_data.page > this_entry->eadd.page) {
00084       if (this_entry->next != NULL) {
00085         fprintf(stderr, "PSIO_ERROR: Attempt to write into next entry: %d, %s\n", unit, key);
00086         psio_error(unit, PSIO_ERROR_BLKEND);
00087       }
00088       this_entry->eadd = end_data;
00089       dirty = 1; /* set flag for writing the TOC header */
00090     } else if ((end_data.page == this_entry->eadd.page) &&(end_data.offset
00091         > this_entry->eadd.offset)) {
00092       if (this_entry->next != NULL) {
00093         fprintf(stderr, "PSIO_ERROR: Attempt to write into next entry: %d, %s\n", unit, key);
00094         psio_error(unit, PSIO_ERROR_BLKEND);
00095       }
00096       this_entry->eadd = end_data;
00097       dirty = 1; /* set flag for writing the TOC header */
00098     }
00099     
00100     /* Update end (an entry-relative address) for the caller */
00101     *end = psio_get_address(start, size);
00102   }
00103   
00104   if (dirty) /* Need to first write/update the TOC header for this record */
00105     rw(unit, (char *) this_entry, start_toc, tocentry_size, 1);
00106   
00107   /* Now write the actual data to the unit */
00108   rw(unit, buffer, start_data, size, 1);
00109   
00110 #ifdef PSIO_STATS
00111   psio_writlen[unit] += size;
00112 #endif
00113 }


The documentation for this class was generated from the following files:
Generated on Wed Feb 13 16:36:15 2008 for PSI by  doxygen 1.5.4