FiveTech Support Forums

FiveWin / Harbour / xBase community
Board index FiveWin para Harbour/xHarbour SubNtx
Posts: 44158
Joined: Thu Oct 06, 2005 05:47 PM
SubNtx
Posted: Thu Sep 11, 2008 04:15 PM

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
Posts: 44158
Joined: Thu Oct 06, 2005 05:47 PM
SubNtx
Posted: Thu Sep 11, 2008 04:18 PM

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
Posts: 682
Joined: Tue Feb 14, 2006 09:48 AM
SubNtx
Posted: Thu Sep 11, 2008 05:18 PM
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/
Posts: 189
Joined: Sun Jul 08, 2007 01:46 AM
SubNtx
Posted: Thu Sep 11, 2008 08:37 PM

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

Posts: 44158
Joined: Thu Oct 06, 2005 05:47 PM
SubNtx
Posted: Thu Sep 11, 2008 09:19 PM

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
Posts: 199
Joined: Tue Apr 22, 2008 09:54 AM
SubNtx
Posted: Fri Sep 12, 2008 07:26 AM
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!
Posts: 199
Joined: Tue Apr 22, 2008 09:54 AM
OrdWildSeek()
Posted: Fri Sep 12, 2008 09:55 AM

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!

Posts: 44158
Joined: Thu Oct 06, 2005 05:47 PM
SubNtx
Posted: Fri Sep 12, 2008 02:12 PM

David,

gracias por la información! :-)

regards, saludos

Antonio Linares
www.fivetechsoft.com
Posts: 330
Joined: Fri May 25, 2007 09:06 PM
SubNtx
Posted: Wed Sep 17, 2008 02:40 AM

y este temaso en que quedo.. por lo que entendi NTX sigue penando a los CDX,,,

Posts: 44158
Joined: Thu Oct 06, 2005 05:47 PM
SubNtx
Posted: Wed Sep 17, 2008 06:36 AM

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
Posts: 44158
Joined: Thu Oct 06, 2005 05:47 PM
SubNtx
Posted: Wed Sep 17, 2008 10:29 AM
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
#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
Posts: 199
Joined: Tue Apr 22, 2008 09:54 AM
Hecha Prueba!
Posted: Mon Sep 22, 2008 04:15 PM

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!

Posts: 44158
Joined: Thu Oct 06, 2005 05:47 PM
SubNtx
Posted: Mon Sep 22, 2008 07:35 PM

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
Posts: 199
Joined: Tue Apr 22, 2008 09:54 AM
SubNtx
Posted: Tue Sep 23, 2008 09:48 AM

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!

Posts: 44158
Joined: Thu Oct 06, 2005 05:47 PM
Re: SubNtx
Posted: Thu Dec 02, 2010 01:13 AM
David,

Prueba por favor estos cambios a ver que velocidad conseguimos, gracias :-)

Code (fw): Select all Collapse
#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