Logo Search packages:      
Sourcecode: kat version File versions  Download package

katscheduler.cpp

/***************************************************************************
 *   Copyright (C) 2005 by Roberto Cappuccio and the Kat team              *
 *   Roberto Cappuccio : roberto.cappuccio@gmail.com                       *
 *   Praveen Kandikuppa : praveen9@gmail.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; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   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.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   51 Franklin Steet, Fifth Floor, Boston, MA 02110-1301, USA.           *
 ***************************************************************************/

#include <qptrqueue.h>
#include <qguardedptr.h>
#include <qapplication.h>
#include <kdebug.h>

#include "katdaemonevents.h"
#include "katindexer.h"
#include "katscheduler.h"

extern bool ddebug;

class IndexerItem
{
public:
    IndexerItem( KatIndexer* indexer, int catalogId )
    {
        m_indexer = indexer;
        m_catalogId = catalogId;
    }
    ~IndexerItem() {};

    QGuardedPtr<KatIndexer> m_indexer;
    int m_catalogId;
};

typedef QPtrQueue<IndexerItem> IndexerList;
typedef QMap<KatScheduler::Priority,IndexerList> SchedulerMap;

class KatSchedulerPrivate
{
public:
    SchedulerMap m_indexers;
};

KatScheduler::KatScheduler( int load, int maxWait )
    : QObject( 0, "katscheduler" ),
      m_lastTime( 0 ), m_nIndexers( 0 ), m_lock( false ), m_load( load ), m_maxWait( maxWait*1000 )
{
    d = new KatSchedulerPrivate();

    d->m_indexers.insert( KatScheduler::Immediate, QPtrQueue<IndexerItem>() );
    d->m_indexers.insert( KatScheduler::Normal, QPtrQueue<IndexerItem>() );
    d->m_indexers.insert( KatScheduler::Idle, QPtrQueue<IndexerItem>() );

    m_lockedCatalog = 0;
}

KatScheduler::~KatScheduler()
{
    delete d;
    d = 0;
};

int KatScheduler::requestLock( KatIndexer* indexer, int catalogId, Priority pri )
{
    kdDebug( ) << k_funcinfo << endl;
    if ( !m_nIndexers && !m_lock )
    {
        int waitTime = 0;

        if ( pri != KatScheduler::Immediate )
            waitTime = getWaitTime();

        m_schedMutex.lock();
        m_lock = true;
        m_lockedCatalog = catalogId;
        m_schedMutex.unlock();

        kdDebug() << " No indexers/No lock .. scheduling this indexer immediately after " << waitTime << " msecs." << endl;

        return waitTime;
    }
    else
    {
        kdDebug() << " Indexer queue is not empty .. queueing this indexer" << endl;
        m_schedMutex.lock();
        d->m_indexers[pri].enqueue( new IndexerItem(indexer, catalogId ) );
        d->m_indexers[pri].setAutoDelete( true );
        m_nIndexers++;
        m_schedMutex.unlock();
        return -1;
    }
}

void KatScheduler::releaseLock( int catalogId, int processTime )
{
    KatIndexer* indexer = 0;
    Priority pri = Immediate;

    if ( !m_lock )
    {
        kdDebug() << "No lock is in place - no indexers to be scheduled " << endl;
        return;
    }

    if ( m_lockedCatalog && catalogId != m_lockedCatalog )
    {
        kdDebug() << " Spurious releaseLock encountered from " << catalogId << " - locked by catalog " << m_lockedCatalog << endl;
        return;
    }

    if ( processTime )
        m_lastTime = processTime;

    m_schedMutex.lock();

    // Clear the lock
    m_lock = false;
    m_lockedCatalog = 0;

    // Find the next indexer to dispatch
    SchedulerMap::Iterator mit = d->m_indexers.find( KatScheduler::Immediate );
    if ( mit != d->m_indexers.end() )
    {
        while ( !indexer && !mit.data().isEmpty() )
        {
            IndexerItem *iitem = mit.data().dequeue();
            if ( iitem )
            {
                indexer = iitem->m_indexer;
                catalogId = iitem->m_catalogId;
                pri = KatScheduler::Immediate;
            }

            delete iitem;
            iitem = 0;
            m_nIndexers--;
        }
    }

    if ( !indexer )
    {
        mit = d->m_indexers.find( KatScheduler::Normal );
        if ( mit != d->m_indexers.end() )
        {
            while ( !indexer && !mit.data().isEmpty() )
            {
                IndexerItem *iitem = mit.data().dequeue();
                if ( iitem )
                {
                    indexer = iitem->m_indexer;
                    catalogId = iitem->m_catalogId;
                    pri = KatScheduler::Normal;
                }

                delete iitem;
                iitem = 0;
                m_nIndexers--;
            }
        }
    }

    if ( !indexer )
    {
        mit = d->m_indexers.find( KatScheduler::Idle );
        if ( mit != d->m_indexers.end() )
        {
            while ( !indexer && !mit.data().isEmpty() )
            {
                IndexerItem *iitem = mit.data().dequeue();
                if ( iitem )
                {
                    indexer = iitem->m_indexer;
                    catalogId = iitem->m_catalogId;
                    pri = KatScheduler::Idle;
                }

                delete iitem;
                iitem = 0;
                m_nIndexers--;
            }
        }
    }

    m_schedMutex.unlock();

    if ( indexer )
    {
        if ( pri == KatScheduler::Immediate )
        {
            kdDebug() << " Last schedule job finished in " << m_lastTime << " scheduling next job for " << catalogId << " immediately " << endl;
            m_schedMutex.lock();
            m_lock = true;
            m_lockedCatalog = catalogId;
            m_schedMutex.unlock();
            QApplication::postEvent( indexer, new ScheduleEvent ( 0 ) );
        }
        else
        {
            int waitTime = getWaitTime();
            kdDebug() << " Last schedule job finished in " << m_lastTime << " scheduling next job for " << catalogId << " in " << waitTime << endl;
            m_schedMutex.lock();
            m_lock = true;
            m_lockedCatalog = catalogId;
            m_schedMutex.unlock();
            QApplication::postEvent( indexer, new ScheduleEvent ( waitTime ) );
        }
    }
    else
        kdDebug() << " No indexers found to be dispatched" << endl;
}

void KatScheduler::setLoad( int load )
{
    if ( ( load < 1 ) || ( load > 100 ) )
        kdDebug() << "load to be set must be between 1 and 100" << endl;
    else
        m_load = load;
}

int KatScheduler::load() const
{
    return m_load;
}

void KatScheduler::setMaxWait( int _wait )
{
    if ( _wait <1 || _wait > 1000 )
        kdDebug() << "max wait to be set must be between 1 and 1000" << endl;
    else
        m_maxWait =  _wait*1000;
}

int KatScheduler::maxWait() const
{
    return ( m_maxWait/1000 );
}

// TODO - modulate this with the amount of wait time
int KatScheduler::getWaitTime()
{
    if ( ( m_load == 100 ) || !m_lastTime )
        return 0;
    else
    {
        int waitTime = m_lastTime * ( 100 - m_load ) / m_load;
        if ( ( m_maxWait > 0 ) && ( waitTime > m_maxWait ) )
            waitTime = m_maxWait;
        return waitTime;
    }
}

Generated by  Doxygen 1.6.0   Back to index