Exemplo n.º 1
0
void ProjectWhack ( BSTNode *n, void *data )
{
    Project* self = (Project*)n;
    StringWhack(self->name);
    StringWhack(self->download_ticket);
    StringWhack(self->encryption_key);
    free(self);
}
Exemplo n.º 2
0
void ObjectWhack ( BSTNode *n, void *data )
{
    Object* self = (Object*)n;
    StringWhack(self->name);
    StringWhack(self->project);
    StringWhack(self->display_name);
    StringWhack(self->checksum);
    StringWhack(self->encryption_key);
    free(self);
}
Exemplo n.º 3
0
static void whack_lane( lane * l )
{
/*    KFileRelease( l->mappings ); */
    KFileRelease( l->reads );
    StringWhack ( l->name );
    free( l );
}
Exemplo n.º 4
0
static bool KNSProxiesHttpProxyInitFromKfg ( KNSProxies * self,
                                             const KConfig * kfg )
{
    bool fromKfg = false;

    const KConfigNode * proxy;
    rc_t rc = KConfigOpenNodeRead ( kfg, & proxy, "/http/proxy" );
    if ( rc == 0 ) {
        const KConfigNode * proxy_path;
        rc = KConfigNodeOpenNodeRead ( proxy, & proxy_path, "path" );
        if ( rc == 0 ) {
            String * path;
            rc = KConfigNodeReadString ( proxy_path, & path );
            if ( rc == 0 ) {
                DBGMSG ( DBG_KNS, DBG_FLAG ( DBG_KNS_PROXY ),
                    ( "Loading proxy '%S' from configuration\n", path ) );
                rc = KNSProxiesAddHTTPProxyPath ( self, "%S", path );
                if ( rc == 0 )
                    fromKfg = true;

                StringWhack ( path );
            }

            KConfigNodeRelease ( proxy_path );
        }

        KConfigNodeRelease ( proxy );
    }

    return fromKfg;
}
Exemplo n.º 5
0
static rc_t report_references( const VDBManager *vdb_mgr, VFSManager * vfs_mgr,
                               const char * spec, bool extended )
{
    const String * resolved = NULL;
    rc_t rc = resolve_accession( vfs_mgr, spec, &resolved );
    if ( rc == 0 && resolved != NULL )
    {
        rc = KOutMsg( "resolved into '%S'\n", resolved );
        if ( rc == 0 )
        {
            int path_type = ( VDBManagerPathType ( vdb_mgr, "%s", spec ) & ~ kptAlias );
            switch( path_type )
            {
            case kptDatabase :
                rc = report_ref_database( vdb_mgr, vfs_mgr, spec, extended );
                break;

            case kptTable    :
                KOutMsg( "cannot report references on a table-object\n" );
                rc = RC ( rcApp, rcNoTarg, rcAccessing, rcParam, rcInvalid );
                (void)LOGERR( klogErr, rc, "cannot report references on a table-object" );
                break;

            default          :
                KOutMsg( "the given object is not a vdb-database\n" );
                rc = RC ( rcApp, rcNoTarg, rcAccessing, rcParam, rcInvalid );
                (void)LOGERR( klogErr, rc, "the given object is not a vdb-database" );
                break;
            }
        }
        StringWhack ( resolved );
    }
    return rc;
}
Exemplo n.º 6
0
static void CC whack_ref_node( BSTNode *n, void *data )
{
    ref_node * node = ( ref_node * )n;
    bool * info = ( bool * )data;

    if ( *info )
    {
        OUTMSG(( "node >%S< used for %lu bytes (%lu active)\n",
                  node->name, node->bytes_requested, node->active_positions ));
    }

    if ( node->cur != NULL )
    {
        VCursorRelease( node->cur );
    }
    if ( node->tab != NULL )
    {
        VTableRelease( node->tab );
    }
    if ( node->name != NULL )
    {
        StringWhack ( node->name );
    }
    free( n );
}
Exemplo n.º 7
0
LIB_EXPORT rc_t CC KNSManagerVSetHTTPProxyPath ( KNSManager * self, const char * fmt, va_list args )
{
    rc_t rc = 0;

    if ( self == NULL )
        rc = RC ( rcNS, rcMgr, rcUpdating, rcSelf, rcNull );
    else
    {
        uint16_t proxy_port = 0;
        const String * proxy = NULL;

        if ( fmt != NULL && fmt [ 0 ] != 0 )
        {
            size_t psize;
            char path [ 4096 ];
            rc = string_vprintf ( path, sizeof path, & psize, fmt, args );
            if ( rc == 0 && psize != 0 )
            {
                char * colon = string_rchr ( path, psize, ':' );
                if ( colon != NULL )
                {
                    char * end;
                    const char * port_spec = colon + 1;
                    /* it is true that some day we might read symbolic port names... */
                    long port_num = strtol ( port_spec, & end, 10 );
                    if ( port_num <= 0 || port_num >= 0x10000 || end [ 0 ] != 0 )
                        rc = RC ( rcNS, rcMgr, rcUpdating, rcPath, rcInvalid );
                    else
                    {
                        proxy_port = ( uint64_t ) port_num;
                        psize = colon - path;
                    }
                }

                if ( rc == 0 )
                {
                    String tmp;
                    StringInit ( & tmp, path, psize, string_len ( path, psize ) );
                    rc = StringCopy ( & proxy, & tmp );
                }
            }
        }

        if ( rc == 0 )
        {
            if ( self -> http_proxy != NULL )
            {
                StringWhack ( self -> http_proxy );
                self -> http_proxy_port = 0;
            }

            self -> http_proxy = proxy;
            self -> http_proxy_enabled = ( proxy != NULL );
            self -> http_proxy_port = proxy_port;
        }
    }

    return rc;
}
Exemplo n.º 8
0
static rc_t CC on_store_entry( uint64_t key, const void *value, void *user_data )
{
    const String * bases = value;
    struct lookup_writer * writer = user_data;
    rc_t rc = write_packed_to_lookup_writer( writer, key, bases );
    StringWhack( bases );
    return rc;
}
Exemplo n.º 9
0
rc_t KeyRingDataAddProject(KeyRingData* data, const String* name, const String* download_ticket, const String* encryption_key)
{
    rc_t rc = 0;
    Project* p;

    p = (Project*)BSTreeFind(&data->projects, name, FindProject);
    if (p != NULL)
    {
        bool rewrite = false;
        String* dl = NULL;
        String* enc = NULL;
        if (StringCompare(p->download_ticket, download_ticket) != 0)
        {
            dl = p->download_ticket;
            rc = StringCopy((const String**)&p->download_ticket, download_ticket);
            if (rc == 0)
                rewrite = true;
            else
                dl = NULL;
        }
        if (rc == 0 && StringCompare(p->encryption_key, encryption_key) != 0)
        {
            enc = p->encryption_key;
            rc = StringCopy((const String**)&p->encryption_key, encryption_key);
            if (rc == 0)
                rewrite = true;
            else
                enc = NULL;
        }
        if (rc == 0 && rewrite)
        {
            if (dl)
                StringWhack(dl);
            if (enc)
                StringWhack(enc);
        }
    }
    else /* insert new */
    {
        rc = KeyRingDataInsertProject (&data->projects, data->next_projectId, name, download_ticket, encryption_key);
        if (rc == 0)
            ++data->next_projectId;
    }
    return rc;
}
Exemplo n.º 10
0
void release_slice( slice * slice )
{
    if ( slice != NULL )
    {
        if ( slice->refname != NULL )
            StringWhack( slice->refname );
        free( ( void * ) slice );
    }
}
Exemplo n.º 11
0
rc_t ProjectInit ( Project* self, uint32_t p_id, const String* name, const String* download_ticket, const String* encryption_key )
{
    rc_t rc = 0;
    memset(self, 0, sizeof(Project)); 
    self->id = p_id;
    rc = StringCopy((const String**)&self->name, name);
    if (rc == 0)
    {
        rc = StringCopy((const String**)&self->download_ticket, download_ticket);
        if (rc == 0)
        {
            rc = StringCopy((const String**)&self->encryption_key, encryption_key);
            if (rc != 0)
                StringWhack(self->download_ticket);
        }
        else
            StringWhack(self->name);
    }
    return rc;
}
Exemplo n.º 12
0
static void CC free_reply_obj( void * obj, void * data )
{
    if ( obj != NULL )
    {
        reply_obj * o = obj;
        if ( o->prj_id != NULL ) StringWhack( o->prj_id );        
        if ( o->obj_type != NULL ) StringWhack( o->obj_type );
        if ( o->id != NULL ) StringWhack( o->id );
        if ( o->name != NULL ) StringWhack( o->name );
        if ( o->date != NULL ) StringWhack( o->date );
        if ( o->checksum != NULL ) StringWhack( o->checksum );
        if ( o->ticket != NULL ) StringWhack( o->ticket );
        if ( o->path != NULL ) StringWhack( o->path );
        if ( o->message != NULL ) StringWhack( o->message );
        free( obj );
    }
}
Exemplo n.º 13
0
static
rc_t KNSManagerWhack ( KNSManager * self )
{
    rc_t rc;
    KConfigRelease ( self -> kfg );
    if ( self -> http_proxy != NULL )
        StringWhack ( self -> http_proxy );
    if ( self -> aws_access_key_id != NULL )
        StringWhack ( self -> aws_access_key_id );
    if ( self -> aws_secret_access_key != NULL )
        StringWhack ( self -> aws_secret_access_key );
    if ( self -> aws_region != NULL )
        StringWhack ( self -> aws_region );
    if ( self -> aws_output != NULL )
        StringWhack ( self -> aws_output );
    
    rc = HttpRetrySpecsDestroy ( & self -> retry_specs );
    free ( self );
    KNSManagerCleanup ();
    return rc;
}
Exemplo n.º 14
0
rc_t ObjectInit ( Object* self, 
                  uint32_t p_id, 
                  const String* p_name, 
                  const String* p_project, 
                  const String* p_display_name,
                  uint64_t p_size,
                  const String* p_checksum,
                  const String* p_encryption_key)
{
    rc_t rc = 0;
    memset(self, 0, sizeof(Project)); 
    self->id = p_id;
    rc = StringCopy((const String**)&self->name, p_name);
    if (rc == 0)
    {
        rc = StringCopy((const String**)&self->project, p_project);
        if (rc == 0)
        {
            rc = StringCopy((const String**)&self->display_name, p_display_name);
            if (rc == 0)
            {
                self->size = p_size;
                rc = StringCopy((const String**)&self->checksum, p_checksum);
                if (rc == 0)
                {
                    rc = StringCopy((const String**)&self->encryption_key, p_encryption_key);
                    if (rc != 0)
                        StringWhack(self->checksum);
                }
                if (rc != 0)
                    StringWhack(self->display_name);
            }
            if (rc != 0)
                StringWhack(self->project);
        }
        if (rc != 0)
            StringWhack(self->name);
    }
    return rc;
}                         
Exemplo n.º 15
0
static
rc_t KDatabaseMakeVPath ( KDatabase **dbp, const KDirectory *dir,
    const VPath *path, KMD5SumFmt *md5, bool read_only )
{
    const String* dbpathStr;
    rc_t rc = VPathMakeString ( path, &dbpathStr );    /* NUL-terminated */
    if ( rc == 0 )
    {
        rc = KDatabaseMake ( dbp, dir, dbpathStr->addr, md5, read_only );
        StringWhack(dbpathStr);
    }
    return rc;
}
Exemplo n.º 16
0
static rc_t on_enter_path( const reply_obj * obj, void * data )
{
    rc_t rc = 0;
    if ( obj != NULL && data != NULL )
    {
        reply_obj_list * list = data;
        reply_obj * found = find_obj( list, obj->id );
        if ( found != NULL )
        {
            if ( found->path != NULL ) StringWhack( found->path );
            rc = StringCopy( &found->path, obj->path );
        }
    }
    return rc;
}
Exemplo n.º 17
0
/******************************************************************************
    for the spot-group ( tree-node ), contains a tree of counter's
******************************************************************************/
static void CC whack_spotgroup( BSTNode *n, void *data )
{
    spotgrp * sg = ( spotgrp * )n;
    uint32_t idx, count;
    count = ( ( sizeof sg->cnv ) / sizeof( sg->cnv[0] ) );
    for ( idx = 0; idx < count; ++idx )
    {
        counter_vector * cv = (counter_vector *)&( sg->cnv[ idx ] );
        if ( cv->v != NULL )
        {
            free( cv->v );
        }
    }
    if ( sg->name != NULL )
        StringWhack ( sg->name );
    free( n );
}
Exemplo n.º 18
0
static rc_t build_full_url( char ** s )
{
    rc_t rc;
    String prefix, accession;
    const String * full_url;

    StringInitCString( &prefix, ENTREZ_URL );
    StringInitCString( &accession, *s );
    rc = StringConcat ( &full_url, &prefix, &accession );
    if ( rc == 0 )
    {
        free( *s );
        *s = string_dup_measure ( full_url->addr, NULL );
        StringWhack ( full_url );
    }
    return rc;
}
Exemplo n.º 19
0
static
void KNSManagerHttpProxyInit ( KNSManager * self )
{
    const KConfigNode * proxy;
    rc_t rc = KConfigOpenNodeRead ( self -> kfg, & proxy, "http/proxy" );
    if ( rc == 0 )
    {
        const KConfigNode * proxy_path;
        rc = KConfigNodeOpenNodeRead ( proxy, & proxy_path, "path" );
        if ( rc == 0 )
        {
            String * path;
            rc = KConfigNodeReadString ( proxy_path, & path );
            if ( rc == 0 )
            {
                rc = KNSManagerSetHTTPProxyPath ( self, "%S", path );
                if ( rc == 0 )
                {
                    const KConfigNode * proxy_enabled;
                    rc = KConfigNodeOpenNodeRead ( proxy, & proxy_enabled, "enabled" );
                    if ( rc == 0 )
                    {
                        rc = KConfigNodeReadBool ( proxy_enabled, & self -> http_proxy_enabled );
                        KConfigNodeRelease ( proxy_enabled );
                    }
                    else if ( GetRCState ( rc ) == rcNotFound )
                    {
                        rc = 0;
                    }

                    if ( rc != 0 )
                    {
                        KNSManagerSetHTTPProxyPath ( self, NULL );
                        assert ( self -> http_proxy_enabled == false );
                    }
                }

                StringWhack ( path );
            }

            KConfigNodeRelease ( proxy_path );
        }

        KConfigNodeRelease ( proxy );
    }
}
Exemplo n.º 20
0
static rc_t make_lane( cg_dump_opts * opts, struct sg_lookup * lookup, KDirectory * dir, String * spot_group, lane ** sg_lane )
{
    rc_t rc = 0;
    ( *sg_lane ) = malloc( sizeof ** sg_lane );
    if ( *sg_lane == NULL )
    {
        rc = RC( rcExe, rcDatabase, rcReading, rcMemory, rcExhausted );
        (void)LOGERR( klogErr, rc, "memory exhausted when creating new lane" );
    }
    else
    {
        (*sg_lane)->chunk = opts->first_chunk;
        (*sg_lane)->write_pos = 0;
        (*sg_lane)->spot_count = 0;
        rc = StringCopy ( &( (*sg_lane)->name ), spot_group );
        if ( rc != 0 )
        {
            (void)LOGERR( klogErr, rc, "cannot copy name for new lane" );
            free( *sg_lane );
        }
        else
        {
            rc = make_read_file( opts, lookup, dir, *sg_lane );
            if ( rc != 0 )
            {
                StringWhack ( (*sg_lane)->name );
                free( *sg_lane );
            }
/*
            else
            {
                rc = make_mappings_file( dir, *sg_lane );
                if ( rc != 0 )
                {
                    KFileRelease( (*sg_lane)->reads );
                    StringWhack ( (*sg_lane)->name );
                    free( *sg_lane );
                }
            }
*/
        }
    }
    return rc;
}
Exemplo n.º 21
0
string CVPath::ToString(EType type) const
{
    const String* str = 0;
    if (type == eSys) {
        if (rc_t rc = VPathMakeSysPath(*this, &str)) {
            NCBI_THROW2(CSraException, eOtherError,
                "Cannot get path from VPath", rc);
        }
    }
    else {
        if (rc_t rc = VPathMakeString(*this, &str)) {
            NCBI_THROW2(CSraException, eOtherError,
                "Cannot get path from VPath", rc);
        }
    }
    string ret(str->addr, str->size);
    StringWhack(str);
    return ret;
}
Exemplo n.º 22
0
rc_t KeyRingDataAddObject (KeyRingData*  data, 
                           const String* name, 
                           const String* project, 
                           const String* display_name,
                           uint64_t      size,
                           const String* checksum,
                           const String* encryption_key)
{
    rc_t rc = 0;
    Object* obj;

    obj = (Object*)BSTreeFind(&data->objects, name, FindObject);
    if (obj != NULL)
    {
        bool rewrite = false;
        String* proj = NULL;
        String* disp = NULL;
        String* csum = NULL;
        String* encr = NULL;
        if (StringCompare(obj->project, project) != 0)
        {
            proj = obj->project;
            rc = StringCopy((const String**)&obj->project, project);
            if (rc == 0)
                rewrite = true;
            else
                proj = NULL;
        }
        if (StringCompare(obj->display_name, display_name) != 0)
        {
            disp = obj->display_name;
            rc = StringCopy((const String**)&obj->display_name, display_name);
            if (rc == 0)
                rewrite = true;
            else
                disp = NULL;
        }
        if (size != obj->size)
        {
            obj->size = size;
            rewrite = true;
        }
        if (StringCompare(obj->checksum, checksum) != 0)
        {
            csum = obj->checksum;
            rc = StringCopy((const String**)&obj->checksum, checksum);
            if (rc == 0)
                rewrite = true;
            else
                csum = NULL;
        }
        if (StringCompare(obj->encryption_key, encryption_key) != 0)
        {
            encr = obj->encryption_key;
            rc = StringCopy((const String**)&obj->encryption_key, encryption_key);
            if (rc == 0)
                rewrite = true;
            else
                encr = NULL;
        }
        if (rc == 0 && rewrite)
        {
            if (proj)
                StringWhack(proj);
            if (disp)
                StringWhack(disp);
            if (csum)
                StringWhack(csum);
            if (encr)
                StringWhack(encr);
        }
    }
    else /* insert new */
    {
        rc = KeyRingDataInsertObject(&data->objects, 
                                     data->next_objectId, 
                                     name, 
                                     project, 
                                     display_name,
                                     size,
                                     checksum,
                                     encryption_key);
        if (rc == 0)
            ++data->next_objectId;
    }
    return rc;
}                           
Exemplo n.º 23
0
static rc_t StringRelease ( String * self ) {
    StringWhack ( self );

    return 0;
}
Exemplo n.º 24
0
static void HttpProxyClear ( HttpProxy * self ) {
    assert ( self );

    StringWhack ( self -> proxy_host );
}
Exemplo n.º 25
0
/* CheckConsistency
 *  runs a consistency check as efficiently as possible
 *
 *  in all cases, we make use of "PTrieForEach" to visit each node
 *  using the natural storage order. each node returned is counted,
 *  read and inserted into a BSTree whose nodes merge adjacent and
 *  overlapping ids into existing nodes.
 *
 *  if running a deep "key->id" test, then the key is first regenerated
 *  from the node, and then used to retrieve the id via the KIndex.
 *
 *  if the projection index exists, the id is tested against the node
 *  to ensure that projection works. if "id->key" is true, then use
 *  the KIndex to produce a key and compare it against the node.
 */
