Skip to content

Commit 7619c1b

Browse files
committed
Merge pull request RedisInsight#3406 from uglide/fix_value_view
Fix value view
2 parents a274f87 + 812dfd9 commit 7619c1b

File tree

10 files changed

+183
-23
lines changed

10 files changed

+183
-23
lines changed

src/app/dialogs/connect.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,7 @@ bool ConnectionWindow::isConnectionSettingsValid()
208208
bool ConnectionWindow::isAdvancedSettingsValid()
209209
{
210210
markFieldValid(ui.namespaceSeparator);
211+
markFieldValid(ui.keysPattern);
211212

212213
bool isValid = !ui.namespaceSeparator->text().isEmpty()
213214
|| !ui.keysPattern->text().isEmpty();

src/app/models/key-models/abstractkey.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include <QPair>
77
#include "modules/value-editor/keymodel.h"
88
#include "modules/redisclient/redisclient.h"
9+
#include "rowcache.h"
910

1011
template < typename T > class KeyModel : public ValueEditor::Model
1112
{
@@ -68,7 +69,7 @@ template < typename T > class KeyModel : public ValueEditor::Model
6869

6970
virtual bool isRowLoaded(int rowIndex) override
7071
{
71-
return 0 <= rowIndex && rowIndex < m_rowsCache.size();
72+
return m_rowsCache.isRowLoaded(rowIndex);
7273
}
7374

7475
virtual unsigned long rowsCount() override
@@ -300,7 +301,7 @@ template < typename T > class KeyModel : public ValueEditor::Model
300301
QString m_fullLoadingCmd;
301302
bool m_fullLoadingCmdSupportsRanges;
302303

303-
QList<T> m_rowsCache;
304+
MappedCache<T> m_rowsCache;
304305
QSharedPointer<ValueEditor::ModelSignals> m_notifier;
305306
};
306307

src/app/models/key-models/hashkey.cpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -131,11 +131,11 @@ void HashKeyModel::deleteHashRow(const QByteArray &hashKey)
131131
}
132132

133133
void HashKeyModel::addLoadedRowsToCache(const QVariantList &rows, int rowStart)
134-
{
135-
unsigned int rowIndex = rowStart;
134+
{
135+
QList<QPair<QByteArray, QByteArray>> result;
136136

137137
for (QVariantList::const_iterator item = rows.begin();
138-
item != rows.end(); ++item, rowIndex++) {
138+
item != rows.end(); ++item) {
139139

140140
QPair<QByteArray, QByteArray> value;
141141
value.first = item->toByteArray();
@@ -145,6 +145,9 @@ void HashKeyModel::addLoadedRowsToCache(const QVariantList &rows, int rowStart)
145145
throw Exception("Partial data loaded from server");
146146

147147
value.second = item->toByteArray();
148-
m_rowsCache.push_back(value);
148+
result.push_back(value);
149149
}
150+
151+
m_rowsCache.addLoadedRange({rowStart, rowStart + result.size() - 1},
152+
result);
150153
}

src/app/models/key-models/listlikekey.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,12 @@ QVariant ListLikeKeyModel::getData(int rowIndex, int dataRole)
4444

4545
void ListLikeKeyModel::addLoadedRowsToCache(const QVariantList &rows, int rowStart)
4646
{
47+
QList<QByteArray> result;
48+
4749
foreach (QVariant row, rows) {
48-
m_rowsCache.push_back(row.toByteArray());
50+
result.push_back(row.toByteArray());
4951
}
52+
53+
m_rowsCache.addLoadedRange({rowStart, rowStart + result.size() - 1},
54+
result);
5055
}

src/app/models/key-models/rowcache.h

Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
#pragma once
2+
#include <QPair>
3+
#include <QList>
4+
#include <QHash>
5+
#include <exception>
6+
7+
typedef long int RowIndex;
8+
9+
class CacheRange : public QPair<RowIndex, RowIndex>
10+
{
11+
public:
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+
23+
24+
template < typename T > class MappedCache
25+
{
26+
public:
27+
28+
MappedCache()
29+
: m_lastCacheRange(),
30+
m_size(0),
31+
m_valid(false)
32+
{
33+
}
34+
35+
bool isValid() const
36+
{
37+
return m_valid;
38+
}
39+
40+
void addLoadedRange(const CacheRange& range, const QList<T>& dataForRange)
41+
{
42+
if (!isValid())
43+
clear();
44+
45+
m_mapping[range] = dataForRange;
46+
m_size += dataForRange.size();
47+
48+
if (range.second > m_lastCacheRange.second)
49+
m_lastCacheRange = range;
50+
}
51+
52+
bool isRowLoaded(RowIndex index)
53+
{
54+
CacheRange i = findTargetRange(index);
55+
return !i.isEmpty();
56+
}
57+
58+
T getRow(RowIndex index)
59+
{
60+
if (!isRowLoaded(index))
61+
return T();
62+
63+
CacheRange i = findTargetRange(index);
64+
qDebug() << "get row with index" << (index - i.first);
65+
return m_mapping[i].at(index - i.first);
66+
}
67+
68+
T operator [](RowIndex index) {
69+
return getRow(index);
70+
}
71+
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");
83+
}
84+
CacheRange i = findTargetRange(index);
85+
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+
}
92+
93+
void push_back(const T& row) {
94+
CacheRange newKey{0, 1};
95+
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;
104+
}
105+
106+
unsigned long long size() const
107+
{
108+
return m_size;
109+
}
110+
111+
void clear()
112+
{
113+
m_mapping.clear();
114+
m_size = 0;
115+
m_lastCacheRange = CacheRange();
116+
m_valid = true;
117+
}
118+
119+
private:
120+
CacheRange findTargetRange(RowIndex index)
121+
{
122+
for (auto i = m_mapping.constBegin();
123+
i != m_mapping.constEnd(); ++i)
124+
{
125+
if (i.key().first <= index && index <= i.key().second) {
126+
return i.key();
127+
}
128+
}
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;
141+
}
142+
143+
private:
144+
CacheRange m_lastCacheRange;
145+
QHash<CacheRange, QList<T>> m_mapping;
146+
unsigned long long m_size;
147+
bool m_valid;
148+
};

