File indexing completed on 2024-05-05 04:48:30

0001 /****************************************************************************************
0002  * Copyright (c) 2008 Daniel Caleb Jones <danielcjones@gmail.com>                       *
0003  *                                                                                      *
0004  * This program is free software; you can redistribute it and/or modify it under        *
0005  * the terms of the GNU General Public License as published by the Free Software        *
0006  * Foundation; either version 2 of the License, or (at your option) version 3 or        *
0007  * any later version accepted by the membership of KDE e.V. (or its successor approved  *
0008  * by the membership of KDE e.V.), which shall act as a proxy defined in Section 14 of  *
0009  * version 3 of the license.                                                            *
0010  *                                                                                      *
0011  * This program is distributed in the hope that it will be useful, but WITHOUT ANY      *
0012  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A      *
0013  * PARTICULAR PURPOSE. See the GNU General Public License for more details.             *
0014  *                                                                                      *
0015  * You should have received a copy of the GNU General Public License along with         *
0016  * this program.  If not, see <http://www.gnu.org/licenses/>.                           *
0017  ****************************************************************************************/
0018 
0019 #ifndef AMAROK_TRACKSET_H
0020 #define AMAROK_TRACKSET_H
0021 
0022 #include "amarok_export.h"
0023 #include "core/meta/forward_declarations.h"
0024 
0025 #include <QBitArray>
0026 #include <QExplicitlySharedDataPointer>
0027 #include <QHash>
0028 #include <QMetaType>
0029 #include <QSharedData>
0030 #include <QString>
0031 #include <QStringList>
0032 
0033 namespace Dynamic
0034 {
0035     class TrackSet;
0036     class TrackCollection;
0037 
0038     typedef QExplicitlySharedDataPointer<TrackCollection> TrackCollectionPtr;
0039 
0040     /**
0041      * We keep a list here of the uid of every track in the set
0042      * collection being considered. This is unfortunately necessary
0043      * because the algorithm in generateInitialPlaylist performs many
0044      * set subtractions and intersections which would be impractical and
0045      * inefficient to perform using database queries. Instead we
0046      * represent a set of tracks as a bit list, where the n'th bit
0047      * indicates whether the n'th track in s_universe is included in the
0048      * set. Set operations can then be performed extremely quickly using
0049      * bitwise operations, rather than tree operations which QSet would
0050      * use.
0051      */
0052 
0053     /** The TrackCollection stores all the uids that a TrackSet can contain.
0054         Usually the dynamic playlist queries all the uids before computing a playlist.
0055     */
0056     class AMAROK_EXPORT TrackCollection : public QSharedData
0057     {
0058         public:
0059             explicit TrackCollection( const QStringList& uids );
0060 
0061             int count() const;
0062             QStringList uids() const;
0063 
0064         private:
0065             QStringList m_uids;
0066             QHash<QString, int> m_ids;
0067 
0068             friend class TrackSet;
0069     };
0070 
0071     /**
0072      * A representation of a set of tracks as a bit array, relative to the
0073      * given universe set.
0074      * Intersecting TrackSets from different universes is not a good idea.
0075      * The BiasSolver uses this class to do a lot of set operations.
0076      * QSet is more space efficient for sparse sets, but set
0077      * operations generally aren't linear.
0078      */
0079     class AMAROK_EXPORT TrackSet
0080     {
0081         public:
0082             /** Creates a TrackSet that is outstanding
0083                 @see isOutstanding() */
0084             TrackSet();
0085 
0086             TrackSet( const TrackSet& other );
0087 
0088             /** Creates a TrackSet that represents the whole universe.
0089              *  @param collection The collection of the tracks
0090              *  @param value If true set is set to "full". Else to "empty".
0091             */
0092             TrackSet( const Dynamic::TrackCollectionPtr &collection, bool value );
0093 
0094             /** Includes or excludes all tracks in the set.
0095                 @param value If true set is set to "full". Else to "empty".
0096             */
0097             void reset( bool value );
0098 
0099             /** Returns true if the results of this track set are not yet available */
0100             bool isOutstanding() const;
0101 
0102             /** The number of songs contained in this trackSet */
0103             int trackCount() const;
0104 
0105             /** True if none of the tracks are included in the set. */
0106             bool isEmpty() const;
0107 
0108             /** True if all of the tracks are included in the set. */
0109             bool isFull() const;
0110             bool contains( const Meta::TrackPtr& ) const;
0111 
0112             /** Returns true if the uid is included in the set */
0113             bool contains( const QString& uid ) const;
0114 
0115             /** Returns the uids of a random track contains in this set */
0116             QString getRandomTrack() const;
0117 
0118             void unite( const Meta::TrackPtr& );
0119             void unite( const TrackSet& );
0120             void unite( const QStringList& uids );
0121             void intersect( const TrackSet& );
0122             void intersect( const QStringList& uids );
0123             void subtract( const Meta::TrackPtr& );
0124             void subtract( const TrackSet& );
0125             void subtract( const QStringList& uids );
0126 
0127             TrackSet& operator=( const TrackSet& );
0128 
0129         private:
0130             QBitArray m_bits;
0131             TrackCollectionPtr m_collection;
0132     };
0133 }
0134 
0135 Q_DECLARE_METATYPE( Dynamic::TrackSet )
0136 
0137 #endif
0138