desktop/src/libsync/progressdispatcher.h

249 lines
6.5 KiB
C++

/*
* Copyright (C) by Klaas Freitag <freitag@owncloud.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*/
#ifndef PROGRESSDISPATCHER_H
#define PROGRESSDISPATCHER_H
#include "owncloudlib.h"
#include <QObject>
#include <QHash>
#include <QTime>
#include <QQueue>
#include <QElapsedTimer>
#include <QTimer>
#include <QDebug>
#include "syncfileitem.h"
namespace OCC {
/*!
* \brief The ProgressInfo class
* \ingroup libsync
*/
class OWNCLOUDSYNC_EXPORT ProgressInfo : public QObject
{
Q_OBJECT
public:
ProgressInfo()
: _totalSizeOfCompletedJobs(0)
, _maxFilesPerSecond(2.0)
, _maxBytesPerSecond(100000.0)
{}
/**
* Called when propagation starts.
*
* hasStarted() will return true afterwards.
*/
void start();
/**
* Returns true when propagation has started (start() was called).
*
* This is used when the SyncEngine wants to indicate a new sync
* is about to start via the transmissionProgress() signal. The
* first ProgressInfo will have hasStarted() == false.
*/
bool hasStarted() const;
/**
* Increase the file and size totals by the amount indicated in item.
*/
void adjustTotalsForFile(const SyncFileItem & item);
/**
* Adjust the total size by some value.
*
* Deprecated. Used only in the legacy propagator.
*/
void adjustTotalSize(qint64 change);
quint64 totalFiles() const;
quint64 completedFiles() const;
quint64 totalSize() const;
quint64 completedSize() const;
/** Number of a file that is currently in progress. */
quint64 currentFile() const;
/** Return true is the size need to be taken in account in the total amount of time */
static inline bool isSizeDependent(const SyncFileItem & item)
{
return ! item._isDirectory && (
item._instruction == CSYNC_INSTRUCTION_CONFLICT
|| item._instruction == CSYNC_INSTRUCTION_SYNC
|| item._instruction == CSYNC_INSTRUCTION_NEW);
}
/**
* Holds estimates about progress, returned to the user.
*/
struct Estimates
{
/// Estimated completion amount per second. (of bytes or files)
quint64 estimatedBandwidth;
/// Estimated eta in milliseconds.
quint64 estimatedEta;
};
/**
* Holds the current state of something making progress and maintains an
* estimate of the current progress per second.
*/
struct OWNCLOUDSYNC_EXPORT Progress
{
Progress()
: _progressPerSec(0)
, _completed(0)
, _prevCompleted(0)
, _total(0)
, _initialSmoothing(1.0)
{
}
/** Returns the estimates about progress per second and eta. */
Estimates estimates() const;
quint64 completed() const;
quint64 remaining() const;
private:
/**
* Update the exponential moving average estimate of _progressPerSec.
*/
void update();
double _progressPerSec;
quint64 _completed;
quint64 _prevCompleted;
quint64 _total;
// Used to get to a good value faster when
// progress measurement stats. See update().
double _initialSmoothing;
friend class ProgressInfo;
};
struct OWNCLOUDSYNC_EXPORT ProgressItem
{
SyncFileItem _item;
Progress _progress;
};
QHash<QString, ProgressItem> _currentItems;
SyncFileItem _lastCompletedItem;
// Used during local and remote update phase
QString _currentDiscoveredFolder;
void setProgressComplete(const SyncFileItem &item);
void setProgressItem(const SyncFileItem &item, quint64 size);
/**
* Get the total completion estimate
*/
Estimates totalProgress() const;
/**
* Get the current file completion estimate structure
*/
Estimates fileProgress(const SyncFileItem &item) const;
private slots:
/**
* Called every second once started, this function updates the
* estimates.
*/
void updateEstimates();
private:
// Sets the completed size by summing finished jobs with the progress
// of active ones.
void recomputeCompletedSize();
// Triggers the update() slot every second once propagation started.
QTimer _updateEstimatesTimer;
Progress _sizeProgress;
Progress _fileProgress;
// All size from completed jobs only.
quint64 _totalSizeOfCompletedJobs;
// The fastest observed rate of files per second in this sync.
double _maxFilesPerSecond;
double _maxBytesPerSecond;
};
namespace Progress {
OWNCLOUDSYNC_EXPORT QString asActionString( const SyncFileItem& item );
OWNCLOUDSYNC_EXPORT QString asResultString( const SyncFileItem& item );
OWNCLOUDSYNC_EXPORT bool isWarningKind( SyncFileItem::Status );
OWNCLOUDSYNC_EXPORT bool isIgnoredKind( SyncFileItem::Status );
}
/**
* @file progressdispatcher.h
* @brief A singleton class to provide sync progress information to other gui classes.
*
* How to use the ProgressDispatcher:
* Just connect to the two signals either to progress for every individual file
* or the overall sync progress.
*
*/
class OWNCLOUDSYNC_EXPORT ProgressDispatcher : public QObject
{
Q_OBJECT
friend class Folder; // only allow Folder class to access the setting slots.
public:
static ProgressDispatcher* instance();
~ProgressDispatcher();
signals:
/**
@brief Signals the progress of data transmission.
@param[out] folder The folder which is being processed
@param[out] progress A struct with all progress info.
*/
void progressInfo( const QString& folder, const ProgressInfo& progress );
/**
* @brief: the item's job is completed
*/
void jobCompleted(const QString &folder, const SyncFileItem & item);
void syncItemDiscovered(const QString &folder, const SyncFileItem & item);
protected:
void setProgressInfo(const QString& folder, const ProgressInfo& progress);
private:
ProgressDispatcher(QObject* parent = 0);
QElapsedTimer _timer;
static ProgressDispatcher* _instance;
};
}
#endif // PROGRESSDISPATCHER_H