rc_t ccat_sra ( CCContainerNode *np, const KFile *sf, const char *name ) { rc_t rc; CCSra * sra; rc = CCSraInit (&sra, &np->sub, sf, name); if (rc == 0) { list_adata ldata; list_adata_init (&ldata); rc = step_through_dir (sra->adir, ".", list_action, &ldata); if (rc == 0) { DBGMSG (DBG_APP, 1, ("Vector sizes list (%u) sort (%u)\n", VectorLength(&ldata.list), VectorLength(&ldata.sort))); VectorDoUntil (&ldata.sort, false, CCSraOneItem, sra); /* VectorDoUntil (&ldata.list, false, CCSraOneItem, sra); */ } list_adata_whack (&ldata); CCSraWhack (sra); } DBGMSG (DBG_APP, 1, ("Done with %s\n", name)); return rc; }
/* CommitRow * commit row after writing * prevents further writes */ LIB_EXPORT rc_t CC VCursorCommitRow ( VCursor *self ) { rc_t rc; if ( self == NULL ) rc = RC ( rcVDB, rcCursor, rcCommitting, rcSelf, rcNull ); else if ( self -> read_only ) rc = RC ( rcVDB, rcCursor, rcCommitting, rcCursor, rcReadonly ); else if ( self -> state == vcFailed ) rc = RC ( rcVDB, rcCursor, rcCommitting, rcCursor, rcInvalid ); else if ( self -> state < vcRowOpen ) rc = RC ( rcVDB, rcCursor, rcCommitting, rcRow, rcNotOpen ); else if ( self -> state >= vcRowCommitted ) rc = 0; else { self -> permit_add_column = self -> permit_post_open_add; /* tell columns to slam in any default values */ rc = 0; if ( VectorDoUntil ( & self -> row, false, WColumnRowDefaults, & rc ) ) return rc; /* account for row just written */ self -> end_id = self -> row_id + 1; /* tell columns to commit the row, and allow each to return an earlier cutoff id ( half-closed ) */ if ( VectorDoUntil ( & self -> row, false, WColumnCommitRow, & self -> end_id ) ) { self -> state = vcFailed; return RC ( rcVDB, rcCursor, rcCommitting, rcMemory, rcExhausted ); } /* returned result should never be <= start id */ assert ( self -> end_id > self -> start_id ); /* if returned result dips down into the range of buffered rows then one or more columns has requested an automatic page commit */ self -> state = ( self -> end_id <= self -> row_id ) ? vcPageCommit : vcRowCommitted; } return rc; }
static bool VSchemaFindUntyped ( const VSchema *self, VTableFindData *pb ) { if ( self -> dad ) { if ( VSchemaFindUntyped ( self -> dad, pb ) ) return true; } return VectorDoUntil ( & self -> tbl, false, VTableTestUntyped, pb ); }
rc_t num_gen_contains_value( const num_gen* self, const uint64_t value ) { uint64_t temp = value; if ( self == NULL ) return RC( rcVDB, rcNoTarg, rcReading, rcSelf, rcNull ); if ( VectorDoUntil ( &(self->nodes), false, num_gen_contains_cb, &temp ) ) return 0; else return RC( rcVDB, rcNoTarg, rcReading, rcData, rcEmpty ); }
/* ---------------------------------------------------------------------- */ static rc_t build_tree () { rc_t rc; rc_data data; bool did_until = false; BSTreeInit (&options.pathtree); VectorDoUntil (options.pathpath, false, build_tree_add, &data); }
LIB_EXPORT rc_t CC KDlsetLastSymbol ( const KDlset *self, KSymAddr **sym, const char *name, bool ( CC * test ) ( const KSymAddr *sym, void *data ), void *data ) { rc_t rc; if ( sym == NULL ) rc = RC ( rcFS, rcDylib, rcSelecting, rcParam, rcNull ); else { if ( self == NULL ) rc = RC ( rcFS, rcDylib, rcSelecting, rcSelf, rcNull ); else if ( name == NULL ) rc = RC ( rcFS, rcDylib, rcSelecting, rcName, rcNull ); else if ( name [ 0 ] == 0 ) rc = RC ( rcFS, rcDylib, rcSelecting, rcName, rcEmpty ); else if ( test == NULL ) rc = RC ( rcFS, rcDylib, rcSelecting, rcFunction, rcNull ); else { KDlsetTrySymData pb; memset ( & pb, 0, sizeof pb ); pb . self = self; pb . name = name; pb . test = test; pb . data = data; pb . rc = RC ( rcFS, rcDylib, rcSelecting, rcName, rcNotFound ); VectorDoUntil ( & self -> ord, false, KDlsetTrySymbol, & pb ); if ( pb . sym != NULL ) { * sym = pb . sym; return 0; } rc = pb . rc; } * sym = NULL; } return rc; }
static rc_t num_gen_fix_overlaps( num_gen* self, uint32_t *count ) { overlap_ctx ctx; bool fix_executed = false; if ( self == NULL ) return RC( rcVDB, rcNoTarg, rcReading, rcSelf, rcNull ); ctx.overlaps = 0; do { ctx.prev = NULL; fix_executed = VectorDoUntil ( &(self->nodes), false, num_gen_overlap_fix_cb, &ctx ); } while ( fix_executed ); if ( count ) *count = ctx.overlaps; return 0; }
LIB_EXPORT rc_t CC KDlsetList ( const KDlset *self, KNamelist **listp ) { list_dylib_param pb; assert ( listp != NULL ); if ( self == NULL ) pb . rc = RC ( rcFS, rcDylib, rcListing, rcSelf, rcNull ); else { pb . rc = VNamelistMake ( & pb . list, VectorLength ( & self -> name ) ); if ( pb . rc == 0 ) { bool fail = VectorDoUntil ( & self -> name, false, list_dylib, & pb ); if ( ! fail ) pb . rc = VNamelistToNamelist ( pb . list, listp ); VNamelistRelease ( pb . list ); } } return pb . rc; }
LIB_EXPORT rc_t CC KDlsetSymbol ( const KDlset *self, KSymAddr **sym, const char *name ) { rc_t rc; if ( sym == NULL ) rc = RC ( rcFS, rcDylib, rcSelecting, rcParam, rcNull ); else { if ( self == NULL ) rc = RC ( rcFS, rcDylib, rcSelecting, rcSelf, rcNull ); else if ( name == NULL ) rc = RC ( rcFS, rcDylib, rcSelecting, rcName, rcNull ); else if ( name [ 0 ] == 0 ) rc = RC ( rcFS, rcDylib, rcSelecting, rcName, rcEmpty ); else { KDlsetTrySymData pb; memset ( & pb, 0, sizeof pb ); pb . self = self; pb . name = name; pb . rc = RC ( rcFS, rcDylib, rcSelecting, rcName, rcNotFound ); if ( VectorDoUntil ( & self -> ord, false, KDlsetTrySymbol, & pb ) ) { * sym = pb . sym; return 0; } rc = pb . rc; } * sym = NULL; } return rc; }
static rc_t VCursorFlushPageInt ( VCursor *self ) { rc_t rc; if ( self == NULL ) rc = RC ( rcVDB, rcCursor, rcFlushing, rcSelf, rcNull ); else if ( self -> read_only ) rc = RC ( rcVDB, rcCursor, rcFlushing, rcCursor, rcReadonly ); else { int64_t end_id; #if ! VCURSOR_FLUSH_THREAD run_trigger_prod_data pb; #endif switch ( self -> state ) { case vcConstruct: rc = RC ( rcVDB, rcCursor, rcFlushing, rcCursor, rcNotOpen ); break; case vcFailed: rc = RC ( rcVDB, rcCursor, rcFlushing, rcCursor, rcInvalid ); break; case vcRowOpen: rc = RC ( rcVDB, rcCursor, rcFlushing, rcCursor, rcBusy ); break; default: /* ignore request if there is no page to commit */ if ( self -> start_id == self -> end_id ) { /* the cursor should be in unwritten state, where the row_id can be reset but drags along the other markers. */ assert ( self -> end_id == self -> row_id ); return 0; } #if VCURSOR_FLUSH_THREAD MTCURSOR_DBG (( "VCursorFlushPageInt: going to acquire lock\n" )); /* get lock */ rc = KLockAcquire ( self -> flush_lock ); if ( rc != 0 ) return rc; MTCURSOR_DBG (( "VCursorFlushPageInt: have lock\n" )); /* make sure that background thread is ready */ while ( self -> flush_state == vfBusy ) { MTCURSOR_DBG (( "VCursorFlushPageInt: waiting for background thread\n" )); rc = KConditionWait ( self -> flush_cond, self -> flush_lock ); if ( rc != 0 ) { LOGERR ( klogSys, rc, "VCursorFlushPageInt: wait failed - exiting" ); KLockUnlock ( self -> flush_lock ); return rc; } } if ( self -> flush_state != vfReady ) { if ( self -> flush_state != vfBgErr ) rc = RC ( rcVDB, rcCursor, rcFlushing, rcCursor, rcInconsistent ); else { rc_t rc2; MTCURSOR_DBG (( "VCursorFlushPageInt: waiting on thread to exit\n" )); rc = KThreadWait ( self -> flush_thread, & rc2 ); if ( rc == 0 ) { rc = rc2; MTCURSOR_DBG (( "VCursorFlushPageInt: releasing thread\n" )); KThreadRelease ( self -> flush_thread ); self -> flush_thread = NULL; } } PLOGERR ( klogInt, (klogInt, rc, "VCursorFlushPageInt: not in ready state[$(state)] - exiting","state=%hu",self -> flush_state )); KLockUnlock ( self -> flush_lock ); return rc; } MTCURSOR_DBG (( "VCursorFlushPageInt: running buffer page\n" )); #endif /* first, tell all columns to bundle up their pages into buffers */ end_id = self -> end_id; rc = RC ( rcVDB, rcCursor, rcFlushing, rcMemory, rcExhausted ); if ( VectorDoUntil ( & self -> row, false, WColumnBufferPage, & end_id ) ) { VectorForEach ( & self -> row, false, WColumnDropPage, NULL ); self -> flush_state = vfFgErr; } else { /* supposed to be constant */ assert ( end_id == self -> end_id ); #if VCURSOR_FLUSH_THREAD MTCURSOR_DBG (( "VCursorFlushPageInt: pages buffered - capturing id and count\n" )); self -> flush_id = self -> start_id; self -> flush_cnt = self -> end_id - self -> start_id; self -> start_id = self -> end_id; self -> end_id = self -> row_id + 1; self -> state = vcReady; MTCURSOR_DBG (( "VCursorFlushPageInt: state set to busy - signaling bg thread\n" )); self -> flush_state = vfBusy; rc = KConditionSignal ( self -> flush_cond ); if ( rc != 0 ) LOGERR ( klogSys, rc, "VCursorFlushPageInt: condition returned error on signal" ); #else /* run all validation and trigger productions */ pb . id = self -> start_id; pb . cnt = self -> end_id - self -> start_id; pb . rc = 0; if ( ! VectorDoUntil ( & self -> trig, false, run_trigger_prods, & pb ) ) { self -> start_id = self -> end_id; self -> end_id = self -> row_id + 1; self -> state = vcReady; } rc = pb . rc; /* drop page buffers */ VectorForEach ( & self -> row, false, WColumnDropPage, NULL ); #endif } #if VCURSOR_FLUSH_THREAD MTCURSOR_DBG (( "VCursorFlushPageInt: unlocking\n" )); KLockUnlock ( self -> flush_lock ); #endif } } return rc; }
static rc_t CC run_flush_thread ( const KThread *t, void *data ) { rc_t rc; VCursor *self = data; /* acquire lock */ MTCURSOR_DBG (( "run_flush_thread: acquiring lock\n" )); rc = KLockAcquire ( self -> flush_lock ); if ( rc == 0 ) { do { bool failed; run_trigger_prod_data pb; /* wait for data */ if ( self -> flush_state == vfReady ) { MTCURSOR_DBG (( "run_flush_thread: waiting for input\n" )); rc = KConditionWait ( self -> flush_cond, self -> flush_lock ); if ( rc != 0 ) break; } /* bail unless state is busy */ if ( self -> flush_state != vfBusy ) { MTCURSOR_DBG (( "run_flush_thread: exiting\n" )); break; } /* prepare param block */ pb . id = self -> flush_id; pb . cnt = self -> flush_cnt; pb . rc = 0; MTCURSOR_DBG (( "run_flush_thread: unlocking and running\n" )); KLockUnlock ( self -> flush_lock ); /* run productions from trigger roots */ failed = VectorDoUntil ( & self -> trig, false, run_trigger_prods, & pb ); /* drop page buffers */ MTCURSOR_DBG (( "run_flush_thread: dropping page buffers\n" )); VectorForEach ( & self -> row, false, WColumnDropPage, NULL ); /* reacquire lock */ MTCURSOR_DBG (( "run_flush_thread: re-acquiring lock" )); rc = KLockAcquire ( self -> flush_lock ); if ( rc != 0 ) { self -> flush_state = vfBgErr; LOGERR ( klogSys, rc, "run_flush_thread: re-acquiring lock failed - exit" ); return rc; } #if FORCE_FLUSH_ERROR_EXIT if ( ! failed ) { pb . rc = RC ( rcVDB, rcCursor, rcFlushing, rcThread, rcCanceled ); failed = true; } #endif /* get out on failure */ if ( failed ) { self -> flush_state = vfBgErr; LOGERR ( klogInt, pb . rc, "run_flush_thread: run_trigger_prods failed - exit" ); KConditionSignal ( self -> flush_cond ); rc = pb . rc; } /* no longer busy */ else if ( self -> flush_state == vfBusy ) { /* signal waiter */ self -> flush_state = vfReady; MTCURSOR_DBG (( "run_flush_thread: signaling ready\n" )); rc = KConditionSignal ( self -> flush_cond ); if ( rc != 0 ) LOGERR ( klogSys, rc, "run_flush_thread: failed to signal foreground thread - exit" ); } } while ( rc == 0 ); MTCURSOR_DBG (( "run_flush_thread: unlocking\n" )); KLockUnlock ( self -> flush_lock ); } MTCURSOR_DBG (( "run_flush_thread: exit\n" )); return rc; }