#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. | |
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.
| 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.
| 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.
| 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 }
1.5.4