static
bool CC KPTrieIndexCCVisit_v2 ( PTNode *n, void *data )
{
    KPTrieIndexCCParms_v2 *pb = (KPTrieIndexCCParms_v2 *)data;
    const KPTrieIndex_v2 *self = pb -> self;

    rc_t rc;
    int64_t id;
    size_t usize;
    uint64_t span;
    uint32_t i, ord;

    /* detect conversion from v1 */
    if ( pb -> convertFromV1 && self -> id_bits == 0 )
    {
        uint32_t id32;

        /* payload of v1 PTNode is a 32-bit spot id */
        assert ( n -> data . size == sizeof id32 );
        memcpy ( & id32, n -> data . addr, sizeof id32 );
        id = self -> byteswap ? bswap_32 ( id32 ) : id32;
    }
    else
    {
        /* native v2 */
        /* TBD - should this pass n -> data . size * 8 ??? */
        if ( self -> id_bits != 0 )
        {
            rc = Unpack ( self -> id_bits, sizeof id * 8,
                n -> data . addr, 0, self -> id_bits, NULL,
                & id, sizeof id, & usize );
            if ( rc != 0 )
            {
                PLOGMSG ( klogWarn, ( klogWarn, "could not determine row id of v2 node $(nid)",
                                 "nid=0x%08x", n -> id ));
                pb -> failed = true;
                return false;
            }
        }
        else
        {
            id = 0;
        }

        id += self -> first;
    }

    /* convert from row-id to 1-based ordinal index */
    ord = KPTrieIndexID2Ord_v2 ( self, id );
    if ( ord == 0 )
    {
        /* 0 means not found */
        PLOGMSG ( klogWarn, ( klogWarn, "v2 node $(nid): row id $(rid) not found in trie",
                              "nid=0x%08x,rid=%ld", n -> id, id ));
        pb -> failed = true;
        return false;
    }

    if ( self -> ord2node != NULL )
    {
        /* to calculate span of last entry, where
           1-based "ord" == the number of nodes,
           just find the distance between the last row-id
           in index ( self->maxid ) and the current row-id */
        if ( ord == self -> count )
            span = self -> maxid - id + 1;
        else
        {
            /* from here on, we will use "ord" to be the
               ZERO-BASED index of the slot FOLLOWING the
               one corresponding to id. we want to find the
               row-id AFTER the current one and calculate distance */
            switch ( self -> variant )
            {
            /* linear array */
            case 0:
                /* starting with the FOLLOWING slot,
                   count duplicate entries */
                for ( i = ord; i < self -> count; ++ i )
                {
                    if ( n -> id != self -> ord2node [ i ] )
                        break;
                }
                span = self -> first + i - id;
                break;

            /* packed ordered array of sparse row-ids from here on
               we already have "id" for this node, so the span will
               be the distance from NEXT id - 1-based ord is 0-based next */
            case 1:
                span = self -> first + self -> id2ord . v8 [ ord ] - id;
                break;
            case 2:
                span = self -> first + self -> id2ord . v16 [ ord ] - id;
                break;
            case 3:
                span = self -> first + self -> id2ord . v32 [ ord ] - id;
                break;
            case 4:
                span = self -> first + self -> id2ord . v64 [ ord ] - id;
                break;
            default:
                PLOGMSG ( klogErr, ( klogErr, "PTrie v2 index has bad variant code: $(variant)",
                                     "variant=%u", self -> variant ));
                pb -> rc = RC ( rcDB, rcIndex, rcValidating, rcIndex, rcCorrupt );
                return true;
            }
        }
    }
    else if ( self -> span_bits == 0 )
        span = 1;
    else
    {
        /* TBD - this case is never used in practice.
           it would be an skey without a projection index */
        rc = Unpack ( self -> span_bits, sizeof span * 8,
                      n -> data . addr, 0, self -> id_bits, NULL,
                      & span, sizeof span, & usize );
        if ( rc != 0 )
        {
            PLOGMSG ( klogWarn, ( klogWarn, "could not determine span of v2 node $(nid), row id $(rid)",
                                  "nid=0x%08x,rid=%ld", n -> id, id ));
            pb -> failed = true;
            return false;
        }
    }

    /* record the node, row id, span */
    pb -> rc = KIdStatsInsert ( & pb -> stats, id, span );
    if ( pb -> rc != 0 )
    {
        PLOGERR ( klogSys, ( klogSys, pb -> rc, "failed when examining node id $(nid) with row id $(rid), span $(span)",
                             "nid=0x%08x,span=%u,rid=%ld", n -> id, span, id ));
        return true;
    }

    /* if we have a projection index, test it */
    if ( self -> ord2node != NULL )
    {
        if ( id < self -> first || id > self -> last )
        {
            PLOGMSG ( klogWarn, ( klogWarn, "node id $(nid) with row id $(rid) is not within projection range of $(min_rid)..$(max_rid)",
                                 "nid=0x%08x,rid=%ld,min_rid=%ld,max_rid=%ld",
                                  n -> id, id, self -> first, self -> last ));
            pb -> failed = true;
            return false;
        }
        for ( i = 0; i < span; ++ i )
        {
            if ( self -> ord2node [ i + ord - 1 ] != n -> id )
            {
                PLOGMSG ( klogWarn, ( klogWarn, "node id $(nid) with row id $(rid) does not match projection node id of $(pnid)",
                                      "nid=0x%08x,rid=%ld,pnid=0x%08x", n -> id, id + 1, self -> ord2node [ i + ord - 1 ] ));
                pb -> failed = true;
                return false;
            }
            if ( ! pb -> all_ids || self -> variant != 0 )
                break;
        }
    }

    /* if performing deeper tests */
    if ( pb -> key2id || pb -> id2key )
    {
        int64_t start_id;
        uint64_t id_count;

        /* need to recover key from given node */
        const String *orig;
        pb -> rc = PTNodeMakeKey ( n, & orig );
        if ( pb -> rc != 0 )
        {
            PLOGERR ( klogSys, ( klogSys, pb -> rc, "failed when retrieving text for node id $(nid) with row id $(rid)",
                                 "nid=0x%08x,rid=%u", n -> id, id ));
            return true;
        }

        /* key->id test */
        if ( pb -> key2id )
        {
            rc = KIndexFindText ( pb -> outer, orig -> addr, & start_id, & id_count, NULL, NULL );
            if ( rc != 0 )
            {
                PLOGERR ( klogWarn, ( klogWarn, rc, "failed to retrieve start id and count for key '$(key)', row id $(rid)",
                                      "key=%S,rid=%u", orig, id ) );
                pb -> failed = true;
            }
            else if ( start_id != ( int64_t ) id || id_count != span )
            {
                PLOGERR ( klogWarn, ( klogWarn, rc, "key '$(key)' maps to start id $(start_id), count $(id_count): expected id $(rid), count 1.",
                                      "key=%S,rid=%u,start_id=%ld,id_count=%lu", orig, id, start_id, id_count ) );
                pb -> failed = true;
            }
        }

        /* id->key test */
        if ( pb -> id2key )
        {
            char buffer [ 256 ], *key = buffer;
            size_t key_size, bsize = sizeof buffer;
            if ( sizeof buffer <= orig -> size )
            {
                key = (char *)malloc ( bsize = orig -> size + 1 );
                if ( key == 0 )
                {
                    pb -> rc = RC ( rcDB, rcIndex, rcValidating, rcMemory, rcExhausted );
                    StringWhack ( ( String* ) orig );
                    return true;
                }
            }

            for ( i = 0; i < span; ++ i )
            {
                rc = KIndexProjectText ( pb -> outer, id + i, & start_id, & id_count, key, bsize, & key_size );
                if ( rc != 0 )
                {
                    PLOGERR ( klogWarn, ( klogWarn, rc, "failed to retrieve key, start id and count for row id $(rid)",
                                          "rid=%u", id + i ) );
                    pb -> failed = true;
                    break;
                }

                if ( orig -> size != key_size || memcmp ( orig -> addr, key, key_size ) != 0 )
                {
                    PLOGERR ( klogWarn, ( klogWarn, rc, "row $(rid) maps to key '$(key)': expected key '$(orig)'.",
                                          "rid=%u,key=%.*s,orig=%S", id + i, ( int ) key_size, key, orig ) );
                    pb -> failed = true;
                }
                if ( start_id != id || id_count != ( uint64_t ) span )
                {
                    PLOGERR ( klogWarn, ( klogWarn, rc, "row $(rid) maps to start id $(start_id), count $(id_count): expected $(row_start), $(span).",
                                          "rid=%u,id_count=%lu,start_id=%ld,row_start=%ld,span=%u",
                                          id, id_count, start_id, id, span ) );
                    pb -> failed = true;
                }

                if ( ! pb -> all_ids || pb -> failed )
                    break;
            }

            if ( key != buffer )
                free ( key );
        }

        StringWhack ( ( String* ) orig );
    }

    return false;
}