1 | // Copyright (C) 2014-2015 ChaosForge Ltd
|
---|
2 | // http://chaosforge.org/
|
---|
3 | //
|
---|
4 | // This file is part of Nova libraries.
|
---|
5 | // For conditions of distribution and use, see copying.txt file in root folder.
|
---|
6 |
|
---|
7 | /**
|
---|
8 | * @file string_table.hh
|
---|
9 | * @author Kornel Kisielewicz
|
---|
10 | */
|
---|
11 |
|
---|
12 | #ifndef NV_STL_STRING_TABLE_HH
|
---|
13 | #define NV_STL_STRING_TABLE_HH
|
---|
14 |
|
---|
15 | #include <nv/common.hh>
|
---|
16 | #include <nv/stl/vector.hh>
|
---|
17 | #include <nv/stl/string.hh>
|
---|
18 | #include <nv/stl/unordered_map.hh>
|
---|
19 | #include <nv/stl/stream.hh>
|
---|
20 |
|
---|
21 | namespace nv
|
---|
22 | {
|
---|
23 |
|
---|
24 | class string_table : noncopyable
|
---|
25 | {
|
---|
26 | public:
|
---|
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;
|
---|
35 |
|
---|
36 | string_table() {}
|
---|
37 | string_table( stream& in );
|
---|
38 | void insert( string_table* in );
|
---|
39 | key_type insert( const value_type& str )
|
---|
40 | {
|
---|
41 | key_type hash_value = str.get_hash< uint64 >();
|
---|
42 | insert( hash_value, str );
|
---|
43 | return hash_value;
|
---|
44 | }
|
---|
45 |
|
---|
46 | bool exists( key_type i ) const
|
---|
47 | {
|
---|
48 | return m_map.find( i ) != m_map.end();
|
---|
49 | }
|
---|
50 |
|
---|
51 | value_type at( key_type i ) const
|
---|
52 | {
|
---|
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 );
|
---|
56 | }
|
---|
57 |
|
---|
58 | value_type operator[]( key_type i ) const
|
---|
59 | {
|
---|
60 | const auto& it = m_map.find( i );
|
---|
61 | return it != m_map.end() ? extract_raw( it->second ) : value_type();
|
---|
62 | }
|
---|
63 |
|
---|
64 | uint32 size() const { return m_map.size(); }
|
---|
65 | bool empty() const { return m_map.empty(); }
|
---|
66 | uint32 dump_size() const;
|
---|
67 | void dump( stream& out ) const;
|
---|
68 | protected:
|
---|
69 | void insert( hash_type h, const value_type& str )
|
---|
70 | {
|
---|
71 | NV_ASSERT_ALWAYS( str.size() < 0xFFF0, "String table can only hold strings up to 64k!" );
|
---|
72 | auto it = m_map.find( h );
|
---|
73 | if ( it != m_map.end() )
|
---|
74 | {
|
---|
75 | // TODO : perform comparison check if in debug mode!
|
---|
76 | return;
|
---|
77 | }
|
---|
78 | insert_raw( h, str.data(), static_cast<length_type>( str.size() ) );
|
---|
79 | }
|
---|
80 |
|
---|
81 |
|
---|
82 | size_type insert_raw( hash_type h, const char* str, length_type s );
|
---|
83 |
|
---|
84 | value_type extract_raw( size_type index ) const
|
---|
85 | {
|
---|
86 | uint16 length = *reinterpret_cast<const uint16*>( m_data.data() + index );
|
---|
87 | return value_type( m_data.data() + index + 2, length );
|
---|
88 | }
|
---|
89 |
|
---|
90 | indexer_type m_map;
|
---|
91 | storage_type m_data;
|
---|
92 | };
|
---|
93 |
|
---|
94 | }
|
---|
95 |
|
---|
96 | #endif // NV_STL_STRING_TABLE_HH
|
---|