SubNtx

User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Post by Antonio Linares »

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 :-)
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Post by Antonio Linares »

Biel,

Gracias por ese código. A ver si conseguimos localizar cual es el sistema más rápido :-)
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Biel EA6DD
Posts: 680
Joined: Tue Feb 14, 2006 9:48 am
Location: Mallorca
Contact:

Post by Biel EA6DD »

Kleyber wrote:Biel,

No seria la función OrdWildSeek() de xHarbour, para CDX?

Saludos,
Pues si, parece que si seria esa la funcion.
Saludos desde Mallorca
Biel Maimó
http://bielsys.blogspot.com/
Ruben D. Fernandez
Posts: 189
Joined: Sun Jul 08, 2007 1:46 am
Location: Uruguay

Post by Ruben D. Fernandez »

Antonio:

Me da error open error Customer.ntx

Solo tengo 2 archivos cuando abro tu .rar
Un archivo .c y un archivo .exe

Gracias


Ruben Fernandez
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Post by Antonio Linares »

Ruben,

Prueba a abrir customer.ntx desde Harbour, usando FOpen( "customer.ntx" ), a ver que valor te devuelve.
regards, saludos

Antonio Linares
www.fivetechsoft.com
triumvirato
Posts: 199
Joined: Tue Apr 22, 2008 9:54 am
Location: Valladolid, Spain.

Post by triumvirato »

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 :-)
Estoy en ello, pero OrdWildSeek() sólo trabaja con CDX si no me equivoco, generaré el índice en CDX.

Por cierto, la versión de la rutina sin malloc() y sin free(), no es que vuele, es que vuela a reación...

Saludos!
triumvirato
Posts: 199
Joined: Tue Apr 22, 2008 9:54 am
Location: Valladolid, Spain.

OrdWildSeek()

Post by triumvirato »

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!
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Post by Antonio Linares »

David,

gracias por la información! :-)
regards, saludos

Antonio Linares
www.fivetechsoft.com
mantonio_08
Posts: 330
Joined: Fri May 25, 2007 9:06 pm

Post by mantonio_08 »

y este temaso en que quedo.. por lo que entendi NTX sigue penando a los CDX,,,
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Post by Antonio Linares »

Vamos a publicar un SubNtx 32 bits gratuito para Harbour/xHarbour.

Y quien sabe si podremos hacer un SubCdx tambien :-)
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Post by Antonio Linares »

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

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
regards, saludos

Antonio Linares
www.fivetechsoft.com
triumvirato
Posts: 199
Joined: Tue Apr 22, 2008 9:54 am
Location: Valladolid, Spain.

Hecha Prueba!

Post by triumvirato »

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!
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Post by Antonio Linares »

David,

gracias por las pruebas :-)

Queda claro que no hay que subir a alto nivel (acceder a la maquina virtual) para nada, si queremos ser tan rápidos como el SubNtx original
regards, saludos

Antonio Linares
www.fivetechsoft.com
triumvirato
Posts: 199
Joined: Tue Apr 22, 2008 9:54 am
Location: Valladolid, Spain.

Post by triumvirato »

Antonio,

Pues parece que sí, que habrá que pasar a bajo nivel, con los inconvenientes que ello conlleva, salvo que alguien dé más luz sobre este asunto... :roll:

Saludos!
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Re: SubNtx

Post by Antonio Linares »

David,

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
 
regards, saludos

Antonio Linares
www.fivetechsoft.com
Post Reply