src/app/models/key-models/setkey.cpp

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,9 @@ void SetKeyModel::updateRow(int rowIndex, const QVariantMap &row)
2121
QByteArray cachedRow = m_rowsCache[rowIndex];
2222
QByteArray newRow(row["value"].toByteArray());
2323

24-
// delete old value
2524
deleteSetRow(cachedRow);
26-
m_rowsCache.removeAt(rowIndex);
27-
28-
// add new value
2925
addSetRow(newRow);
30-
m_rowsCache.insert(rowIndex, newRow);
26+
m_rowsCache.replace(rowIndex, newRow);
3127
}
3228

3329
void SetKeyModel::addRow(const QVariantMap &row)
@@ -44,7 +40,7 @@ void SetKeyModel::removeRow(int i)
4440
if (!isRowLoaded(i))
4541
return;
4642

47-
QByteArray value = m_rowsCache.value(i);
43+
QByteArray value = m_rowsCache[i];
4844
deleteSetRow(value);
4945

5046
m_rowCount--;

src/app/models/key-models/sortedsetkey.cpp

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ void SortedSetKeyModel::addRow(const QVariantMap &row)
7979
row["score"].toDouble());
8080

8181
if (addSortedSetRow(cachedRow.first, cachedRow.second)) {
82-
m_rowsCache.append(cachedRow);
82+
m_rowsCache.push_back(cachedRow);
8383
m_rowCount++;
8484
}
8585
}
@@ -89,7 +89,7 @@ void SortedSetKeyModel::removeRow(int i)
8989
if (!isRowLoaded(i))
9090
return;
9191

92-
QByteArray value = m_rowsCache.value(i).first;
92+
QByteArray value = m_rowsCache[i].first;
9393

9494
using namespace RedisClient;
9595

@@ -134,8 +134,10 @@ void SortedSetKeyModel::deleteSortedSetRow(const QByteArray &value)
134134
}
135135
}
136136

137-
void SortedSetKeyModel::addLoadedRowsToCache(const QVariantList &rows, int)
137+
void SortedSetKeyModel::addLoadedRowsToCache(const QVariantList &rows, int rowStart)
138138
{
139+
QList<QPair<QByteArray, double>> result;
140+
139141
for (QVariantList::const_iterator item = rows.begin();
140142
item != rows.end(); ++item) {
141143

@@ -147,6 +149,9 @@ void SortedSetKeyModel::addLoadedRowsToCache(const QVariantList &rows, int)
147149
throw Exception("Partial data loaded from server");
148150

149151
value.second = item->toDouble();
150-
m_rowsCache.push_back(value);
152+
result.push_back(value);
151153
}
154+
155+
m_rowsCache.addLoadedRange({rowStart, rowStart + result.size() - 1},
156+
result);
152157
}

src/app/models/key-models/stringkey.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,8 @@ void StringKeyModel::updateRow(int rowIndex, const QVariantMap &row)
6262
throw Exception("Connection error: " + QString(e.what()));
6363
}
6464

65-
if (result.isOkMessage()) {
66-
m_rowsCache.clear();
67-
m_rowsCache.append(value);
65+
if (result.isOkMessage()) {
66+
m_rowsCache.replace(0, value);
6867
m_notifier->dataLoaded();
6968
}
7069
}
@@ -104,7 +103,7 @@ bool StringKeyModel::loadValue()
104103
}
105104

106105
m_rowsCache.clear();
107-
m_rowsCache.append(result.getValue().toByteArray());
106+
m_rowsCache.push_back(result.getValue().toByteArray());
108107

109108
m_notifier->dataLoaded();
110109

src/modules/value-editor/valueviewmodel.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,8 @@ void ValueEditor::ValueViewModel::loadRows(int start, int count)
8989
QString msg = QString("Cannot load key value: %1");
9090

9191
try {
92+
// NOTE(u_glide): Do so for proper rendering of QML table
93+
m_lastLoadedRowFrameSize = totalRowCount() - start;
9294
m_model->loadRows(start, count, [this, start, count, msg](const QString& err)
9395
{
9496
if (!err.isEmpty()) {

src/resources/qml/ValueTabs.qml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -183,9 +183,9 @@ Repeater {
183183
anchors.verticalCenter: parent.verticalCenter
184184
color: truncated ? 'red' : styleData.textColor
185185
elide: styleData.elideMode
186-
text: styleData.value + (truncated ? '...' : '')
186+
text: styleData.value ? styleData.value + (truncated ? '...' : '') : (styleData.column == 1)? "[not loaded from server]" : "--"
187187
wrapMode: Text.WordWrap
188-
maximumLineCount: 1
188+
maximumLineCount: 1
189189
}
190190
}
191191

0 commit comments

Comments
 (0)