mirror of
https://github.com/laurent22/joplin.git
synced 2024-11-27 08:21:03 +02:00
Laod note
This commit is contained in:
parent
ac166d7976
commit
40e9b82137
@ -1,4 +1,4 @@
|
||||
QT += qml quick sql
|
||||
QT += qml quick sql quickcontrols2
|
||||
|
||||
CONFIG += c++11
|
||||
|
||||
@ -15,7 +15,8 @@ SOURCES += \
|
||||
services/noteservice.cpp \
|
||||
application.cpp \
|
||||
models/notecollection.cpp \
|
||||
services/notecache.cpp
|
||||
services/notecache.cpp \
|
||||
models/qmlnote.cpp
|
||||
|
||||
RESOURCES += qml.qrc
|
||||
|
||||
@ -40,7 +41,9 @@ HEADERS += \
|
||||
services/noteservice.h \
|
||||
application.h \
|
||||
models/notecollection.h \
|
||||
services/notecache.h
|
||||
services/notecache.h \
|
||||
sparsevector.hpp \
|
||||
models/qmlnote.h
|
||||
|
||||
DISTFILES +=
|
||||
|
||||
|
51
QtClient/JoplinQtClient/NoteEditor.qml
Executable file
51
QtClient/JoplinQtClient/NoteEditor.qml
Executable file
@ -0,0 +1,51 @@
|
||||
import QtQuick 2.0
|
||||
import QtQuick.Controls 2.0
|
||||
import QtQuick.Layouts 1.1
|
||||
|
||||
Item {
|
||||
|
||||
property QtObject model
|
||||
|
||||
Connections {
|
||||
target: model
|
||||
onChanged: {
|
||||
if (!model) {
|
||||
titleField.text = ""
|
||||
bodyField.text = ""
|
||||
} else {
|
||||
titleField.text = model.title
|
||||
bodyField.text = model.body
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
color: "#eeeeee"
|
||||
border.color: "#0000ff"
|
||||
anchors.fill: parent
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
|
||||
anchors.fill: parent
|
||||
spacing: 2
|
||||
|
||||
TextField {
|
||||
id: titleField
|
||||
Layout.fillWidth: true
|
||||
Layout.minimumWidth: 50
|
||||
Layout.preferredWidth: 100
|
||||
}
|
||||
|
||||
TextArea {
|
||||
id: bodyField
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
Layout.minimumWidth: 50
|
||||
Layout.preferredWidth: 100
|
||||
Layout.minimumHeight: 150
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -5,7 +5,7 @@ Item {
|
||||
id: root
|
||||
property alias model: listView.model
|
||||
property alias currentIndex: listView.currentIndex
|
||||
signal currentItemChanged()
|
||||
property alias currentItem: listView.currentItem
|
||||
|
||||
Rectangle {
|
||||
color: "#ffeeee"
|
||||
|
@ -19,12 +19,14 @@ Application::Application(int &argc, char **argv) : QGuiApplication(argc, argv) {
|
||||
QQmlContext *ctxt = view_.rootContext();
|
||||
ctxt->setContextProperty("folderListModel", &folderModel_);
|
||||
ctxt->setContextProperty("noteListModel", ¬eModel_);
|
||||
ctxt->setContextProperty("noteModel", &selectedQmlNote_);
|
||||
|
||||
view_.setSource(QUrl("qrc:/main.qml"));
|
||||
|
||||
QObject* rootObject = (QObject*)view_.rootObject();
|
||||
|
||||
connect(rootObject, SIGNAL(currentFolderChanged()), this, SLOT(view_currentFolderChanged()));
|
||||
connect(rootObject, SIGNAL(currentNoteChanged()), this, SLOT(view_currentNoteChanged()));
|
||||
|
||||
view_.show();
|
||||
}
|
||||
@ -37,8 +39,28 @@ int Application::selectedFolderId() const {
|
||||
return folderModel_.data(modelIndex, FolderModel::IdRole).toInt();
|
||||
}
|
||||
|
||||
int Application::selectedNoteId() const {
|
||||
QObject* rootObject = (QObject*)view_.rootObject();
|
||||
|
||||
int index = rootObject->property("currentNoteIndex").toInt();
|
||||
QModelIndex modelIndex = noteModel_.index(index);
|
||||
return noteModel_.data(modelIndex, NoteModel::IdRole).toInt();
|
||||
}
|
||||
|
||||
void Application::view_currentFolderChanged() {
|
||||
int folderId = selectedFolderId();
|
||||
noteCollection_ = NoteCollection(db_, noteCache_, folderId, "title ASC");
|
||||
noteCollection_ = NoteCollection(db_, folderId, "title ASC");
|
||||
noteModel_.setCollection(noteCollection_);
|
||||
}
|
||||
|
||||
void Application::view_currentNoteChanged() {
|
||||
int noteId = selectedNoteId();
|
||||
Note note = noteCollection_.byId(noteId);
|
||||
selectedQmlNote_.setNote(note);
|
||||
|
||||
// TODO: get note by id
|
||||
//Note note = noteCollection_.by
|
||||
//selectedQmlNote_ = QmlNote(noteId);
|
||||
//noteCollection_ = NoteCollection(db_, folderId, "title ASC");
|
||||
//noteModel_.setCollection(noteCollection_);
|
||||
}
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "models/notecollection.h"
|
||||
#include "services/notecache.h"
|
||||
#include "models/notemodel.h"
|
||||
#include "models/qmlnote.h"
|
||||
|
||||
namespace jop {
|
||||
|
||||
@ -31,11 +32,14 @@ private:
|
||||
FolderModel folderModel_;
|
||||
NoteModel noteModel_;
|
||||
int selectedFolderId() const;
|
||||
int selectedNoteId() const;
|
||||
NoteCache noteCache_;
|
||||
QmlNote selectedQmlNote_;
|
||||
|
||||
public slots:
|
||||
|
||||
void view_currentFolderChanged();
|
||||
void view_currentNoteChanged();
|
||||
|
||||
};
|
||||
|
||||
|
@ -8,7 +8,9 @@ Item {
|
||||
width: 800
|
||||
height: 600
|
||||
signal currentFolderChanged()
|
||||
signal currentNoteChanged()
|
||||
property alias currentFolderIndex: folderList.currentIndex
|
||||
property alias currentNoteIndex: noteList.currentIndex
|
||||
|
||||
RowLayout {
|
||||
id: layout
|
||||
@ -22,7 +24,7 @@ Item {
|
||||
Layout.fillHeight: true
|
||||
Layout.minimumWidth: 50
|
||||
Layout.preferredWidth: 100
|
||||
Layout.maximumWidth: 300
|
||||
Layout.maximumWidth: 200
|
||||
Layout.minimumHeight: 150
|
||||
|
||||
onCurrentItemChanged: {
|
||||
@ -36,8 +38,22 @@ Item {
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
Layout.minimumWidth: 100
|
||||
Layout.maximumWidth: 200
|
||||
Layout.preferredWidth: 200
|
||||
Layout.preferredHeight: 100
|
||||
|
||||
onCurrentItemChanged: {
|
||||
root.currentNoteChanged()
|
||||
}
|
||||
}
|
||||
|
||||
NoteEditor {
|
||||
id: noteEditor
|
||||
model: noteModel
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
Layout.minimumWidth: 100
|
||||
Layout.preferredHeight: 100
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -6,3 +6,11 @@ Note::Note()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
QString Note::body() const {
|
||||
return body_;
|
||||
}
|
||||
|
||||
void Note::setBody(const QString &v) {
|
||||
body_ = v;
|
||||
}
|
||||
|
@ -11,10 +11,12 @@ class Note : public Item {
|
||||
public:
|
||||
|
||||
Note();
|
||||
QString body() const;
|
||||
void setBody(const QString& v);
|
||||
|
||||
private:
|
||||
|
||||
|
||||
QString body_;
|
||||
|
||||
};
|
||||
|
||||
|
@ -4,77 +4,46 @@ using namespace jop;
|
||||
|
||||
NoteCollection::NoteCollection() {}
|
||||
|
||||
NoteCollection::NoteCollection(Database& db, NoteCache cache, int parentId, const QString& orderBy) {
|
||||
NoteCollection::NoteCollection(Database& db, int parentId, const QString& orderBy) {
|
||||
db_ = db;
|
||||
parentId_ = parentId;
|
||||
orderBy_ = orderBy;
|
||||
cache_ = cache;
|
||||
cacheMinIndex_ = 0;
|
||||
cacheMaxIndex_ = -1;
|
||||
}
|
||||
|
||||
|
||||
int NoteCollection::cacheMinIndex() const {
|
||||
return cacheMinIndex_;
|
||||
}
|
||||
|
||||
int NoteCollection::cacheMaxIndex() const {
|
||||
return cacheMaxIndex_;
|
||||
}
|
||||
|
||||
Note NoteCollection::itemAt(int index) const {
|
||||
Note NoteCollection::at(int index) const {
|
||||
if (!parentId_) return Note();
|
||||
|
||||
qDebug() << "Note at" << index << "Min" << cacheMinIndex() << "Max" << cacheMaxIndex() << "Count" << count();
|
||||
if (cache_.isset(index)) return cache_.get(index);
|
||||
|
||||
if (index >= cacheMinIndex() && index < cacheMaxIndex()) {
|
||||
return notes_[index];
|
||||
std::vector<int> indexes = cache_.availableBufferAround(index, 32);
|
||||
if (!indexes.size()) {
|
||||
qWarning() << "Couldn't acquire buffer"; // "Cannot happen"
|
||||
return Note();
|
||||
}
|
||||
|
||||
int buff = 16;
|
||||
int from = indexes[0];
|
||||
int to = indexes[indexes.size() - 1];
|
||||
|
||||
int from = index - buff;
|
||||
int to = from + (buff - 1);
|
||||
qDebug() << "Getting from" << from << "to" << to;
|
||||
|
||||
if (notes_.size()) {
|
||||
if (from <= cacheMaxIndex()) {
|
||||
from = cacheMaxIndex() + 1;
|
||||
to = from + (buff - 1);
|
||||
cacheMaxIndex_ = to;
|
||||
} else if (to >= cacheMinIndex()) {
|
||||
to = cacheMinIndex() - 1;
|
||||
from = to - (buff - 1);
|
||||
cacheMinIndex_ = from;
|
||||
}
|
||||
} else {
|
||||
from = std::max(0, index - buff);
|
||||
to = from + (buff - 1);
|
||||
}
|
||||
|
||||
if (from < 0) from = 0;
|
||||
if (to >= count()) to = count() - 1;
|
||||
|
||||
qDebug() << "Loading from" << from << "to" << to;
|
||||
|
||||
QSqlQuery q = db_.query("SELECT id, title FROM notes WHERE parent_id = :parent_id ORDER BY " + orderBy_ + " LIMIT " + QString::number(to - from + 1) + " OFFSET " + QString::number(from));
|
||||
QSqlQuery q = db_.query("SELECT id, title, body FROM notes WHERE parent_id = :parent_id ORDER BY " + orderBy_ + " LIMIT " + QString::number(to - from + 1) + " OFFSET " + QString::number(from));
|
||||
q.bindValue(":parent_id", parentId_);
|
||||
q.exec();
|
||||
|
||||
int noteIndex = from;
|
||||
while (q.next()) {
|
||||
Note f;
|
||||
f.setId(q.value(0).toInt());
|
||||
f.setTitle(q.value(1).toString());
|
||||
f.setIsPartial(true);
|
||||
Note note;
|
||||
note.setId(q.value(0).toInt());
|
||||
note.setTitle(q.value(1).toString());
|
||||
note.setBody(q.value(2).toString());
|
||||
note.setIsPartial(true);
|
||||
|
||||
qDebug() << "Adding" << noteIndex;
|
||||
notes_[noteIndex] = f;
|
||||
cache_.set(noteIndex, note);
|
||||
|
||||
noteIndex++;
|
||||
}
|
||||
|
||||
qDebug() << notes_.contains(index);
|
||||
return notes_[index];
|
||||
return cache_.get(index);
|
||||
}
|
||||
|
||||
// TODO: cache result
|
||||
@ -87,3 +56,27 @@ int NoteCollection::count() const {
|
||||
q.next();
|
||||
return q.value(0).toInt();
|
||||
}
|
||||
|
||||
Note NoteCollection::byId(int id) const {
|
||||
std::vector<int> indexes = cache_.indexes();
|
||||
for (int i = 0; i < indexes.size(); i++) {
|
||||
Note note = cache_.get(indexes[i]);
|
||||
if (note.id() == id) return note;
|
||||
}
|
||||
|
||||
QSqlQuery q = db_.query("SELECT id, title, body FROM notes WHERE id = :id");
|
||||
q.bindValue(":id", id);
|
||||
q.exec();
|
||||
q.next();
|
||||
if (!q.isValid()) {
|
||||
qWarning() << "Invalid note ID:" << id;
|
||||
return Note();
|
||||
}
|
||||
|
||||
// TODO: refactor creation of note from SQL query object
|
||||
Note note;
|
||||
note.setId(q.value(0).toInt());
|
||||
note.setTitle(q.value(1).toString());
|
||||
note.setBody(q.value(2).toString());
|
||||
return note;
|
||||
}
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include "database.h"
|
||||
#include "models/note.h"
|
||||
#include "services/notecache.h"
|
||||
#include "sparsevector.hpp"
|
||||
|
||||
namespace jop {
|
||||
|
||||
@ -14,23 +15,17 @@ class NoteCollection {
|
||||
public:
|
||||
|
||||
NoteCollection();
|
||||
NoteCollection(Database& db, NoteCache cache, int parentId, const QString& orderBy);
|
||||
Note itemAt(int index) const;
|
||||
NoteCollection(Database& db, int parentId, const QString& orderBy);
|
||||
Note at(int index) const;
|
||||
int count() const;
|
||||
Note byId(int id) const;
|
||||
|
||||
private:
|
||||
|
||||
int parentId_;
|
||||
QString orderBy_;
|
||||
Database db_;
|
||||
NoteCache cache_;
|
||||
|
||||
int cacheMinIndex() const;
|
||||
int cacheMaxIndex() const;
|
||||
|
||||
mutable int cacheMinIndex_;
|
||||
mutable int cacheMaxIndex_;
|
||||
mutable QMap<int, Note> notes_;
|
||||
mutable SparseVector<Note> cache_;
|
||||
|
||||
};
|
||||
|
||||
|
@ -12,17 +12,13 @@ int jop::NoteModel::rowCount(const QModelIndex &parent) const {
|
||||
QVariant jop::NoteModel::data(const QModelIndex &index, int role) const {
|
||||
if (index.row() < 0 || index.row() >= rowCount()) return QVariant();
|
||||
|
||||
Note note = collection_.itemAt(index.row());
|
||||
Note note = collection_.at(index.row());
|
||||
|
||||
if (role == IdRole) {
|
||||
return QVariant(note.id());
|
||||
}
|
||||
|
||||
return QVariant(note.title());
|
||||
|
||||
// int from = std::max(0, index.row() - 16);
|
||||
// int to = from + 32;
|
||||
// QList<Note> list = noteService_.overviewList(folderId_, from, to, "title ASC");
|
||||
|
||||
|
||||
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
void jop::NoteModel::setFolderId(const QString &v) {
|
||||
|
@ -14,6 +14,11 @@ class NoteModel : public QAbstractListModel {
|
||||
|
||||
public:
|
||||
|
||||
enum NoteRoles {
|
||||
IdRole = Qt::UserRole + 1,
|
||||
TitleRole
|
||||
};
|
||||
|
||||
NoteModel();
|
||||
int rowCount(const QModelIndex & parent = QModelIndex()) const;
|
||||
QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const;
|
||||
|
20
QtClient/JoplinQtClient/models/qmlnote.cpp
Executable file
20
QtClient/JoplinQtClient/models/qmlnote.cpp
Executable file
@ -0,0 +1,20 @@
|
||||
#include "qmlnote.h"
|
||||
|
||||
using namespace jop;
|
||||
|
||||
QmlNote::QmlNote() {}
|
||||
|
||||
QString QmlNote::title() const {
|
||||
return note_.title();
|
||||
}
|
||||
|
||||
QString QmlNote::body() const {
|
||||
return note_.body();
|
||||
}
|
||||
|
||||
void QmlNote::setNote(const Note ¬e) {
|
||||
note_ = note;
|
||||
emit changed();
|
||||
//emit titleChanged();
|
||||
//emit bodyChanged();
|
||||
}
|
37
QtClient/JoplinQtClient/models/qmlnote.h
Executable file
37
QtClient/JoplinQtClient/models/qmlnote.h
Executable file
@ -0,0 +1,37 @@
|
||||
#ifndef QMLNOTE_H
|
||||
#define QMLNOTE_H
|
||||
|
||||
#include <stable.h>
|
||||
#include "note.h"
|
||||
|
||||
namespace jop {
|
||||
|
||||
class QmlNote : public QObject {
|
||||
|
||||
Q_OBJECT
|
||||
|
||||
Q_PROPERTY(QString title READ title NOTIFY titleChanged)
|
||||
Q_PROPERTY(QString body READ body NOTIFY bodyChanged)
|
||||
|
||||
public:
|
||||
|
||||
QmlNote();
|
||||
QString title() const;
|
||||
QString body() const;
|
||||
void setNote(const Note& note);
|
||||
|
||||
signals:
|
||||
|
||||
void titleChanged();
|
||||
void bodyChanged();
|
||||
void changed();
|
||||
|
||||
private:
|
||||
|
||||
Note note_;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // QMLNOTE_H
|
@ -3,5 +3,6 @@
|
||||
<file>main.qml</file>
|
||||
<file>FolderList.qml</file>
|
||||
<file>NoteList.qml</file>
|
||||
<file>NoteEditor.qml</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
213
QtClient/JoplinQtClient/sparsevector.hpp
Executable file
213
QtClient/JoplinQtClient/sparsevector.hpp
Executable file
@ -0,0 +1,213 @@
|
||||
#ifndef SPARSEARRAY_HPP
|
||||
#define SPARSEARRAY_HPP
|
||||
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <math.h>
|
||||
|
||||
template <class ClassType> class SparseVector {
|
||||
|
||||
public:
|
||||
|
||||
SparseVector() {
|
||||
counter_ = -1;
|
||||
count_ = -1;
|
||||
}
|
||||
|
||||
ClassType get(int index) const {
|
||||
if (index > count()) return ClassType();
|
||||
if (!isset(index)) return ClassType();
|
||||
|
||||
typename IndexMap::const_iterator pos = indexes_.find(index);
|
||||
int valueIndex = pos->second.valueIndex;
|
||||
|
||||
typename std::map<int, ClassType>::const_iterator pos2 = values_.find(valueIndex);
|
||||
return pos2->second;
|
||||
}
|
||||
|
||||
void set(int index, ClassType value) {
|
||||
unset(index);
|
||||
int valueIndex = ++counter_;
|
||||
values_[valueIndex] = value;
|
||||
IndexRecord r;
|
||||
r.valueIndex = valueIndex;
|
||||
r.time = 0; // Disabled / not needed
|
||||
//r.time = time(0);
|
||||
indexes_[index] = r;
|
||||
count_ = -1;
|
||||
}
|
||||
|
||||
void push(ClassType value) {
|
||||
set(count(), value);
|
||||
}
|
||||
|
||||
bool isset(int index) const {
|
||||
return indexes_.find(index) != indexes_.end();
|
||||
}
|
||||
|
||||
std::vector<int> indexes() const {
|
||||
std::vector<int> output;
|
||||
for (typename IndexMap::const_iterator it = indexes_.begin(); it != indexes_.end(); ++it) {
|
||||
output.push_back(it->first);
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
// Unsets that particular index, but without shifting the following indexes
|
||||
void unset(int index) {
|
||||
if (!isset(index)) return;
|
||||
IndexRecord r = indexes_[index];
|
||||
values_.erase(r.valueIndex);
|
||||
indexes_.erase(index);
|
||||
}
|
||||
|
||||
void insert(int index, ClassType value) {
|
||||
IndexMap newIndexes;
|
||||
for (typename IndexMap::const_iterator it = indexes_.begin(); it != indexes_.end(); ++it) {
|
||||
ClassType key = it->first;
|
||||
if (key > index) key++;
|
||||
newIndexes[key] = it->second;
|
||||
}
|
||||
indexes_ = newIndexes;
|
||||
set(index, value);
|
||||
}
|
||||
|
||||
// Removes the element at that particular index, and shift all the following elements
|
||||
void remove(int index) {
|
||||
if (index > count()) return;
|
||||
|
||||
if (isset(index)) {
|
||||
int valueIndex = indexes_[index].valueIndex;
|
||||
values_.erase(valueIndex);
|
||||
}
|
||||
|
||||
IndexMap newIndexes;
|
||||
for (typename IndexMap::const_iterator it = indexes_.begin(); it != indexes_.end(); ++it) {
|
||||
ClassType key = it->first;
|
||||
if (key == index) continue;
|
||||
if (key > index) key--;
|
||||
newIndexes[key] = it->second;
|
||||
}
|
||||
indexes_ = newIndexes;
|
||||
count_ = -1;
|
||||
}
|
||||
|
||||
// Returns a vector containing the indexes that are not currently set around
|
||||
// the given index, up to bufferSize indexes.
|
||||
std::vector<int> availableBufferAround(int index, int bufferSize) const {
|
||||
std::vector<int> temp;
|
||||
|
||||
// Doesn't make sense to search for an empty buffer around
|
||||
// an index that is already set.
|
||||
if (isset(index)) return temp;
|
||||
|
||||
temp.push_back(index);
|
||||
|
||||
// Probably not the most efficient algorithm but it works:
|
||||
// First search 1 position to the left, then 1 position to the right,
|
||||
// then 2 to the left, etc. If encountering an unavailable index on one
|
||||
// of the side, the path is "blocked" and searching is now done in only
|
||||
// one direction. If both sides are blocked, the algorithm exit.
|
||||
|
||||
int inc = 1;
|
||||
int sign = -1;
|
||||
bool leftBlocked = false;
|
||||
bool rightBlocked = false;
|
||||
while (temp.size() < bufferSize) {
|
||||
int bufferIndex = index + (inc * sign);
|
||||
|
||||
bool blocked = isset(bufferIndex) || bufferIndex < 0;
|
||||
if (blocked) {
|
||||
if (sign < 0) {
|
||||
leftBlocked = true;
|
||||
} else {
|
||||
rightBlocked = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (leftBlocked && rightBlocked) break;
|
||||
|
||||
if (!blocked) temp.push_back(bufferIndex);
|
||||
|
||||
sign = -sign;
|
||||
if (sign < 0) inc++;
|
||||
if (leftBlocked && sign < 0) sign = 1;
|
||||
if (rightBlocked && sign > 0) sign = -1;
|
||||
}
|
||||
|
||||
std::sort(temp.begin(), temp.end());
|
||||
|
||||
return temp;
|
||||
}
|
||||
|
||||
int count() const {
|
||||
if (count_ >= 0) return count_;
|
||||
int maxKey = -1;
|
||||
for (typename IndexMap::const_iterator it = indexes_.begin(); it != indexes_.end(); ++it) {
|
||||
const int& key = it->first;
|
||||
if (key > maxKey) maxKey = key;
|
||||
}
|
||||
count_ = maxKey + 1;
|
||||
return count_;
|
||||
}
|
||||
|
||||
void clearOlderThan(time_t time) {
|
||||
IndexMap newIndexes;
|
||||
for (typename IndexMap::const_iterator it = indexes_.begin(); it != indexes_.end(); ++it) {
|
||||
const IndexRecord& r = it->second;
|
||||
if (r.time > time) {
|
||||
newIndexes[it->first] = r;
|
||||
} else {
|
||||
values_.erase(r.valueIndex);
|
||||
}
|
||||
}
|
||||
indexes_ = newIndexes;
|
||||
count_ = -1;
|
||||
}
|
||||
|
||||
// Unset all values outside of this interval
|
||||
void unsetAllButInterval(int intervalFrom, int intervalTo) {
|
||||
int count = this->count();
|
||||
for (int i = 0; i < count; i++) {
|
||||
if (i >= intervalFrom && i <= intervalTo) continue;
|
||||
unset(i);
|
||||
}
|
||||
}
|
||||
|
||||
void clear() {
|
||||
indexes_.clear();
|
||||
values_.clear();
|
||||
counter_ = 0;
|
||||
count_ = -1;
|
||||
}
|
||||
|
||||
void print() const {
|
||||
for (int i = 0; i < count(); i++) {
|
||||
std::cout << "|";
|
||||
std::cout << " " << get(i) << " ";
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
struct IndexRecord {
|
||||
int valueIndex;
|
||||
time_t time;
|
||||
};
|
||||
|
||||
typedef std::map<int, IndexRecord> IndexMap;
|
||||
|
||||
int counter_;
|
||||
IndexMap indexes_;
|
||||
std::map<int, ClassType> values_;
|
||||
|
||||
// This is used to cache the result of ::count().
|
||||
// Don't forget to set it to -1 whenever the list
|
||||
// size changes, so that it can be recalculated.
|
||||
mutable int count_;
|
||||
|
||||
};
|
||||
|
||||
#endif // SPARSEARRAY_HPP
|
Loading…
Reference in New Issue
Block a user