blob: ebe991b0addf1c9488d1524707b288e4f4ea1a75 [file] [log] [blame]
/* ------------------------------------------------------------------
* Copyright (C) 2008 PacketVideo
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied.
* See the License for the specific language governing permissions
* and limitations under the License.
* -------------------------------------------------------------------
*/
// -*- c++ -*-
// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
// O S C L _ P R I Q U E U E ( P R I O R I T Y Q U E U E )
// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
/*! \addtogroup osclutil OSCL Util
*
* @{
*/
#ifndef OSCL_PRIQUEUE_H_INCLUDED
#define OSCL_PRIQUEUE_H_INCLUDED
/*!
* \file oscl_priqueue.h
* \brief Implements a priority queue data structure similar to STL.
*
* Implements a priority queue data structure similar to the STL class.
* The properties of the class include O(Log_2(N))
* insertion and deletion complexity and O(1) complexity
* to access the top priority item.
*
*/
#ifndef OSCL_BASE_H_INCLUDED
#include "oscl_base.h"
#endif
#ifndef OSCL_VECTOR_H_INCLUDED
#include "oscl_vector.h"
#endif
/**
* OsclPriorityQueueBase is a non-templatized base class for OsclPriorityQueue.
* The purpose of this base class is to avoid large inline routines
* in the OsclPriorityQueue implementation.
* This class is not intended for direct instantiation except by
* OsclPriorityQueue.
*/
class OsclPriorityQueueBase
{
protected:
virtual ~OsclPriorityQueueBase()
{}
OSCL_IMPORT_REF void push_heap(OsclAny* first, OsclAny* last) ;
OSCL_IMPORT_REF void pop_heap(OsclAny* first, OsclAny* last) ;
OSCL_IMPORT_REF OsclAny* find_heap(const OsclAny* input, OsclAny* first, OsclAny* last) ;
OSCL_IMPORT_REF int remove(const OsclAny* input) ;
void construct(Oscl_Opaque_Type_Compare* ot, Oscl_Vector_Base* vec)
{
pOpaqueType = ot;
pVec = vec;
}
private:
//return delta from "first" to "last" expressed as a number of T elements.
int delta_T(OsclAny*first, OsclAny*last)
{
return ((int)last -(int)first) / pVec->sizeof_T;
}
Oscl_Opaque_Type_Compare* pOpaqueType;
Oscl_Vector_Base* pVec;
};
template < class T> class OsclCompareLess
{
public:
int compare(T& a, T& b) const
{
return (a < b);
}
};
template < class Qelem, class Alloc,
class Container = Oscl_Vector<Qelem, Alloc>,
class Compare = OsclCompareLess<Qelem> >
class OsclPriorityQueue : public OsclPriorityQueueBase
, public Oscl_Opaque_Type_Compare
{
public:
typedef typename Container::value_type value_type;
typedef Container container_type;
typedef typename Container::iterator iterator;
typedef typename Container::const_reference const_reference;
bool empty() const
{
return c.empty();
};
uint32 size() const
{
return c.size();
};
void reserve(uint32 n)
{
c.reserve(n);
};
const_reference top() const
{
return c.front();
};
void push(const value_type& input)
{
c.push_back(input);
push_heap(c.begin(), c.end());
}
//remove top element
void pop()
{
pop_heap(c.begin(), c.end());
c.pop_back();
}
//Remove an arbitrary element, by value.
//If there are multiple matches, this removes the first one it finds.
//Returns number of items removed(either 0 or 1).
int remove(const value_type& input)
{
return OsclPriorityQueueBase::remove(&input);
}
//Constructor
OsclPriorityQueue(): OsclPriorityQueueBase(), Oscl_Opaque_Type_Compare()
, c()
{
OsclPriorityQueueBase::construct(this, &c);
}
virtual ~OsclPriorityQueue()
{}
protected:
Container c;
Compare comp;
void push_heap(iterator first, iterator last)
{
OsclPriorityQueueBase::push_heap(first, last);
}
void pop_heap(iterator first, iterator last)
{
OsclPriorityQueueBase::pop_heap(first, last);
}
iterator find_heap(const value_type& input, iterator first, iterator last)
{
return OsclPriorityQueueBase::find_heap(&input, first, last);
}
//a debug routine for validating the current sort.
int validate()
{
unsigned int ch;
for (unsigned int par = 0;par < c.size();par++)
{
ch = 2 * par + 1;
if (ch < c.size() && comp.compare(c[par], c[ch]))
return par;//error-- parent<child
ch++;
if (ch < c.size() && comp.compare(c[par], c[ch]))
return par;//error-- parent<child
}
return -1;//ok
}
//a debug routine for direct access to the contents of the Oscl_Vector.
const Container & vec()
{
return c;
}
friend class oscl_priqueue_test;
//from Oscl_Opaque_Type_Compare
void swap(OsclAny* dest, const OsclAny* src)
{
OSCL_ASSERT(dest);
OSCL_ASSERT(src);
if (dest != src)
{
value_type temp(*((value_type*)dest));
*((value_type*)dest) = *((value_type*)src);
*((value_type*)src) = temp;
}
}
//from Oscl_Opaque_Type_Compare
int compare_LT(OsclAny* a, OsclAny* b) const
{
OSCL_ASSERT(a);
OSCL_ASSERT(b);
return comp.compare(*((value_type*)a), *((value_type*)b));
}
//from Oscl_Opaque_Type_Compare
int compare_EQ(const OsclAny* a, const OsclAny* b) const
{
OSCL_ASSERT(a);
OSCL_ASSERT(b);
return (*((value_type*)a)) == (*((value_type*)b));
}
};
#endif
/*! @} */