SubNtx
- Antonio Linares
- Site Admin
- Posts: 37481
- Joined: Thu Oct 06, 2005 5:47 pm
- Location: Spain
- Contact:
- Antonio Linares
- Site Admin
- Posts: 37481
- Joined: Thu Oct 06, 2005 5:47 pm
- Location: Spain
- Contact:
- Biel EA6DD
- Posts: 680
- Joined: Tue Feb 14, 2006 9:48 am
- Location: Mallorca
- Contact:
-
- Posts: 189
- Joined: Sun Jul 08, 2007 1:46 am
- Location: Uruguay
- Antonio Linares
- Site Admin
- Posts: 37481
- Joined: Thu Oct 06, 2005 5:47 pm
- Location: Spain
- Contact:
-
- Posts: 199
- Joined: Tue Apr 22, 2008 9:54 am
- Location: Valladolid, Spain.
Estoy en ello, pero OrdWildSeek() sólo trabaja con CDX si no me equivoco, generaré el índice en CDX.Antonio Linares wrote:Habría que hacer unas pruebas de velocidad con OrdWildSeek() y ver en que tiempos estamos.
David, nos ayudas con la misma prueba que hicistes anteriormente, pero usando OrdWildSeek() ? Gracias
Por cierto, la versión de la rutina sin malloc() y sin free(), no es que vuele, es que vuela a reación...
Saludos!
-
- Posts: 199
- Joined: Tue Apr 22, 2008 9:54 am
- Location: Valladolid, Spain.
OrdWildSeek()
Pues con OrdWildSeek(), se llega a producir un error, imagino que debido al colapso de memoria¿?... (no sé si digo una burrada, pero es lo que parece), arrojando el siguiente error:
----------------------------------------
Total 16036824 allocations (5334271 reallocation), of which 16036823 freed.
Highest total allocated 6900507 bytes in 5073 blocks.
WARNING! Memory allocated but not released: 40 bytes (1 blocks)
source\vm\fm.c:778: HB_TR_ERROR Block 1 00B0B24C (size 40) ORDLISTADD(0), "4CB2B
0004CB2B000E0AD44000100020002000000000000000A000000010000000000000000000000"
Hasta este error, llevábamos 38 segundos (no sé si efectivos de búsqueda o como causa que luego arroja), con índice CDX, por lo que no creo que en velocidad lleguemos a igualar a SubNtx()
Saludos!
----------------------------------------
Total 16036824 allocations (5334271 reallocation), of which 16036823 freed.
Highest total allocated 6900507 bytes in 5073 blocks.
WARNING! Memory allocated but not released: 40 bytes (1 blocks)
source\vm\fm.c:778: HB_TR_ERROR Block 1 00B0B24C (size 40) ORDLISTADD(0), "4CB2B
0004CB2B000E0AD44000100020002000000000000000A000000010000000000000000000000"
Hasta este error, llevábamos 38 segundos (no sé si efectivos de búsqueda o como causa que luego arroja), con índice CDX, por lo que no creo que en velocidad lleguemos a igualar a SubNtx()
Saludos!
- Antonio Linares
- Site Admin
- Posts: 37481
- Joined: Thu Oct 06, 2005 5:47 pm
- Location: Spain
- Contact:
-
- Posts: 330
- Joined: Fri May 25, 2007 9:06 pm
- Antonio Linares
- Site Admin
- Posts: 37481
- Joined: Thu Oct 06, 2005 5:47 pm
- Location: Spain
- Contact:
- Antonio Linares
- Site Admin
- Posts: 37481
- Joined: Thu Oct 06, 2005 5:47 pm
- Location: Spain
- Contact:
Hemos adaptado el código de Cesar A. Gil, para poder usarlo y probarlo desde Harbour y xHarbour.
Aqui está la primera versión. Fijaros en que le pasamos un codeblock para hacer lo que queramos con cada clave del fichero NTX. El siguiente paso será crear un nuevo fichero NTX con las claves que cumplan una determinada condición.:
test.prg
Aqui está la primera versión. Fijaros en que le pasamos un codeblock para hacer lo que queramos con cada clave del fichero NTX. El siguiente paso será crear un nuevo fichero NTX con las claves que cumplan una determinada condición.:
test.prg
Code: Select all
#include "FiveWin.ch"
FIELD First, Last
function Main()
USE Customer VIA "DBFNTX"
INDEX ON First+Last TO Customer
SET INDEX TO
SubNtx( "customer.ntx", { | nRecNo, cKey | Test( nRecNo, cKey ) } )
return nil
function Test( nRecNo, cKey ) // En esta prueba solo vamos a mostrar las 10 primeras claves
static nTimes := 1
if nTimes < 11
MsgInfo( cKey, "Key: " + AllTrim( Str( nTimes++ ) ) + ;
" --> RecNo: " + AllTrim( Str( nRecNo ) ) )
endif
return nil
#pragma BEGINDUMP
#include <hbapi.h>
#include <hbapifs.h>
#include <hbvm.h>
#define MAX_KEY 256
#define BUF_SIZE 1024
typedef struct
{
unsigned short int type;
unsigned short int version;
long root;
long next_page;
unsigned short int item_size;
unsigned short int key_size;
unsigned short int key_dec;
unsigned short int max_item;
unsigned short int half_page;
char key_expr[ MAX_KEY ];
char unique;
} NTX_HEADER;
typedef struct
{
long page;
long rec_no;
char key[ 1 ];
} NTX_ITEM;
typedef struct
{
unsigned short item_count;
unsigned short item_offset[ 1 ];
} NTX_BUFFER;
static void ReadPage( int hFileIn, long page_offset, PHB_ITEM pCodeBlock, unsigned short int iKeySize )
{
char ntxPage[ BUF_SIZE ];
NTX_ITEM * pNtxItem;
NTX_BUFFER * pNtxBuffer;
int i;
hb_fsSeek( hFileIn, page_offset, FS_SET );
if( hb_fsRead( hFileIn, ntxPage, BUF_SIZE ) != BUF_SIZE )
return;
pNtxBuffer = ( NTX_BUFFER * ) ntxPage;
for( i = 0; i < pNtxBuffer->item_count; i ++ )
{
pNtxItem = ( NTX_ITEM * ) ( ntxPage + pNtxBuffer->item_offset[ i ] );
if( pNtxItem->page )
ReadPage( hFileIn, pNtxItem->page, pCodeBlock, iKeySize );
hb_vmPushSymbol( &hb_symEval );
hb_vmPush( pCodeBlock );
hb_vmPushLong( pNtxItem->rec_no );
hb_vmPushString( ( char * ) &pNtxItem->key, iKeySize );
hb_vmFunction( 2 );
}
pNtxItem = ( NTX_ITEM * ) ( ntxPage + pNtxBuffer->item_offset[ pNtxBuffer->item_count ] );
if( pNtxItem->page )
ReadPage( hFileIn, pNtxItem->page, pCodeBlock, iKeySize );
}
HB_FUNC( SUBNTX )
{
NTX_HEADER ntx_header;
int hFileIn = hb_fsOpen( hb_parc( 1 ), FO_READ );
PHB_ITEM pCodeBlock = hb_param( 2, HB_IT_BLOCK );
if( hFileIn != -1 )
{
hb_fsRead( hFileIn, ( char * ) &ntx_header, sizeof( NTX_HEADER ) );
ReadPage( hFileIn, ntx_header.root, pCodeBlock, ntx_header.key_size );
hb_fsClose( hFileIn );
}
}
#pragma ENDDUMP
-
- Posts: 199
- Joined: Tue Apr 22, 2008 9:54 am
- Location: Valladolid, Spain.
Hecha Prueba!
Antonio,
He realizado pruebas con el código que has publicado... el resultado es, en la misma Dbf (2.600.000 registros), mismo índice, tarda en recorrerlo 56,27 segundos... sin pasar a bajo nivel, contra los 3,xx que tarda SubNtx().
Este tiempo es muy similar al que tarda si hacemos un índice en memoria (con la cláusula MEMORY, del INDEX ON).
Saludos!
He realizado pruebas con el código que has publicado... el resultado es, en la misma Dbf (2.600.000 registros), mismo índice, tarda en recorrerlo 56,27 segundos... sin pasar a bajo nivel, contra los 3,xx que tarda SubNtx().
Este tiempo es muy similar al que tarda si hacemos un índice en memoria (con la cláusula MEMORY, del INDEX ON).
Saludos!
- Antonio Linares
- Site Admin
- Posts: 37481
- Joined: Thu Oct 06, 2005 5:47 pm
- Location: Spain
- Contact:
-
- Posts: 199
- Joined: Tue Apr 22, 2008 9:54 am
- Location: Valladolid, Spain.
- Antonio Linares
- Site Admin
- Posts: 37481
- Joined: Thu Oct 06, 2005 5:47 pm
- Location: Spain
- Contact:
Re: SubNtx
David,
Prueba por favor _ a ver que velocidad conseguimos, gracias
Prueba por favor _ a ver que velocidad conseguimos, gracias
Code: Select all
#include "FiveWin.ch"
FIELD First, Last
function Main()
USE Customer VIA "DBFNTX"
INDEX ON First+Last TO Customer
SET INDEX TO
SubNtx( "customer.ntx", { | nRecNo, cKey | Test( nRecNo, cKey ) } )
return nil
function Test( nRecNo, cKey ) // En esta prueba solo vamos a mostrar las 10 primeras claves
static nTimes := 1
if nTimes < 11
MsgInfo( cKey, "Key: " + AllTrim( Str( nTimes++ ) ) + ;
" --> RecNo: " + AllTrim( Str( nRecNo ) ) )
endif
return nil
#pragma BEGINDUMP
#include <hbapi.h>
#include <hbapifs.h>
#include <hbvm.h>
#define MAX_KEY 256
#define BUF_SIZE 1024
typedef struct
{
unsigned short int type;
unsigned short int version;
long root;
long next_page;
unsigned short int item_size;
unsigned short int key_size;
unsigned short int key_dec;
unsigned short int max_item;
unsigned short int half_page;
char key_expr[ MAX_KEY ];
char unique;
} NTX_HEADER;
typedef struct
{
long page;
long rec_no;
char key[ 1 ];
} NTX_ITEM;
typedef struct
{
unsigned short item_count;
unsigned short item_offset[ 1 ];
} NTX_BUFFER;
static void ReadPage( int hFileIn, long page_offset, PHB_ITEM pCodeBlock, unsigned short int iKeySize )
{
char ntxPage[ BUF_SIZE ];
NTX_ITEM * pNtxItem;
NTX_BUFFER * pNtxBuffer;
int i;
hb_fsSeek( hFileIn, page_offset, FS_SET );
if( hb_fsRead( hFileIn, ntxPage, BUF_SIZE ) != BUF_SIZE )
return;
pNtxBuffer = ( NTX_BUFFER * ) ntxPage;
for( i = 0; i < pNtxBuffer->item_count; i ++ )
{
pNtxItem = ( NTX_ITEM * ) ( ntxPage + pNtxBuffer->item_offset[ i ] );
if( pNtxItem->page )
ReadPage( hFileIn, pNtxItem->page, pCodeBlock, iKeySize );
// hb_vmPushSymbol( &hb_symEval );
// hb_vmPush( pCodeBlock );
// hb_vmPushLong( pNtxItem->rec_no );
// hb_vmPushString( ( char * ) &pNtxItem->key, iKeySize );
// hb_vmFunction( 2 );
}
pNtxItem = ( NTX_ITEM * ) ( ntxPage + pNtxBuffer->item_offset[ pNtxBuffer->item_count ] );
if( pNtxItem->page )
ReadPage( hFileIn, pNtxItem->page, pCodeBlock, iKeySize );
}
HB_FUNC( SUBNTX )
{
NTX_HEADER ntx_header;
int hFileIn = hb_fsOpen( hb_parc( 1 ), FO_READ );
PHB_ITEM pCodeBlock = hb_param( 2, HB_IT_BLOCK );
if( hFileIn != -1 )
{
hb_fsRead( hFileIn, ( char * ) &ntx_header, sizeof( NTX_HEADER ) );
ReadPage( hFileIn, ntx_header.root, pCodeBlock, ntx_header.key_size );
hb_fsClose( hFileIn );
}
}
#pragma ENDDUMP