add option when memory's available for dict to store all of its data

in a single FtrPtr so that lookup can be faster.  Still need to
confirm that there's a noticable speedup this way....
This commit is contained in:
ehouse 2004-10-07 13:23:20 +00:00
parent b804927e1a
commit 698c71fc06
4 changed files with 124 additions and 44 deletions

View file

@ -459,9 +459,8 @@ make_stubbed_dict( MPFORMAL_NOCOMMA )
#endif /* STUBBED_DICT */
#ifndef OVERRIDE_EDGE_FOR_INDEX
array_edge*
dict_edge_for_index( DictionaryCtxt* dict, XP_U32 index )
static array_edge*
dict_super_edge_for_index( DictionaryCtxt* dict, XP_U32 index )
{
array_edge* result;
@ -470,15 +469,34 @@ dict_edge_for_index( DictionaryCtxt* dict, XP_U32 index )
} else {
XP_ASSERT( index < dict->numEdges );
#ifdef NODE_CAN_4
index *= dict->nodeSize;
/* avoid long-multiplication lib call on Palm... */
if ( dict->nodeSize == 3 ) {
index += (index << 1);
} else {
XP_ASSERT( dict->nodeSize == 4 );
index <<= 2;
}
#else
index *= 3;
index += (index << 1);
#endif
result = &dict->base[index];
}
return result;
} /* dict_edge_for_index */
#endif
static array_edge*
dict_super_getTopEdge( DictionaryCtxt* dict )
{
return dict->topEdge;
} /* dict_super_getTopEdge */
void
dict_super_init( DictionaryCtxt* ctxt )
{
/* subclass may change these later.... */
ctxt->func_edge_for_index = dict_super_edge_for_index;
ctxt->func_dict_getTopEdge = dict_super_getTopEdge;
} /* dict_super_init */
#ifdef CPLUS
}

View file

