Skip to content

Commit

Permalink
Add BF/CF support
Browse files Browse the repository at this point in the history
  • Loading branch information
uglide committed Oct 5, 2022
1 parent db9b827 commit adf48e1
Show file tree
Hide file tree
Showing 10 changed files with 190 additions and 6 deletions.
74 changes: 74 additions & 0 deletions src/app/models/key-models/bfkey.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
#include "bfkey.h"

#include <QJsonDocument>

BloomFilterKeyModel::BloomFilterKeyModel(
QSharedPointer<RedisClient::Connection> connection, QByteArray fullPath,
int dbIndex, long long ttl, QString filterFamily)
: KeyModel(connection, fullPath, dbIndex, ttl), m_type(filterFamily) {}

QString BloomFilterKeyModel::type() { return m_type; }

QStringList BloomFilterKeyModel::getColumnNames() {
return QStringList() << "value";
}

QHash<int, QByteArray> BloomFilterKeyModel::getRoles() {
QHash<int, QByteArray> roles;
roles[Roles::Value] = "value";
return roles;
}

QVariant BloomFilterKeyModel::getData(int rowIndex, int dataRole) {
if (rowIndex > 0 || !isRowLoaded(rowIndex)) return QVariant();
if (dataRole == Roles::Value)
return QJsonDocument::fromVariant(m_rowsCache[rowIndex])
.toJson(QJsonDocument::Compact);

return QVariant();
}

void BloomFilterKeyModel::addRow(const QVariantMap& row, Callback c) {
QByteArray value = row.value("value").toByteArray();

executeCmd({QString("%1.ADD").arg(m_type).toLatin1(), m_keyFullPath, value},
[this, c](const QString& err) {
m_rowCount++;
return c(err);
});
}

void BloomFilterKeyModel::loadRows(QVariant, unsigned long,
LoadRowsCallback callback) {
auto onConnectionError = [callback](const QString& err) {
return callback(err, 0);
};

auto responseHandler = [this, callback](RedisClient::Response r, Callback) {
m_rowsCache.clear();
auto value = r.value().toList();

QVariantMap row;

for (QVariantList::const_iterator item = value.cbegin(); item != value.cend();
++item) {
auto key = item->toByteArray();
++item;

if (item == value.cend()) {
emit m_notifier->error(QCoreApplication::translate(
"RESP", "Data was loaded from server partially."));
break;
}

auto keyVal = item->toByteArray();
row[key] = keyVal;
}

m_rowsCache.push_back(row);
callback(QString(), 1);
};

executeCmd({QString("%1.INFO").arg(m_type).toLatin1(), m_keyFullPath},
onConnectionError, responseHandler, RedisClient::Response::Array);
}
28 changes: 28 additions & 0 deletions src/app/models/key-models/bfkey.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#pragma once
#include "stringkey.h"

class BloomFilterKeyModel : public KeyModel<QVariant> {
public:
BloomFilterKeyModel(QSharedPointer<RedisClient::Connection> connection,
QByteArray fullPath, int dbIndex, long long ttl, QString filterFamily="bf");

QString type() override;
QStringList getColumnNames() override;
QHash<int, QByteArray> getRoles() override;
QVariant getData(int rowIndex, int dataRole) override;

void addRow(const QVariantMap&, Callback c) override;
virtual void updateRow(int, const QVariantMap&,
Callback) override {}
void loadRows(QVariant, unsigned long, LoadRowsCallback callback) override;
void removeRow(int, Callback) override {}

virtual unsigned long rowsCount() override { return m_rowCount; }

protected:
int addLoadedRowsToCache(const QVariantList&, QVariant) override { return 1; }

private:
enum Roles { Value = Qt::UserRole + 1 };
QString m_type;
};
5 changes: 5 additions & 0 deletions src/app/models/key-models/keyfactory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include <QFile>
#include <QObject>

#include "bfkey.h"
#include "hashkey.h"
#include "listkey.h"
#include "rejsonkey.h"
Expand Down Expand Up @@ -155,6 +156,10 @@ QSharedPointer<ValueEditor::Model> KeyFactory::createModel(
} else if (type == "stream") {
return QSharedPointer<ValueEditor::Model>(
new StreamKeyModel(connection, keyFullPath, dbIndex, ttl));
} else if (type.startsWith("MBbloom")) {
QString ff = type.endsWith("CF")? "cf" : "bf";
return QSharedPointer<ValueEditor::Model>(
new BloomFilterKeyModel(connection, keyFullPath, dbIndex, ttl, ff));
}

