22#include < QPair>
33#include < QList>
44#include < QHash>
5+ #include < exception>
56
7+ typedef long int RowIndex;
68
7- template < typename T > class MappedCache
9+ class CacheRange : public QPair <RowIndex, RowIndex>
810{
911public:
10- typedef unsigned long int RowIndex;
11- typedef QPair<RowIndex, RowIndex> CacheRange;
12+ CacheRange (const RowIndex& f = -1 , const RowIndex& s = -1 )
13+ : QPair<RowIndex, RowIndex>(f, s)
14+ {
15+ }
16+
17+ bool isEmpty () const
18+ {
19+ return first == -1 && second == -1 ;
20+ }
21+ };
22+
1223
24+ template < typename T > class MappedCache
25+ {
1326public:
1427
15- MappedCache ()
16- : m_size(0 )
28+ MappedCache ()
29+ : m_lastCacheRange(),
30+ m_size (0 ),
31+ m_valid(false )
1732 {
33+ }
1834
35+ bool isValid () const
36+ {
37+ return m_valid;
1938 }
2039
2140 void addLoadedRange (const CacheRange& range, const QList<T>& dataForRange)
2241 {
42+ if (!isValid ())
43+ clear ();
44+
2345 m_mapping[range] = dataForRange;
2446 m_size += dataForRange.size ();
47+
48+ if (range.second > m_lastCacheRange.second )
49+ m_lastCacheRange = range;
2550 }
2651
2752 bool isRowLoaded (RowIndex index)
2853 {
2954 CacheRange i = findTargetRange (index);
30- return i != CacheRange ({- 1 , - 1 } );
55+ return !i. isEmpty ( );
3156 }
3257
3358 T getRow (RowIndex index)
@@ -36,23 +61,46 @@ template < typename T > class MappedCache
3661 return T ();
3762
3863 CacheRange i = findTargetRange (index);
39-
40- RowIndex mappedIndex = i.first - index;
41-
42- return m_mapping.value (i).at (mappedIndex);
64+ qDebug () << " get row with index" << (index - i.first );
65+ return m_mapping[i].at (index - i.first );
4366 }
4467
4568 T operator [](RowIndex index) {
4669 return getRow (index);
4770 }
4871
49- void replace (RowIndex i, T row) {
50- if (!isRowLoaded (i)) {
51- return std::
72+ void replace (RowIndex index, T row) {
73+ if (!isRowLoaded (index)) {
74+ throw std::out_of_range (" Invalid row" );
75+ }
76+ CacheRange i = findTargetRange (index);
77+ return m_mapping[i].replace (index - i.first , row);
78+ }
79+
80+ void removeAt (RowIndex index) {
81+ if (!isRowLoaded (index)) {
82+ throw std::out_of_range (" Invalid row" );
5283 }
84+ CacheRange i = findTargetRange (index);
5385
86+ m_mapping[i].removeAt (index - i.first );
87+ CacheRange newKey{i.first , i.second - 1 };
88+ replaceRangeInMapping (newKey, i);
89+ m_valid = false ;
90+ m_size -= 1 ;
91+ }
5492
93+ void push_back (const T& row) {
94+ CacheRange newKey{0 , 1 };
5595
96+ if (!m_lastCacheRange.isEmpty ()) {
97+ newKey.first += m_lastCacheRange.first ;
98+ newKey.second += m_lastCacheRange.second ;
99+ }
100+
101+ m_mapping[m_lastCacheRange].push_back (row);
102+ replaceRangeInMapping (newKey);
103+ m_size += 1 ;
56104 }
57105
58106 unsigned long long size () const
@@ -64,6 +112,8 @@ template < typename T > class MappedCache
64112 {
65113 m_mapping.clear ();
66114 m_size = 0 ;
115+ m_lastCacheRange = CacheRange ();
116+ m_valid = true ;
67117 }
68118
69119private:
@@ -76,11 +126,23 @@ template < typename T > class MappedCache
76126 return i.key ();
77127 }
78128 }
79- return {-1 , -1 };
129+ return CacheRange ();
130+ }
131+
132+ void replaceRangeInMapping (const CacheRange& newRange, const CacheRange& current = CacheRange())
133+ {
134+ CacheRange replaceKey = current.isEmpty ()? m_lastCacheRange : current;
135+
136+ m_mapping[newRange] = m_mapping[replaceKey];
137+ m_mapping.remove (current);
138+
139+ if (current.isEmpty ())
140+ m_lastCacheRange = newRange;
80141 }
81142
82143private:
144+ CacheRange m_lastCacheRange;
83145 QHash<CacheRange, QList<T>> m_mapping;
84146 unsigned long long m_size;
147+ bool m_valid;
85148};
86-
0 commit comments