/* * -- inv_open_next_log - Open next best log file in inventory. * * inv_open_next_log searches the inventory for the next best * log file to process. * * Returns: * 1 if no next log file * 0 if successful * -1 other error */ static int inv_open_next_log(sam_fsa_inv_t **invp) { sam_fsa_inv_t *inv; int done_ord = -1; /* Ordinal of youngest done log */ sam_time_t done_time = 0; /* Init time of youngest done log */ int next_ord = -1; /* Ordinal of oldest not done log */ sam_time_t next_time = 0; /* Init time of oldest not done log */ int i; if (inv_update(invp) < 0) { return (-1); } inv = *invp; /* * Scan inventory table: * 1. Find youngest log file that is completely processed (i.e. done) * 2. Find next best log file for processing (i.e., oldest not done) */ for (i = 0; i < inv->n_logs; i++) { /* Don't want to pick current log */ if (i == inv->c_log) { continue; } /* If log already processed record youngest done time */ if (inv->logs[i].status == fstat_done && inv->logs[i].init_time > done_time) { done_ord = i; done_time = inv->logs[i].init_time; } /* If log still requires processing */ if (inv->logs[i].status == fstat_none || inv->logs[i].status == fstat_part) { if (inv->logs[i].init_time < next_time || next_ord == -1) { next_ord = i; next_time = inv->logs[i].init_time; } } } if (next_ord < 0) { return (1); /* If no next entry */ } if (inv->c_log >= 0 && next_time < inv->logs[inv->c_log].init_time) { Trace(TR_ERR, "next file [%s] older than current file [%s]", inv->logs[next_ord].name, inv->logs[inv->c_log].name); } if (inv->last_time != 0 && next_time < inv->last_time) { Trace(TR_ERR, "next file [%s] older than last processed event", inv->logs[next_ord].name, inv->logs[inv->c_log].name); } if (done_ord >= 0 && next_time < done_time) { Trace(TR_ERR, "next file [%s] older than" "youngest done file [%s]", inv->logs[next_ord].name, inv->logs[done_ord].name); } /* Close current log, mark as done */ if (inv->c_log >= 0) { inv_close_log(inv, TRUE); } inv_open_log(inv, next_ord); return (0); }
dyret_enum dy_pivot (int xipos, double abarij, double maxabarj) /* This routine handles a single pivot. It first checks that the pivot element satisfies a stability test, then calls inv_update to pivot the basis. We can still run into trouble, however, if the pivot results in a singular or near-singular basis. NOTE: There is an implicit argument here that's not immediately obvious. inv_update gets the entering column from a cached result set with the most recent call to inv_ftran(*,1) (dy_ftran(*,true), if you prefer). The underlying assumption is that this is readily available from when we ftran'd the entering column to find the leaving variable. Parameters: xipos: the basis position of the entering variable abarij: the pivot element (only the absolute value is used) maxabarj: for a primal pivot, max{i} |abar<i,j>|, for a dual pivot, max{j} |abar<i,j>| Returns: dyrOK: the pivot was accomplished without incident (inv_update) dyrMADPIV: the pivot element abar<i,j> was rejected as numerically unstable (dy_chkpiv) dyrSINGULAR: the pivot attempt resulted in a structurally singular basis (i.e., some diagonal element is zero) (inv_update) dyrNUMERIC: the pivot attempt resulted in a numerically singular (unstable) basis (i.e, some diagonal element is too small compared to other elements in the associated row and column) (inv_update) dyrBSPACE: glpinv/glpluf ran out of space for the basis representation (inv_update) dyrFATAL: internal confusion */ { int retval ; double ratio ; dyret_enum retcode ; const char *rtnnme = "dy_pivot" ; /* Check that the pivot element meets the current criterion for numerical stability. Arguably this should have been checked by the caller, but that's no excuse for not doing it now. */ ratio = dy_chkpiv(abarij,maxabarj) ; if (ratio < 1.0) { # ifndef DYLP_NDEBUG if (dy_opts->print.basis >= 3) { dyio_outfmt(dy_logchn,dy_gtxecho, "\n %s(%d) pivot aborted; est. pivot stability %g.", dy_prtlpphase(dy_lp->phase,TRUE), dy_lp->tot.iters,rtnnme,ratio) ; } # endif return (dyrMADPIV) ; } /* Make the call to inv_update, then recode the result. */ retval = inv_update(luf_basis,xipos) ; # ifndef DYLP_NDEBUG if ((retval == 0 && dy_opts->print.basis >= 5) || (retval > 0 && dy_opts->print.basis >= 3)) { dyio_outfmt(dy_logchn,dy_gtxecho, "\n %s(%d) estimated pivot stability %g; ", dy_prtlpphase(dy_lp->phase,TRUE),dy_lp->tot.iters,ratio) ; dyio_outfmt(dy_logchn,dy_gtxecho,"measured pivot stability %g.", luf_basis->min_vrratio) ; } # endif switch (retval) { case 0: { retcode = dyrOK ; break ; } case 1: { retcode = dyrSINGULAR ; # ifndef DYLP_NDEBUG if (dy_opts->print.basis >= 2) { dyio_outfmt(dy_logchn,dy_gtxecho, "\n %s(%d) singular basis (structural) after pivot.", dy_prtlpphase(dy_lp->phase,TRUE),dy_lp->tot.iters) ; } # endif break ; } case 2: { retcode = dyrNUMERIC ; # ifndef DYLP_NDEBUG if (dy_opts->print.basis >= 2) { dyio_outfmt(dy_logchn,dy_gtxecho, "\n %s(%d) singular basis (numeric) after pivot.", dy_prtlpphase(dy_lp->phase,TRUE),dy_lp->tot.iters) ; } # endif break ; } case 3: case 4: { retcode = dyrBSPACE ; # ifndef DYLP_NDEBUG if (dy_opts->print.basis >= 2) { dyio_outfmt(dy_logchn,dy_gtxecho,"\n %s(%d) out of space (%s)", dy_prtlpphase(dy_lp->phase,TRUE),dy_lp->tot.iters, (retval == 3)?"eta matrix limit":"sparse vector area") ; } # endif break ; } default: { errmsg(1,rtnnme,__LINE__) ; retcode = dyrFATAL ; break ; } } return (retcode) ; }
/* * sam_fsa_open_inv - opens inventory for event log path * inv - address of pointer for inventory to create * path - absolute path to directory with events logs * fs_name - family set name for filesystem events * appname - unique identifier for application using this fsa api * * precond - * inv pointer is null * fs_name is valid family set name * path points to valid directory with event logs for fs_name * postcond - * inv is allocated and populated with complete event log information * inventory file is created in path with name 'fs_name.appname.inv' * * Returns 0 on success, -1 on failure */ int sam_fsa_open_inv( sam_fsa_inv_t **invp, char *path, char *fs_name, char *appname) { sam_fsa_inv_t *inv; char *inv_path; int inv_fd; int inv_sz; int rst = 0; if (*invp != NULL) { Trace(TR_ERR, "Inventory table already allocated."); return (-1); } inv_path = inv_build_path(path, fs_name, appname); inv_fd = inv_open(inv_path, &inv_sz); if (inv_fd < 0) { Trace(TR_ERR, "Open inventory file failed."); return (-1); } /* * Allocate inventory table. Initially inv_sz+100 file entries * allocated (one in fsalog_inv_t) */ SamMalloc(inv, sizeof (sam_fsa_inv_t) + inv_sz + 99*sizeof (sam_fsa_log_t)); memset(inv, 0, sizeof (sam_fsa_inv_t) + inv_sz + 99*sizeof (sam_fsa_log_t)); /* Initialize inventory */ strncpy(inv->fs_name, fs_name, sizeof (inv->fs_name)); inv->l_fsn = strlen(fs_name); inv->n_logs = inv_sz / sizeof (sam_fsa_log_t); inv->n_alloc = inv->n_logs+100; inv->c_log = -1; inv->fd_log = -1; inv->fd_inv = inv_fd; SamStrdup(inv->path_fsa, path); inv->path_inv = inv_path; /* Read inventory file. */ if (inv_sz > 0) { rst = read(inv->fd_inv, &inv->logs[0], inv_sz); if (rst < 0) { Trace(TR_ERR, "read(%s) failed", inv->path_inv); goto error; } if (rst != inv_sz) { Trace(TR_ERR, "read(%s) failed: incomplete read", inv->path_inv); goto error; } } if (inv_update(&inv) < 0) { goto error; } *invp = inv; return (0); error: inv_free(&inv); return (-1); }