Exemple #1
0
/*
 *  --	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);
}
Exemple #2
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) ; }
Exemple #3
0
/*
 * 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);
}