[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