/*
-Minetest-c55
-Copyright (C) 2010-2012 celeron55, Perttu Ahola <celeron55@gmail.com>
+Minetest
+Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
#define UTIL_CONTAINER_HEADER
#include "../irrlichttypes.h"
-#include <jmutex.h>
-#include <jmutexautolock.h>
-#include "../porting.h" // For sleep_ms
+#include "../exceptions.h"
+#include "../jthread/jmutex.h"
+#include "../jthread/jmutexautolock.h"
+#include "../jthread/jsemaphore.h"
+#include <list>
+#include <vector>
+#include <map>
/*
Queue with unique values with fast checking of value existence
bool push_back(Value value)
{
// Check if already exists
- if(m_map.find(value) != NULL)
+ if(m_map.find(value) != m_map.end())
return false;
// Add
- m_map.insert(value, 0);
+ m_map[value] = 0;
m_list.push_back(value);
return true;
Value pop_front()
{
- typename core::list<Value>::Iterator i = m_list.begin();
+ typename std::list<Value>::iterator i = m_list.begin();
Value value = *i;
- m_map.remove(value);
+ m_map.erase(value);
m_list.erase(i);
return value;
}
u32 size()
{
- assert(m_list.size() == m_map.size());
- return m_list.size();
+ return m_map.size();
}
private:
- core::map<Value, u8> m_map;
- core::list<Value> m_list;
+ std::map<Value, u8> m_map;
+ std::list<Value> m_list;
};
#if 1
public:
MutexedMap()
{
- m_mutex.Init();
- assert(m_mutex.IsInitialized());
}
void set(const Key &name, const Value &value)
{
JMutexAutoLock lock(m_mutex);
- typename core::map<Key, Value>::Node *n;
+ typename std::map<Key, Value>::iterator n;
n = m_values.find(name);
- if(n == NULL)
+ if(n == m_values.end())
return false;
if(result != NULL)
- *result = n->getValue();
+ *result = n->second;
return true;
}
+ std::list<Value> getValues()
+ {
+ std::list<Value> result;
+ for(typename std::map<Key, Value>::iterator
+ i = m_values.begin();
+ i != m_values.end(); ++i){
+ result.push_back(i->second);
+ }
+ return result;
+ }
+
+ void clear ()
+ {
+ m_values.clear();
+ }
+
private:
- core::map<Key, Value> m_values;
+ std::map<Key, Value> m_values;
JMutex m_mutex;
};
#endif
public:
MutexedIdGenerator()
{
- m_mutex.Init();
- assert(m_mutex.IsInitialized());
}
// Returns true if found
u32 getId(const T &value)
{
JMutexAutoLock lock(m_mutex);
- typename core::map<T, u32>::Node *n;
+ typename std::map<T, u32>::iterator n;
n = m_value_to_id.find(value);
- if(n != NULL)
- return n->getValue();
+ if(n != m_value_to_id.end())
+ return n->second;
m_id_to_value.push_back(value);
u32 new_id = m_id_to_value.size();
m_value_to_id.insert(value, new_id);
private:
JMutex m_mutex;
// Values are stored here at id-1 position (id 1 = [0])
- core::array<T> m_id_to_value;
- core::map<T, u32> m_value_to_id;
+ std::vector<T> m_id_to_value;
+ std::map<T, u32> m_value_to_id;
};
/*
class Queue
{
public:
+ Queue():
+ m_list_size(0)
+ {}
+
void push_back(T t)
{
m_list.push_back(t);
+ ++m_list_size;
}
+ void push_front(T t)
+ {
+ m_list.push_front(t);
+ ++m_list_size;
+ }
+
T pop_front()
{
- if(m_list.size() == 0)
+ if(m_list.empty())
throw ItemNotFoundException("Queue: queue is empty");
- typename core::list<T>::Iterator begin = m_list.begin();
+ typename std::list<T>::iterator begin = m_list.begin();
T t = *begin;
m_list.erase(begin);
+ --m_list_size;
return t;
}
T pop_back()
{
- if(m_list.size() == 0)
+ if(m_list.empty())
throw ItemNotFoundException("Queue: queue is empty");
- typename core::list<T>::Iterator last = m_list.getLast();
+ typename std::list<T>::iterator last = m_list.back();
T t = *last;
m_list.erase(last);
+ --m_list_size;
return t;
}
u32 size()
{
- return m_list.size();
+ return m_list_size;
+ }
+
+ bool empty()
+ {
+ return m_list.empty();
}
protected:
- core::list<T> m_list;
+ std::list<T> m_list;
+ u32 m_list_size;
};
/*
class MutexedQueue
{
public:
+ template<typename Key, typename U, typename Caller, typename CallerData>
+ friend class RequestQueue;
+
MutexedQueue()
{
- m_mutex.Init();
}
- u32 size()
+ bool empty()
{
JMutexAutoLock lock(m_mutex);
- return m_list.size();
+ return (m_size.GetValue() == 0);
}
void push_back(T t)
{
JMutexAutoLock lock(m_mutex);
m_list.push_back(t);
+ m_size.Post();
+ }
+
+ /* this version of pop_front returns a empty element of T on timeout.
+ * Make sure default constructor of T creates a recognizable "empty" element
+ */
+ T pop_frontNoEx(u32 wait_time_max_ms)
+ {
+ if (m_size.Wait(wait_time_max_ms))
+ {
+ JMutexAutoLock lock(m_mutex);
+
+ typename std::list<T>::iterator begin = m_list.begin();
+ T t = *begin;
+ m_list.erase(begin);
+ return t;
+ }
+ else
+ {
+ return T();
+ }
}
- T pop_front(u32 wait_time_max_ms=0)
+
+ T pop_front(u32 wait_time_max_ms)
{
- u32 wait_time_ms = 0;
+ if (m_size.Wait(wait_time_max_ms))
+ {
+ JMutexAutoLock lock(m_mutex);
- for(;;)
+ typename std::list<T>::iterator begin = m_list.begin();
+ T t = *begin;
+ m_list.erase(begin);
+ return t;
+ }
+ else
{
- {
- JMutexAutoLock lock(m_mutex);
-
- if(m_list.size() > 0)
- {
- typename core::list<T>::Iterator begin = m_list.begin();
- T t = *begin;
- m_list.erase(begin);
- return t;
- }
-
- if(wait_time_ms >= wait_time_max_ms)
- throw ItemNotFoundException("MutexedQueue: queue is empty");
- }
-
- // Wait a while before trying again
- sleep_ms(10);
- wait_time_ms += 10;
+ throw ItemNotFoundException("MutexedQueue: queue is empty");
}
}
+
+ T pop_frontNoEx()
+ {
+ m_size.Wait();
+
+ JMutexAutoLock lock(m_mutex);
+
+ typename std::list<T>::iterator begin = m_list.begin();
+ T t = *begin;
+ m_list.erase(begin);
+ return t;
+ }
+
T pop_back(u32 wait_time_max_ms=0)
{
- u32 wait_time_ms = 0;
+ if (m_size.Wait(wait_time_max_ms))
+ {
+ JMutexAutoLock lock(m_mutex);
- for(;;)
+ typename std::list<T>::iterator last = m_list.end();
+ last--;
+ T t = *last;
+ m_list.erase(last);
+ return t;
+ }
+ else
{
- {
- JMutexAutoLock lock(m_mutex);
-
- if(m_list.size() > 0)
- {
- typename core::list<T>::Iterator last = m_list.getLast();
- T t = *last;
- m_list.erase(last);
- return t;
- }
-
- if(wait_time_ms >= wait_time_max_ms)
- throw ItemNotFoundException("MutexedQueue: queue is empty");
- }
-
- // Wait a while before trying again
- sleep_ms(10);
- wait_time_ms += 10;
+ throw ItemNotFoundException("MutexedQueue: queue is empty");
}
}
+ /* this version of pop_back returns a empty element of T on timeout.
+ * Make sure default constructor of T creates a recognizable "empty" element
+ */
+ T pop_backNoEx(u32 wait_time_max_ms=0)
+ {
+ if (m_size.Wait(wait_time_max_ms))
+ {
+ JMutexAutoLock lock(m_mutex);
+
+ typename std::list<T>::iterator last = m_list.end();
+ last--;
+ T t = *last;
+ m_list.erase(last);
+ return t;
+ }
+ else
+ {
+ return T();
+ }
+ }
+
+ T pop_backNoEx()
+ {
+ m_size.Wait();
+
+ JMutexAutoLock lock(m_mutex);
+
+ typename std::list<T>::iterator last = m_list.end();
+ last--;
+ T t = *last;
+ m_list.erase(last);
+ return t;
+ }
+
+protected:
JMutex & getMutex()
{
return m_mutex;
}
- core::list<T> & getList()
+ // NEVER EVER modify the >>list<< you got by using this function!
+ // You may only modify it's content
+ std::list<T> & getList()
{
return m_list;
}
-protected:
JMutex m_mutex;
- core::list<T> m_list;
+ std::list<T> m_list;
+ JSemaphore m_size;
};
#endif