@ -57,6 +57,10 @@ typedef struct SpecialBitmaps {
struct DictionaryCtxt {
void (*destructor)( DictionaryCtxt* dict );
array_edge* (*func_edge_for_index)( DictionaryCtxt* dict, XP_U32 index );
array_edge* (*func_dict_getTopEdge)( DictionaryCtxt* dict );
array_edge* topEdge;
array_edge* base; /* the physical beginning of the dictionary; not
necessarily the entry point for search!! */
@ -107,6 +111,9 @@ struct DictionaryCtxt {
/* #define dict_numTileFaces(dc) (dc)->vtable->m_numTileFaces(dc) */
#define dict_destroy(d) (*((d)->destructor))(d)
#define dict_edge_for_index(d, i) (*((d)->func_edge_for_index))((d), (i))
#define dict_getTopEdge(d) (*((d)->func_dict_getTopEdge))(d)
XP_Bool dict_tilesAreSame( DictionaryCtxt* dict1, DictionaryCtxt* dict2 );
@ -133,20 +140,14 @@ void dict_loadFromStream( DictionaryCtxt* dict, XWStreamCtxt* stream );
/* These methods get "overridden" by subclasses. That is, they must be
implemented by each platform. */
array_edge* dict_edge_for_index( DictionaryCtxt* dict, XP_U32 index );
#ifdef OVERRIDE_GETTOPEDGE
/* platform code will implement this */
array_edge* dict_getTopEdge( DictionaryCtxt* dict );
#else
# define dict_getTopEdge( dict ) ((dict)->topEdge)
#endif
#ifdef STUBBED_DICT
DictionaryCtxt* make_stubbed_dict( MPFORMAL_NOCOMMA );
#endif
/* To be called only by subclasses!!! */
void dict_super_init( DictionaryCtxt* ctxt );
#ifdef CPLUS
}
#endif

View file

@ -20,6 +20,7 @@
#include <PalmTypes.h>
#include <DataMgr.h>
#include <VFSMgr.h>
#include <FeatureMgr.h>
#include "dictnryp.h"
#include "dawg.h"
@ -60,6 +61,8 @@ static void palm_dictionary_destroy( DictionaryCtxt* dict );
static XP_U16 countSpecials( FaceType* ptr, UInt16 nChars );
static void setupSpecials( MPFORMAL PalmDictionaryCtxt* ctxt,
Xloc_specialEntry* specialStart, XP_U16 nSpecials );
static array_edge* palm_dict_edge_for_index_multi( DictionaryCtxt* dict,
XP_U32 index );
DictionaryCtxt*
palm_dictionary_make( MPFORMAL XP_UCHAR* dictName, PalmDictList* dl )
@ -74,7 +77,7 @@ palm_dictionary_make( MPFORMAL XP_UCHAR* dictName, PalmDictList* dl )
dawg_header* headerRecP;
unsigned char* charPtr;
UInt16 nChars, nSpecials;
unsigned long offset = 0;
XP_U32 offset;
DictListEntry* dle;
Err err;
XP_U16 i;
@ -83,6 +86,8 @@ palm_dictionary_make( MPFORMAL XP_UCHAR* dictName, PalmDictList* dl )
XP_U16 flags;
XP_U16 nodeSize = 3; /* init to satisfy compiler */
#endif
XP_U32 totalSize;
void* dawgBase;
/* check and see if there's already a dict for this name. If yes,
increment its refcount and return. */
@ -105,6 +110,8 @@ palm_dictionary_make( MPFORMAL XP_UCHAR* dictName, PalmDictList* dl )
XP_MEMSET( ctxt, 0, sizeof(*ctxt) );
MPASSIGN( ctxt->super.mpool, mpool );
dict_super_init( (DictionaryCtxt*)ctxt );
if ( !!dictName ) {
XP_ASSERT( XP_STRLEN((const char*)dictName) > 0 );
@ -188,6 +195,8 @@ palm_dictionary_make( MPFORMAL XP_UCHAR* dictName, PalmDictList* dl )
ctxt->super.topEdge = NULL;
ctxt->nRecords = 0;
} else {
MemHandle record;
XP_U16 size;
short index;
XP_U16 nRecords;
@ -203,34 +212,78 @@ palm_dictionary_make( MPFORMAL XP_UCHAR* dictName, PalmDictList* dl )
ctxt->super.is_4_byte = nodeSize == 4;
#endif
totalSize = 0;
for ( index = 0; index < nRecords; ++index ) {
MemHandle record =
DmQueryRecord( dbRef, index + headerRecP->firstEdgeRecNum);
ctxt->dictStarts[index].indexStart = offset;
/* cast to short to avoid libc call */
XP_ASSERT( MemHandleSize(record) < 0xFFFF );
#ifdef NODE_CAN_4
XP_ASSERT( 0 == ((unsigned short)(MemHandleSize(record))
% nodeSize ));
offset += ((unsigned short)MemHandleSize(record))
/ nodeSize;
#else
XP_ASSERT( ((unsigned short)(MemHandleSize(record)) % 3 )==0);
offset += ((unsigned short)MemHandleSize(record)) / 3;
#endif
ctxt->dictStarts[index].array =
(array_edge*)MemHandleLock( record );
XP_ASSERT( MemHandleLockCount(record) == 1 );
record = DmQueryRecord( dbRef, index
+ headerRecP->firstEdgeRecNum);
totalSize += MemHandleSize( record );
}
XP_ASSERT( index == ctxt->nRecords );
ctxt->dictStarts[index].indexStart = 0xFFFFFFFFL;
ctxt->super.topEdge = ctxt->dictStarts[0].array;
/* NOTE: need to use more than one feature to support having
multiple dicts open at once. */
err = ~errNone; /* so test below will pass if nRecords == 1 */
if ( 0 && nRecords > 1 ) {
err = FtrPtrNew( APPID, DAWG_STORE_FEATURE, totalSize,
&dawgBase );
if ( err == errNone ) {
for ( index = 0, offset = 0; index < nRecords; ++index ) {
record = DmQueryRecord( dbRef, index
+ headerRecP->firstEdgeRecNum );
size = MemHandleSize( record );
XP_LOGF( "size=%d", size );
err = DmWrite( dawgBase, offset,
MemHandleLock( record ), size );
XP_ASSERT( err == errNone );
MemHandleUnlock( record );
offset += size;
XP_LOGF( "offset now = %ld", offset );
#ifdef DEBUG
ctxt->super.numEdges = offset;
#ifdef NODE_CAN_4
ctxt->super.numEdges += size / nodeSize;
#else
ctxt->super.numEdges += size / 3;
#endif
#endif
}
ctxt->super.base = dawgBase;
ctxt->super.topEdge = dawgBase;
} else {
XP_LOGF( "unable to use Ftr for dict; err=%d", err );
}
}
if ( err != errNone ) {
offset = 0;
for ( index = 0; index < nRecords; ++index ) {
record = DmQueryRecord( dbRef, index + headerRecP->firstEdgeRecNum );
size = MemHandleSize( record );
ctxt->dictStarts[index].indexStart = offset;
/* cast to short to avoid libc call */
XP_ASSERT( size < 0xFFFF );
#ifdef NODE_CAN_4
XP_ASSERT( 0 == (size % nodeSize) );
offset += size / nodeSize;
#else
XP_ASSERT( ((unsigned short)size % 3 )==0);
offset += ((unsigned short)size) / 3;
#endif
ctxt->dictStarts[index].array =
(array_edge*)MemHandleLock( record );
XP_ASSERT( MemHandleLockCount(record) == 1 );
}
XP_ASSERT( index == ctxt->nRecords );
ctxt->dictStarts[index].indexStart = 0xFFFFFFFFL;
ctxt->super.topEdge = ctxt->dictStarts[0].array;
#ifdef DEBUG
ctxt->super.numEdges = offset;
#endif
ctxt->super.func_edge_for_index = palm_dict_edge_for_index_multi;
}
}
setBlankTile( (DictionaryCtxt*)ctxt );
@ -330,8 +383,14 @@ palm_dictionary_destroy( DictionaryCtxt* dict )
XP_FREE( dict->mpool, ctxt->super.faces16 );
for ( i = 0; i < ctxt->nRecords; ++i ) {
MemPtrUnlock( ctxt->dictStarts[i].array );
/* Try first to delete the feature. */
if ( FtrPtrFree( APPID, DAWG_STORE_FEATURE ) == ftrErrNoSuchFeature ) {
for ( i = 0; i < ctxt->nRecords; ++i ) {
XP_ASSERT( !!ctxt->dictStarts[i].array );
MemPtrUnlock( ctxt->dictStarts[i].array );
}
} else {
XP_ASSERT( ctxt->dictStarts[0].array == NULL );
}
MemPtrUnlock( headerRecP );
@ -359,8 +418,8 @@ palm_dictionary_destroy( DictionaryCtxt* dict )
} /* palm_dictionary_destroy */
#ifdef OVERRIDE_EDGE_FOR_INDEX
array_edge*
dict_edge_for_index( DictionaryCtxt* dict, XP_U32 index )
static array_edge*
palm_dict_edge_for_index_multi( DictionaryCtxt* dict, XP_U32 index )
{
PalmDictionaryCtxt* ctxt = (PalmDictionaryCtxt*)dict;
array_edge* result;
@ -397,4 +456,5 @@ dict_edge_for_index( DictionaryCtxt* dict, XP_U32 index )
return result;
} /* dict_edge_for_index */
#endif

View file

@ -336,6 +336,7 @@ enum {
, GLOBALS_FEATURE /* for passing globals to form handlers */
, FEATURE_WANTS_68K /* support for (pre-ship) ability to choose
armlet or 68K */
, DAWG_STORE_FEATURE
};
enum { WANTS_68K, WANTS_ARM };