Пример #1
0
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;
}
Пример #2
0
/* 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;
}
Пример #3
0
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 );
}
Пример #4
0
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 );
}
Пример #5
0
/*  ----------------------------------------------------------------------
 */
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);
}
Пример #6
0
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;
}
Пример #7
0
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;
}
Пример #8
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;
}
Пример #9
0
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;
}
Пример #10
0
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;
}
Пример #11
0
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;
}