[fdo-commits] r2700 - in trunk/Providers/SDF/Src: Provider Utils
svn_fdo at osgeo.org
svn_fdo at osgeo.org
Tue Mar 20 13:08:01 EDT 2007
Author: badreddinekaroui
Date: 2007-03-20 13:08:00 -0400 (Tue, 20 Mar 2007)
New Revision: 2700
Modified:
trunk/Providers/SDF/Src/Provider/BinaryReader.cpp
trunk/Providers/SDF/Src/Provider/BinaryReader.h
trunk/Providers/SDF/Src/Provider/SdfDistinctDataReader.cpp
trunk/Providers/SDF/Src/Provider/SdfSimpleFeatureReader.cpp
trunk/Providers/SDF/Src/Utils/PropertyIndex.cpp
trunk/Providers/SDF/Src/Utils/PropertyIndex.h
Log:
See Ticket#47 http://trac.osgeo.org/fdo/ticket/47
Modified: trunk/Providers/SDF/Src/Provider/BinaryReader.cpp
===================================================================
--- trunk/Providers/SDF/Src/Provider/BinaryReader.cpp 2007-03-20 03:28:38 UTC (rev 2699)
+++ trunk/Providers/SDF/Src/Provider/BinaryReader.cpp 2007-03-20 17:08:00 UTC (rev 2700)
@@ -25,19 +25,27 @@
//uses 0 as default empty values.
const int ADD_TO_OFFSET = 1;
-BinaryReader::BinaryReader(unsigned char* data, int len)
+BinaryReader::BinaryReader(unsigned char* data, int len, int propCount )
{
- Init();
+ Init(propCount);
m_data = data;
m_len = len;
}
+BinaryReader::BinaryReader(unsigned char* data, int len )
+{
+ Init(SDF_STRING_CACHE_COUNT);
+ m_data = data;
+ m_len = len;
+
+}
+
BinaryReader::BinaryReader()
{
- Init();
+ Init(SDF_STRING_CACHE_COUNT);
}
-void BinaryReader::Init()
+void BinaryReader::Init( int propCount )
{
m_data = NULL;
m_len = 0;
@@ -45,16 +53,27 @@
m_wcsCacheLen = 0;
m_wcsCacheCurrent = 0;
m_wcsCache = NULL;
+ wcsCacheLastIndex = 0;
+ m_wcsStringCache = NULL;
+ wcsCacheLen = propCount;
+ m_wcsStringCache = new SdfStringCacheDef[propCount];
+ for(int i=0; i<propCount; i++ )
+ {
+ m_wcsStringCache[i].wcsLen = 0;
+ m_wcsStringCache[i].wcsString = NULL;
+ }
}
BinaryReader::~BinaryReader()
{
- //if we used extra string buffers, clear them
- if (!m_stringCaches.empty())
+ if( m_wcsStringCache != NULL )
{
- for (std::list<wchar_t*>::iterator iter=m_stringCaches.begin();
- iter != m_stringCaches.end(); iter++)
- delete [] (*iter);
+ for(int i=0; i<wcsCacheLen; i++ )
+ {
+ if( m_wcsStringCache[i].wcsString != NULL )
+ delete[] m_wcsStringCache[i].wcsString;
+ }
+ delete[] m_wcsStringCache;
}
if (m_wcsCache)
@@ -63,25 +82,16 @@
void BinaryReader::Reset(unsigned char* data, int len)
{
+
m_data = data;
m_len = len;
m_pos = 0;
m_wcsCacheCurrent = 0;
-
- if (!(m_wcsCachedStrings).empty())
- {
- (m_wcsCachedStrings).clear();
- }
- //if we used extra string buffers, clear them
- //and only reuse the last one (pointed to by m_wcsCache)
- if (!m_stringCaches.empty())
+ for(int i=0; i<wcsCacheLen; i++ )
{
- for (std::list<wchar_t*>::iterator iter=m_stringCaches.begin();
- iter != m_stringCaches.end(); iter++)
- delete [] (*iter);
-
- m_stringCaches.clear();
+ if( m_wcsStringCache[i].wcsString != NULL )
+ m_wcsStringCache[i].wcsString[0] = '\0';
}
}
@@ -206,75 +216,71 @@
return ReadRawString(mbstrlen);
}
+const wchar_t* BinaryReader::ReadRawString( unsigned mbstrlen, int index )
+{
+ if( mbstrlen <= 1 )
+ {
+ m_pos += mbstrlen;
+ return L"";
+ }
+ if( index >= wcsCacheLen )
+ return ReadRawString( mbstrlen );
-const wchar_t* BinaryReader::ReadRawString(unsigned mbstrlen)
-{
-
- //check if we have read this string already (it will be cached)
- wchar_t* thestring = (m_wcsCachedStrings)[m_pos];
- if (thestring != NULL)
- {
- m_pos += mbstrlen;
- return thestring;
- }
+ if( m_wcsStringCache[index].wcsString != NULL && m_wcsStringCache[index].wcsString[0] != '\0' )
+ {
+ m_pos += mbstrlen;
+ wcsCacheLastIndex = index;
+ return m_wcsStringCache[index].wcsString;
+ }
- //make sure wchar_t cache size is big enough
- if (m_wcsCacheLen - m_wcsCacheCurrent < mbstrlen + 1)
+ if( mbstrlen > m_wcsStringCache[index].wcsLen )
{
- //pick size -- minimum size is STRING_BUFFER_SIZE
- m_wcsCacheLen = max(STRING_CACHE_SIZE, m_wcsCacheCurrent + mbstrlen + 1);
- wchar_t* tmp = new wchar_t[m_wcsCacheLen];
+ if( NULL != m_wcsStringCache[index].wcsString )
+ delete[] m_wcsStringCache[index].wcsString;
- if (m_wcsCache)
- {
- //if we already had a buffer, keep track of it
- //in the list, but set the new current buffer
- //to the newly allocated one
- m_stringCaches.push_back(m_wcsCache);
- m_wcsCache = tmp;
- }
- else
- {
- //otherwise just keep track of cache buffer pointer
- m_wcsCache = tmp;
- }
+ m_wcsStringCache[index].wcsString = new wchar_t[mbstrlen+1];
+ m_wcsStringCache[index].wcsLen = mbstrlen;
}
+ int count = ut_utf8_to_unicode((char*)(m_data + m_pos), mbstrlen, m_wcsStringCache[index].wcsString, mbstrlen);
- //handle empty string
- if (mbstrlen <= 1)
+ _ASSERT(count > 0 && (unsigned int)count < mbstrlen);
+
+ m_pos += mbstrlen;
+ wcsCacheLastIndex = index;
+ return m_wcsStringCache[index].wcsString;
+}
+
+//
+// Should only be called from internal code that does not require the returned
+// string to stay around until the next reset. It uses a circular buffer of
+// SDF_STRING_CACHE_COUNT elements and the individual elements may get overwriten before the reset.
+// The Fdo requirement for feature reader is that string stays around untill the next ReadNext.
+const wchar_t* BinaryReader::ReadRawString(unsigned mbstrlen)
+{
+ if( mbstrlen <= 1 )
{
- m_wcsCache[m_wcsCacheCurrent] = 0;
- (m_wcsCachedStrings)[m_pos] = m_wcsCache + m_wcsCacheCurrent;
- m_wcsCacheCurrent += 1;
-
- //skip past null character
m_pos += mbstrlen;
+ return L"";
+ }
+ if( (++wcsCacheLastIndex) >= wcsCacheLen )
+ wcsCacheLastIndex = 0;
- return m_wcsCache + m_wcsCacheCurrent - 1;
+ if( mbstrlen > m_wcsStringCache[wcsCacheLastIndex].wcsLen )
+ {
+ if( NULL != m_wcsStringCache[wcsCacheLastIndex].wcsString )
+ delete[] m_wcsStringCache[wcsCacheLastIndex].wcsString;
+
+ m_wcsStringCache[wcsCacheLastIndex].wcsString = new wchar_t[mbstrlen+1];
+ m_wcsStringCache[wcsCacheLastIndex].wcsLen = mbstrlen;
}
-
- //Note: we pass in m_len as number of characters to read, but we know
- //the string must be null terminated, so the function will terminate before that
- int count = ut_utf8_to_unicode((char*)(m_data + m_pos), mbstrlen, m_wcsCache + m_wcsCacheCurrent, mbstrlen);
+ int count = ut_utf8_to_unicode((char*)(m_data + m_pos), mbstrlen, m_wcsStringCache[wcsCacheLastIndex].wcsString, mbstrlen);
_ASSERT(count > 0 && (unsigned int)count < mbstrlen);
- //remember offset of current string
- unsigned offset = m_wcsCacheCurrent;
- (m_wcsCachedStrings)[m_pos] = m_wcsCache + offset;
-
- //increment position count to position after string
- //note that "count" is the number of unicode characters
- //read, not the number of bytes we need to increment.
- m_pos += mbstrlen;
-
- //remember where to put next string that we read
- m_wcsCacheCurrent += (int)wcslen(m_wcsCache + m_wcsCacheCurrent) + 1;
-
- return m_wcsCache + offset;
+ m_pos += mbstrlen;
+ return m_wcsStringCache[wcsCacheLastIndex].wcsString;
}
-
//deserializes a FdoDateTime
FdoDateTime BinaryReader::ReadDateTime()
{
@@ -420,7 +426,7 @@
delete[] m_wcsCache;
m_wcsCache = NULL;
//pick size -- minimum size is STRING_BUFFER_SIZE
- m_wcsCacheLen = max(STRING_CACHE_SIZE, mbstrlen + 1);
+ m_wcsCacheLen = max(SDF_STRING_CACHE_SIZE, mbstrlen + 1);
m_wcsCache = new wchar_t[m_wcsCacheLen];
}
Modified: trunk/Providers/SDF/Src/Provider/BinaryReader.h
===================================================================
--- trunk/Providers/SDF/Src/Provider/BinaryReader.h 2007-03-20 03:28:38 UTC (rev 2699)
+++ trunk/Providers/SDF/Src/Provider/BinaryReader.h 2007-03-20 17:08:00 UTC (rev 2700)
@@ -30,16 +30,19 @@
//if we need bigger, either a new buffer will be allocated or a
//the bigger size will be used if it is the first buffer we
//create
-#define STRING_CACHE_SIZE 256
+#define SDF_STRING_CACHE_SIZE 256
+#define SDF_STRING_CACHE_COUNT 10
+
class BinaryReader
{
public:
- BinaryReader(unsigned char* data, int len);
+ BinaryReader(unsigned char* data, int len );
+ BinaryReader(unsigned char* data, int len, int propCount );
BinaryReader();
virtual ~BinaryReader();
- void Init();
+ void Init( int propCount );
void Reset(unsigned char* data, int len);
void SetPosition(int offset);
int GetPosition();
@@ -57,6 +60,7 @@
char ReadChar();
const wchar_t* ReadString();
const wchar_t* ReadRawString(unsigned mbstrlen);
+ const wchar_t* ReadRawString(unsigned mbstrlen, int index);
const wchar_t* ReadRawStringNoCache(unsigned mbstrlen);
FdoDateTime ReadDateTime();
FdoDataValue* ReadDataValue();
@@ -71,17 +75,19 @@
//current unicode string buffer
wchar_t* m_wcsCache;
unsigned m_wcsCacheCurrent;
- unsigned m_wcsCacheLen;
+ unsigned m_wcsCacheLen;
-
- //maps offset of a string in the data record to an
- //offset of the unicode representation in the m_wcsCache
- stdext::hash_map<int, wchar_t*> m_wcsCachedStrings;
-
- //since we cannot invalidate pointers to strings we have returned
+ //since we cannot invalidate pointers to strings we have returned
//we need to keep all previous caches valid until we are reset or
//destroyed.
- std::list<wchar_t*> m_stringCaches;
+ typedef struct _wcsStringCache {
+ wchar_t* wcsString;
+ unsigned int wcsLen;
+ } SdfStringCacheDef;
+
+ SdfStringCacheDef *m_wcsStringCache;
+ unsigned int wcsCacheLen;
+ unsigned int wcsCacheLastIndex;
};
#endif
Modified: trunk/Providers/SDF/Src/Provider/SdfDistinctDataReader.cpp
===================================================================
--- trunk/Providers/SDF/Src/Provider/SdfDistinctDataReader.cpp 2007-03-20 03:28:38 UTC (rev 2699)
+++ trunk/Providers/SDF/Src/Provider/SdfDistinctDataReader.cpp 2007-03-20 17:08:00 UTC (rev 2700)
@@ -55,7 +55,7 @@
_ASSERT(ret == 0);
- m_binReader = new BinaryReader(NULL, 0);
+ m_binReader = new BinaryReader(NULL, 0, m_propIndex->GetNumProps() );
m_currentKey = new SQLiteData();
Modified: trunk/Providers/SDF/Src/Provider/SdfSimpleFeatureReader.cpp
===================================================================
--- trunk/Providers/SDF/Src/Provider/SdfSimpleFeatureReader.cpp 2007-03-20 03:28:38 UTC (rev 2699)
+++ trunk/Providers/SDF/Src/Provider/SdfSimpleFeatureReader.cpp 2007-03-20 17:08:00 UTC (rev 2700)
@@ -74,7 +74,7 @@
//this prop index stays fixed
m_basePropIndex = m_propIndex;
- m_dataReader = new BinaryReader(NULL, 0);
+ m_dataReader = new BinaryReader(NULL, 0, m_propIndex->GetNumProps() );
if (m_filter)
{
@@ -129,7 +129,7 @@
m_filterExec = FilterExecutor::Create(this, m_propIndex, NULL, m_class);
- m_dataReader = new BinaryReader(NULL, 0);
+ m_dataReader = new BinaryReader(NULL, 0, m_propIndex->GetNumProps() );
m_currentFeatureRecno = reader.m_currentFeatureRecno;
@@ -535,7 +535,7 @@
//returns a pointer to the BinaryReader string cache memory
//the pointer is valid until the next call to ReadNext(), when
//the binary reader is reset
- FdoString* st = m_dataReader->ReadRawString(len);
+ FdoString* st = m_dataReader->ReadRawString(len, ps->m_recordIndex );
return st;
}
@@ -739,7 +739,7 @@
break; // Just bail out. The association is not set therefore no associted objects exist
if( idProp->GetDataType() == FdoDataType_String )
- val = FdoStringValue::Create( m_dataReader->ReadRawString( len ) ); // Need to use the raw string getter
+ val = FdoStringValue::Create( m_dataReader->ReadRawString( len, ps->m_recordIndex ) ); // Need to use the raw string getter
else
val = GetValue( idProp->GetDataType() );
}
@@ -765,7 +765,7 @@
break; // Should not happen as it's the primary key of the object; it must exist
if( idProp->GetDataType() == FdoDataType_String )
- val = FdoStringValue::Create( m_dataReader->ReadRawString( len ) ); // Need to use the raw string getter
+ val = FdoStringValue::Create( m_dataReader->ReadRawString( len, ps->m_recordIndex ) ); // Need to use the raw string getter
else
val = GetValue( idProp->GetDataType() );
}
Modified: trunk/Providers/SDF/Src/Utils/PropertyIndex.cpp
===================================================================
--- trunk/Providers/SDF/Src/Utils/PropertyIndex.cpp 2007-03-20 03:28:38 UTC (rev 2699)
+++ trunk/Providers/SDF/Src/Utils/PropertyIndex.cpp 2007-03-20 17:08:00 UTC (rev 2700)
@@ -31,7 +31,7 @@
m_numProps = bpdc->GetCount() + pdc->GetCount();
m_vProps = new PropertyStub[m_numProps];
-
+ m_lastIndex = 0;
int index = 0;
//now iterate over inherited properties
@@ -125,14 +125,27 @@
//search for the correct PropertyStub -- iterate linearly
//since we have relatively few properties. Using a hash_map
//was slow for this
- for (int i=0; i<m_numProps; i++)
+ for (int i=m_lastIndex; i<m_numProps; i++)
{
ps = &m_vProps[i];
if (wcscmp((wchar_t*)name, ps->m_name) == 0)
+ {
+ m_lastIndex = i;
return ps;
+ }
}
+ for (int i=0; i<m_lastIndex; i++)
+ {
+ ps = &m_vProps[i];
+ if (wcscmp((wchar_t*)name, ps->m_name) == 0)
+ {
+ m_lastIndex = i;
+ return ps;
+ }
+ }
+
return NULL;
}
Modified: trunk/Providers/SDF/Src/Utils/PropertyIndex.h
===================================================================
--- trunk/Providers/SDF/Src/Utils/PropertyIndex.h 2007-03-20 03:28:38 UTC (rev 2699)
+++ trunk/Providers/SDF/Src/Utils/PropertyIndex.h 2007-03-20 17:08:00 UTC (rev 2700)
@@ -65,6 +65,7 @@
PropertyIndex(){};
int m_numProps;
+ int m_lastIndex;
PropertyStub* m_vProps;
FdoClassDefinition* m_baseClass;
FdoFeatureClass* m_baseFeatureClass;
More information about the fdo-commits
mailing list