Changeset 422


Ignore:
Timestamp:
07/16/15 19:22:35 (10 years ago)
Author:
epyon
Message:
  • stream and file_system moved to stl
  • hash literal operator
  • string table rewrite
Location:
trunk
Files:
7 edited
2 moved

Legend:

Unmodified
Added
Removed
  • trunk/nv/formats/assimp_loader.hh

    r416 r422  
    3737                void create_keys( mesh_node_data* data, const void* vnode );
    3838
    39                 string_table_creator m_strings;
     39                string_table* m_strings;
    4040                std::string m_ext;
    4141                uint32 m_assimp_flags;
  • trunk/nv/io/c_file_system.hh

    r395 r422  
    1515
    1616#include <nv/common.hh>
    17 #include <nv/interface/file_system.hh>
     17#include <nv/stl/file_system.hh>
    1818
    1919namespace nv
  • trunk/nv/io/c_stream.hh

    r395 r422  
    1515
    1616#include <nv/common.hh>
    17 #include <nv/interface/stream.hh>
     17#include <nv/stl/stream.hh>
    1818
    1919namespace nv
  • trunk/nv/io/std_stream.hh

    r395 r422  
    1515
    1616#include <nv/common.hh>
    17 #include <nv/interface/stream.hh>
     17#include <nv/stl/stream.hh>
    1818#include <streambuf>
    1919#include <istream>
  • trunk/nv/io/string_table.hh

    r421 r422  
    1717#include <nv/stl/string.hh>
    1818#include <nv/stl/unordered_map.hh>
    19 #include <nv/interface/stream.hh>
     19#include <nv/stl/stream.hh>
    2020
    2121namespace nv
    2222{
     23
    2324        class string_table : noncopyable
    2425        {
    2526        public:
    26                 typedef uint16 index;
    27                 typedef uint32 offset;
     27                typedef string_view value_type;
     28                typedef uint64 key_type;
     29                typedef uint64 hash_type;
     30                typedef uint32 size_type;
     31                typedef uint16 length_type;
     32                typedef unordered_map< key_type, size_type > indexer_type;
     33                typedef vector< char > storage_type;
     34                typedef indexer_type::const_iterator const_iterator;
    2835
    29                 string_table( char* data, uint32 size, offset* offsets, index count )
    30                         : m_data( data ), m_size( size ), m_offsets( offsets ), m_count( count )
     36                string_table() {}
     37                string_table( stream& in );
     38                void insert( string_table* in );
     39                key_type insert( const value_type& str )
    3140                {
    32 
    33                 }
    34                 explicit string_table( nv::stream* in )
    35                 {
    36                         load( in );
     41                        key_type hash_value = str.get_hash< uint64 >();
     42                        insert( hash_value, str );
     43                        return hash_value;
    3744                }
    3845
    39                 const char* get( index i ) const
     46                bool exists( key_type i ) const
    4047                {
    41                         return i < m_count ? m_data + m_offsets[i] : nullptr;
     48                        return m_map.find( i ) != m_map.end();
    4249                }
    4350
    44                 void dump( nv::stream* out ) const
     51                value_type at( key_type i ) const
    4552                {
    46                         out->write( &m_count,  sizeof( m_count ), 1 );
    47                         out->write( &m_size,   sizeof( m_size ), 1 );
    48                         out->write( m_offsets, sizeof( offset ), m_count );
    49                         out->write( m_data,    sizeof( char ), m_size );
     53                        const auto& it = m_map.find( i );
     54                        NV_ASSERT_ALWAYS( it != m_map.end(), "Key not found in string_table!" );
     55                        return extract_raw( it->second );
    5056                }
    5157
    52                 ~string_table()
     58                value_type operator[]( key_type i ) const
    5359                {
    54                         delete[] m_data;
    55                         delete[] m_offsets;
    56                 }
    57         private:
    58                 void load( stream* in )
    59                 {
    60                         in->read( &m_count, sizeof( m_count ), 1 );
    61                         in->read( &m_size, sizeof( m_size ), 1 );
    62                         m_offsets = new offset[ m_count ];
    63                         m_data    = new char[ m_size ];
    64                         in->read( m_offsets, sizeof( offset ), m_count );
    65                         in->read( m_data,    sizeof( char ), m_size );
     60                        const auto& it = m_map.find( i );
     61                        return it != m_map.end() ? extract_raw( it->second ) : value_type();
    6662                }
    6763
    68                 char*   m_data;
    69                 uint32  m_size;
    70                 offset* m_offsets;
    71                 index   m_count;
     64                uint32 dump_size() const;
     65                void dump( stream& out ) const;
     66        protected:
     67                void insert( hash_type h, const value_type& str )
     68                {
     69                        NV_ASSERT_ALWAYS( str.size() < 0xFFF0, "String table can only hold strings up to 64k!" );
     70                        auto it = m_map.find( h );
     71                        if ( it != m_map.end() )
     72                        {
     73                                // TODO : perform comparison check if in debug mode!
     74                                return;
     75                        }
     76                        insert_raw( h, str.data(), static_cast<length_type>( str.size() ) );
     77                }
     78
     79
     80                size_type insert_raw( hash_type h, const char* str, length_type s );
     81
     82                value_type extract_raw( size_type index ) const
     83                {
     84                        uint16 length = *reinterpret_cast<const uint16*>( m_data.data() + index );
     85                        return value_type( m_data.data() + index + 2, length );
     86                }
     87
     88                indexer_type m_map;
     89                storage_type m_data;
    7290        };
    73 
    74         class string_table_creator
    75         {
    76         public:
    77                 typedef string_table::index  index;
    78                 typedef string_table::offset offset;
    79 
    80                 string_table_creator();
    81                 index insert( const string_view& s );
    82                 string_table* create_table() const;
    83                 uint32 dump_size() const;
    84                 void dump( nv::stream* out ) const;
    85                 const char* get( index i ) const;
    86                 index get( const string_view& s ) const;
    87                 void clear();
    88         private:
    89                 unordered_map< uint64, index > m_map;
    90                 vector< offset > m_offsets;
    91                 vector< char >   m_data;
    92         };
    93 
    9491
    9592}
  • trunk/nv/stl/file_system.hh

    r413 r422  
    1010 */
    1111
    12 #ifndef NV_INTERFACE_FILE_SYSTEM_HH
    13 #define NV_INTERFACE_FILE_SYSTEM_HH
     12#ifndef NV_STL_FILE_SYSTEM_HH
     13#define NV_STL_FILE_SYSTEM_HH
    1414
    1515#include <nv/common.hh>
    16 #include <nv/interface/stream.hh>
     16#include <nv/stl/stream.hh>
    1717
    1818namespace nv
     
    3131} // namespace nv
    3232
    33 #endif // NV_FILE_SYSTEM_HH
     33#endif // NV_STL_FILE_SYSTEM_HH
  • trunk/nv/stl/functional/hash.hh

    r402 r422  
    203203        };
    204204
     205        constexpr uint32 operator "" _h32( const char* str, size_t len )
     206        {
     207                return detail::fnv_hash< uint32 >::hash( str, len );
     208        }
     209
     210        constexpr uint64 operator "" _h64( const char* str, size_t len )
     211        {
     212                return detail::fnv_hash< uint32 >::hash( str, len );
     213        }
     214
    205215}
    206216
     217using nv::operator "" _h32;
     218using nv::operator "" _h64;
     219
    207220#endif // NV_STL_FUNCTIONAL_HASH_HH
  • trunk/nv/stl/stream.hh

    r413 r422  
    1111 */
    1212
    13 #ifndef NV_INTERFACE_STREAM_HH
    14 #define NV_INTERFACE_STREAM_HH
     13#ifndef NV_STL_STREAM_HH
     14#define NV_STL_STREAM_HH
    1515
    1616#include <nv/common.hh>
     
    4242} // namespace nv
    4343
    44 #endif // NV_INTERFACE_STREAM_HH
     44#endif // NV_STL_STREAM_HH
  • trunk/src/io/string_table.cc

    r421 r422  
    77#include "nv/io/string_table.hh"
    88
    9 nv::string_table_creator::string_table_creator()
     9nv::string_table::string_table( stream& in )
    1010{
    11         insert(""); // 0 always is empty string
     11        uint32 entry_count = 0;
     12        in.read( &entry_count, sizeof( entry_count ), 1 );
     13        m_map.reserve( entry_count );
     14        indexer_type::value_type entry;
     15        for ( uint32 i = 0; i < entry_count; )
     16        {
     17                in.read( &entry, sizeof( entry ), 1 );
     18                // TODO: this performs a existence check -
     19                //   using a per-container stream implementation would avoid this!
     20                m_map.insert( entry );
     21        }
     22
     23        uint32 data_size = 0;
     24        in.read( &data_size, sizeof( data_size ), 1 );
     25        // TODO: either no-init resize, or per-container implementation?
     26        m_data.resize( data_size );
     27        in.read( m_data.data(), data_size, 1 );
    1228}
    1329
    14 nv::string_table_creator::index nv::string_table_creator::insert( const string_view& s )
     30void nv::string_table::insert( string_table* in )
    1531{
    16         uint64 hash_value = hash_string< uint64 >( s.data() );
    17         auto i = m_map.find( hash_value );
    18         if ( i != m_map.end() )
     32        m_data.reserve( m_data.size() + in->m_data.size() );
     33        m_map.reserve( m_map.size() + in->m_map.size() );
     34        for ( const auto& hash_index : in->m_map )
    1935        {
    20                 return i->second;
     36                insert( hash_index.first, in->extract_raw( hash_index.second ) );
    2137        }
    22         const char* cs = s.data();
    23         uint32 cs_size = s.size() + 1;
    24         NV_ASSERT( m_offsets.size() < index(-1), "Too many strings!" );
    25         index  result = index( m_offsets.size() );
    26         size_t dsize = m_data.size();
    27         m_offsets.push_back( dsize );
    28         m_data.resize( dsize + cs_size );
    29         raw_copy( cs, cs + cs_size, m_data.data() + dsize );
    30         m_map[ hash_value ] = result;
    31         return result;
    3238}
    3339
    34 nv::string_table* nv::string_table_creator::create_table() const
     40nv::uint32 nv::string_table::dump_size() const
    3541{
    36         offset* offsets = new offset[m_offsets.size()];
    37         char*   data    = new char [m_data.size()];
    38         raw_copy( m_offsets.begin(), m_offsets.end(), offsets );
    39         raw_copy( m_data.begin(),    m_data.end(),    data );
    40         return new string_table( data, m_data.size(), offsets, index( m_offsets.size() ) );
     42        return sizeof( uint32 ) + sizeof( indexer_type::value_type ) * m_map.size() +
     43                sizeof( uint32 ) + m_data.size();
    4144}
    4245
    43 void nv::string_table_creator::dump( nv::stream* out ) const
     46void nv::string_table::dump( nv::stream& out ) const
    4447{
    45         index  count = index( m_offsets.size() );
    46         uint32 size  = m_data.size();
    47         out->write( &count,  sizeof( count ), 1 );
    48         out->write( &size,   sizeof( size ), 1 );
    49         out->write( m_offsets.data(), sizeof( offset ), count );
    50         out->write( m_data.data(),    sizeof( char ),  size );
     48        // TODO these should be generic stream operations
     49        uint32 entry_count = m_map.size();
     50        out.write( &entry_count, sizeof( entry_count ), 1 );
     51        for ( const auto& entry : m_map )
     52        {
     53                out.write( &entry, sizeof( entry ), 1 );
     54        }
     55
     56        uint32 data_size = m_data.size();
     57        out.write( &data_size, sizeof( data_size ), 1 );
     58        // TODO: either no-init resize, or per-container implementation?
     59        out.write( m_data.data(), data_size, 1 );
    5160}
    5261
    53 const char* nv::string_table_creator::get( index i ) const
     62nv::string_table::size_type  nv::string_table::insert_raw( hash_type h, const char* str, length_type length )
    5463{
    55         return i < m_offsets.size() ? m_data.data() + m_offsets[i] : nullptr;
     64        size_type dsize  = static_cast<uint32>( m_data.size() );
     65        // TODO : resize without init!
     66        m_data.resize( dsize + 2 + length + 1 );
     67        *reinterpret_cast<uint16*>( m_data.data() + dsize ) = length;
     68        raw_copy( str, str + length + 1, m_data.data() + dsize + 2 );
     69        m_map[h] = dsize;
     70        return dsize;
    5671}
    5772
    58 nv::string_table_creator::index nv::string_table_creator::get( const string_view& s ) const
    59 {
    60         uint64 hash_value = hash_string< uint64 >( s.data() );
    61         auto i = m_map.find( hash_value );
    62         if ( i != m_map.end() )
    63         {
    64                 return i->second;
    65         }
    66         return 0;
    67 }
    68 
    69 void nv::string_table_creator::clear()
    70 {
    71         m_map.clear();
    72         m_offsets.clear();
    73         m_data.clear();
    74 }
    75 
    76 nv::uint32 nv::string_table_creator::dump_size() const
    77 {
    78         return sizeof( index ) + sizeof( uint32 ) +
    79                 sizeof( offset ) * m_offsets.size() +
    80                 sizeof( char ) * m_data.size();
    81 }
    82 
Note: See TracChangeset for help on using the changeset viewer.