return QSharedPointer<ValueEditor::Model>(
Expand Down
1 change: 1 addition & 0 deletions src/qml/qml.qrc
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@
<file>connections/AskSecretDialog.qml</file>
<file>common/ColorInput.qml</file>
<file>value-editor/editors/UnsupportedDataType.qml</file>
<file>value-editor/editors/ReadOnlySingleItemEditor.qml</file>
<file>extension-server/ExtensionServerSettings.qml</file>
<file>connections-tree/TreeItemDelegate.qml</file>
<file>server-actions/ServerActionTabs.qml</file>
Expand Down
2 changes: 1 addition & 1 deletion src/qml/value-editor/AddKeyDialog.qml
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ BetterDialog {

asynchronous: true
source: Editor.getEditorByTypeString(
typeSelector.model[typeSelector.currentIndex])
typeSelector.model[typeSelector.currentIndex], true)

onLoaded: {
item.state = "new"
Expand Down
2 changes: 1 addition & 1 deletion src/qml/value-editor/ValueTableActions.qml
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ ColumnLayout {
property int currentRow: -1
objectName: "rdm_add_row_dialog"

source: keyTab.keyModel ? Editor.getEditorByTypeString(keyType) : ""
source: keyTab.keyModel ? Editor.getEditorByTypeString(keyType, true) : ""

onLoaded: {
item.state = "add"
Expand Down
2 changes: 1 addition & 1 deletion src/qml/value-editor/ValueTabs.qml
Original file line number Diff line number Diff line change
Expand Up @@ -430,7 +430,7 @@ Repeater {

property int currentRow: -1

source: keyTab.keyModel? Editor.getEditorByTypeString(keyType) : ""
source: keyTab.keyModel? Editor.getEditorByTypeString(keyType, false) : ""

function loadRowValue(row) {
console.log("loading row value", row)
Expand Down
8 changes: 6 additions & 2 deletions src/qml/value-editor/editors/MultilineEditor.qml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ Item
property bool showSaveBtn: false
property bool showFormatters: true
property bool showOnlyRWformatters: false
property bool showValueSize: true
property string fieldLabel: qsTranslate("RESP","Value") + ":"
property bool isEdited: false
property var value
Expand Down Expand Up @@ -361,6 +362,7 @@ Item
readOnly: true;
selectByMouse: true
color: "#ccc"
visible: showValueSize
}
BetterLabel { id: binaryFlag; text: qsTranslate("RESP","[Binary]"); visible: false; color: "green"; }
Item { Layout.fillWidth: true }
Expand Down Expand Up @@ -510,8 +512,10 @@ Item
iconSource: PlatformUtils.getThemeIcon("add.svg")
Layout.alignment: Qt.AlignHCenter

text: qsTranslate("RESP","Add Element to HLL");
visible: keyType === "hyperloglog"
text: qsTranslate("RESP","Add Element");
visible: (keyType === "hyperloglog"
|| keyType === "bf"
|| keyType === "cf")

onClicked: {
keyTab.addRowDialog.open()
Expand Down
66 changes: 66 additions & 0 deletions src/qml/value-editor/editors/ReadOnlySingleItemEditor.qml
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import QtQuick 2.0
import QtQuick.Layouts 1.1
import QtQuick.Controls 1.2
import QtQuick.Controls.Styles 1.1

import "."

AbstractEditor {
id: root
anchors.fill: parent

property bool active: false
property alias defaultFormatter: textEditor.defaultFormatter

MultilineEditor {
id: textEditor
Layout.fillWidth: true
Layout.fillHeight: true
value: ""
enabled: false
showToolBar: false
showSaveBtn: false
showFormatters: false
showValueSize: false
objectName: "rdm_key_value_field"

function validationRule(raw) {
return true;
}
}

onKeyTypeChanged: {
textEditor.hintFormatter("JSON")
}

function initEmpty() {
textEditor.initEmpty()
}

function getValue(validateVal, callback) {
if (!validateVal) {
return callback(true, {"value": ""});
}

return textEditor.validate(function (valid, raw) {
return callback(valid, {"value": raw});
});
}

function setValue(rowValue) {
if (!rowValue)
return

active = true
textEditor.loadFormattedValue(rowValue['value'])
}

function isEdited() {
return textEditor.isEdited
}

function reset() {
textEditor.reset()
active = false
}
}
8 changes: 7 additions & 1 deletion src/qml/value-editor/editors/editor.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ function getSupportedKeyTypes() {
return ["string", "list", "set", "zset", "hash", "stream"]
}

function getEditorByTypeString(keyType) {
function getEditorByTypeString(keyType, writeOnly) {
if (keyType === "string"
|| keyType === "hyperloglog"
|| keyType === "list"
Expand All @@ -16,6 +16,12 @@ function getEditorByTypeString(keyType) {
return "./editors/HashItemEditor.qml"
} else if (keyType === "stream") {
return "./editors/StreamItemEditor.qml"
} else if (keyType === "bf" || keyType === "cf") {
if (writeOnly) {
return "./editors/SingleItemEditor.qml"
} else {
return "./editors/ReadOnlySingleItemEditor.qml"
}
} else if (keyType) {
return "./editors/UnsupportedDataType.qml"
}
Expand Down

0 comments on commit adf48e1

Please sign in to comment.