[vlc-devel] [PATCH v2 06/13] qt: medialib: use list cache from MLBaseModel
Romain Vimont
rom1v at videolabs.io
Thu Nov 26 17:10:38 CET 2020
Use the new list cache. For now, the cache loader just delegates calls
to the model.
---
modules/gui/qt/medialibrary/mlbasemodel.cpp | 8 ++
modules/gui/qt/medialibrary/mlbasemodel.hpp | 138 ++++++++++++++------
2 files changed, 106 insertions(+), 40 deletions(-)
diff --git a/modules/gui/qt/medialibrary/mlbasemodel.cpp b/modules/gui/qt/medialibrary/mlbasemodel.cpp
index 97c9341b1d..24d1362078 100644
--- a/modules/gui/qt/medialibrary/mlbasemodel.cpp
+++ b/modules/gui/qt/medialibrary/mlbasemodel.cpp
@@ -66,6 +66,14 @@ void MLBaseModel::onResetRequested()
endResetModel();
}
+void MLBaseModel::onLocalDataChanged(size_t offset, size_t count)
+{
+ assert(count);
+ auto first = index(offset);
+ auto last = index(offset + count - 1);
+ emit dataChanged(first, last);
+}
+
void MLBaseModel::onVlcMlEvent(const MLEvent &event)
{
switch(event.i_type)
diff --git a/modules/gui/qt/medialibrary/mlbasemodel.hpp b/modules/gui/qt/medialibrary/mlbasemodel.hpp
index 093e8c774f..15930aaf63 100644
--- a/modules/gui/qt/medialibrary/mlbasemodel.hpp
+++ b/modules/gui/qt/medialibrary/mlbasemodel.hpp
@@ -33,6 +33,7 @@
#include <memory>
#include "mlevent.hpp"
#include "mlqueryparams.hpp"
+#include "util/listcache.hpp"
class MediaLib;
@@ -69,6 +70,7 @@ signals:
protected slots:
void onResetRequested();
+ void onLocalDataChanged(size_t index, size_t count);
private:
static void onVlcMlEvent( void* data, const vlc_ml_event_t* event );
@@ -131,13 +133,11 @@ template <typename T>
class MLSlidingWindowModel : public MLBaseModel
{
public:
- static constexpr size_t BatchSize = 100;
+ static constexpr ssize_t COUNT_UNINITIALIZED =
+ ListCache<std::unique_ptr<T>>::COUNT_UNINITIALIZED;
MLSlidingWindowModel(QObject* parent = nullptr)
: MLBaseModel(parent)
- , m_initialized(false)
- , m_total_count(0)
- , m_offset(0)
{
}
@@ -146,24 +146,15 @@ public:
if (parent.isValid())
return 0;
- if ( m_initialized == false )
- {
- MLQueryParams params{ m_search_pattern.toUtf8(), m_sort, m_sort_desc };
- m_total_count = countTotalElements(params);
- m_initialized = true;
- emit countChanged( static_cast<unsigned int>(m_total_count) );
- }
+ validateCache();
- return m_total_count;
+ return m_cache->count();
}
void clear() override
{
- m_offset = 0;
- m_initialized = false;
- m_total_count = 0;
- m_item_list.clear();
- emit countChanged( static_cast<unsigned int>(m_total_count) );
+ invalidateCache();
+ emit countChanged( static_cast<unsigned int>(0) );
}
@@ -215,30 +206,50 @@ public:
}
unsigned int getCount() const override {
- return static_cast<unsigned int>(m_total_count);
+ if (!m_cache || m_cache->count() == COUNT_UNINITIALIZED)
+ return 0;
+ return static_cast<unsigned int>(m_cache->count());
}
protected:
+ void validateCache() const
+ {
+ if (m_cache)
+ return;
+
+ auto loader = std::make_unique<Loader>(*this);
+ m_cache.reset(new ListCache<std::unique_ptr<T>>(std::move(loader)));
+ connect(&*m_cache, &BaseListCache::localDataChanged,
+ this, &MLBaseModel::onLocalDataChanged);
+
+ m_cache->initCount();
+ emit countChanged( static_cast<unsigned int>(m_cache->count()) );
+ }
+
+ void invalidateCache()
+ {
+ m_cache.reset();
+ }
+
T* item(int signedidx) const
{
- if (!m_initialized || signedidx < 0)
- return nullptr;
+ validateCache();
- unsigned int idx = static_cast<unsigned int>(signedidx);
- if ( idx >= m_total_count )
+ ssize_t count = m_cache->count();
+ if (count == COUNT_UNINITIALIZED || signedidx < 0
+ || signedidx >= count)
return nullptr;
- if ( idx < m_offset || idx >= m_offset + m_item_list.size() )
- {
- m_offset = idx - idx % BatchSize;
- MLQueryParams params{ m_search_pattern.toUtf8(), m_sort, m_sort_desc, m_offset, BatchSize };
- m_item_list = fetch(params);
- }
+ unsigned int idx = static_cast<unsigned int>(signedidx);
+ m_cache->refer(idx);
- //db has changed
- if ( idx >= m_offset + m_item_list.size() || idx < m_offset )
+ const std::unique_ptr<T> *item = m_cache->get(idx);
+ if (!item)
+ /* Not in cache */
return nullptr;
- return m_item_list[idx - m_offset].get();
+
+ /* Return raw pointer */
+ return item->get();
}
virtual void onVlcMlEvent(const MLEvent &event) override
@@ -248,13 +259,27 @@ protected:
case VLC_ML_EVENT_MEDIA_THUMBNAIL_GENERATED:
{
if (event.media_thumbnail_generated.b_success) {
- int idx = static_cast<int>(m_offset);
- for ( const auto& it : m_item_list ) {
- if (it->getId().id == event.media_thumbnail_generated.i_media_id) {
- thumbnailUpdated(idx);
+ if (!m_cache)
+ break;
+
+ ssize_t stotal = m_cache->count();
+ if (stotal == COUNT_UNINITIALIZED)
+ break;
+
+ size_t total = static_cast<size_t>(stotal);
+ for (size_t i = 0; i < total; ++i)
+ {
+ const std::unique_ptr<T> *item = m_cache->get(i);
+ if (!item)
+ /* Only consider items available locally in cache */
+ break;
+
+ T *localItem = item->get();
+ if (localItem->getId().id == event.media_thumbnail_generated.i_media_id)
+ {
+ thumbnailUpdated(i);
break;
}
- idx += 1;
}
}
break;
@@ -270,10 +295,43 @@ private:
virtual std::vector<std::unique_ptr<T>> fetch(const MLQueryParams ¶ms) const = 0;
virtual void thumbnailUpdated( int ) {}
- mutable std::vector<std::unique_ptr<T>> m_item_list;
- mutable bool m_initialized;
- mutable size_t m_total_count;
- mutable size_t m_offset; /* offset of m_item_list in the global list */
+ /* Data loader for the cache */
+ struct Loader : public ListCacheLoader<std::unique_ptr<T>>
+ {
+ Loader(const MLSlidingWindowModel &model)
+ : m_model(model)
+ , m_searchPattern(model.m_search_pattern)
+ , m_sort(model.m_sort)
+ , m_sort_desc(model.m_sort_desc)
+ {
+ }
+
+ size_t count() const override;
+ std::vector<std::unique_ptr<T>> load(size_t index, size_t count) const override;
+
+ private:
+ const MLSlidingWindowModel &m_model;
+ QString m_searchPattern;
+ vlc_ml_sorting_criteria_t m_sort;
+ bool m_sort_desc;
+ };
+
+ mutable std::unique_ptr<ListCache<std::unique_ptr<T>>> m_cache;
};
+template <typename T>
+size_t MLSlidingWindowModel<T>::Loader::count() const
+{
+ MLQueryParams params{ m_searchPattern.toUtf8(), m_sort, m_sort_desc };
+ return m_model.countTotalElements(params);
+}
+
+template <typename T>
+std::vector<std::unique_ptr<T>>
+MLSlidingWindowModel<T>::Loader::load(size_t index, size_t count) const
+{
+ MLQueryParams params{ m_searchPattern.toUtf8(), m_sort, m_sort_desc, index, count };
+ return m_model.fetch(params);
+}
+
#endif // MLBASEMODEL_HPP
--
2.29.2
More information about the vlc-devel
mailing list