initial commit
This commit is contained in:
commit
4b60ece582
327 changed files with 28286 additions and 0 deletions
316
lib/wModel/icatalogue.h
Normal file
316
lib/wModel/icatalogue.h
Normal file
|
@ -0,0 +1,316 @@
|
|||
#ifndef ICATALOGUE_H
|
||||
#define ICATALOGUE_H
|
||||
|
||||
#include "model.h"
|
||||
|
||||
#include <set>
|
||||
#include <map>
|
||||
|
||||
#include <wModel/vocabulary.h>
|
||||
#include <utils/exception.h>
|
||||
|
||||
namespace M {
|
||||
class ICatalogue : public M::Model
|
||||
{
|
||||
Q_OBJECT
|
||||
protected:
|
||||
class AbstractIndex;
|
||||
public:
|
||||
ICatalogue(const W::Address p_address, QObject* parent = 0);
|
||||
~ICatalogue();
|
||||
|
||||
virtual uint64_t addElement(const W::Vocabulary& record);
|
||||
virtual void removeElement(uint64_t id);
|
||||
virtual W::Vocabulary* getElement(uint64_t id) = 0;
|
||||
virtual void modifyElement(uint64_t id, const W::Vocabulary& newValue) = 0;
|
||||
virtual uint64_t size() const = 0;
|
||||
virtual void clear();
|
||||
|
||||
virtual void addIndex(const W::String& fieldName, W::Object::objectType fieldType);
|
||||
const std::set<uint64_t>& find(const W::String& indexName, const W::Object& value) const;
|
||||
std::set<uint64_t> find(const W::Vocabulary& value) const;
|
||||
|
||||
M::Model::ModelType getType() const override;
|
||||
static const M::Model::ModelType type = catalogue;
|
||||
void set(const W::Object & value) override;
|
||||
void set(W::Object * value) override;
|
||||
|
||||
W::Handler* subscribeMember;
|
||||
handler(subscribeMember);
|
||||
|
||||
static bool match(const W::Vocabulary& value, const W::Vocabulary& filter);
|
||||
static const std::set<uint64_t> empty;
|
||||
|
||||
signals:
|
||||
void countChange(uint64_t count);
|
||||
|
||||
protected:
|
||||
virtual std::set<uint64_t> getAll() const = 0;
|
||||
void h_subscribe(const W::Event & ev) override;
|
||||
|
||||
handler(get);
|
||||
handler(add);
|
||||
handler(update);
|
||||
|
||||
typedef std::map<W::String, AbstractIndex*> IndexMap;
|
||||
IndexMap indexes;
|
||||
|
||||
private:
|
||||
uint64_t lastIndex;
|
||||
std::map<uint64_t, M::Vocabulary*> activeChildren;
|
||||
|
||||
void processAddElement(uint64_t id, const W::Vocabulary& value, SMap::const_iterator subscriberIterator, uint64_t socketId);
|
||||
uint64_t getInsertingNeighbour(const W::Vocabulary& params, const W::Vocabulary& record, uint64_t id, const std::set<uint64_t>& allowed = empty) const;
|
||||
|
||||
protected:
|
||||
class AbstractIndex {
|
||||
public:
|
||||
AbstractIndex(W::Object::objectType vt): valueType(vt) {}
|
||||
virtual ~AbstractIndex() {}
|
||||
|
||||
virtual const std::set<uint64_t>& find(const W::Object& value) const = 0;
|
||||
virtual void add(const W::Object& value, uint64_t id) = 0;
|
||||
virtual void remove(const W::Object & value, uint64_t id) = 0;
|
||||
virtual void clear() = 0;
|
||||
virtual W::Vector sort(const std::set<uint64_t>& set, bool ascending) = 0;
|
||||
virtual uint64_t getNext(uint64_t id, const W::Object& value) = 0;
|
||||
virtual uint64_t getPrev(uint64_t id, const W::Object& value) = 0;
|
||||
|
||||
W::Object::objectType valueType;
|
||||
|
||||
protected:
|
||||
class TypeError : public Utils::Exception {
|
||||
public:
|
||||
TypeError(const std::string& name, const std::string& method, W::Object::objectType myType, W::Object::objectType valueType);
|
||||
|
||||
std::string getMessage() const;
|
||||
|
||||
private:
|
||||
std::string name;
|
||||
std::string method;
|
||||
W::Object::objectType myType;
|
||||
W::Object::objectType valueType;
|
||||
};
|
||||
};
|
||||
|
||||
template <class T>
|
||||
class Index : public AbstractIndex {
|
||||
public:
|
||||
Index();
|
||||
~Index();
|
||||
|
||||
const std::set<uint64_t>& find(const W::Object& value) const override;
|
||||
void add(const W::Object & value, uint64_t id) override;
|
||||
void remove(const W::Object & value, uint64_t id) override;
|
||||
void clear() override;
|
||||
W::Vector sort(const std::set<uint64_t> & set, bool ascending) override;
|
||||
uint64_t getNext(uint64_t id, const W::Object& value) override;
|
||||
uint64_t getPrev(uint64_t id, const W::Object& value) override;
|
||||
|
||||
private:
|
||||
typedef std::map<T, std::set<uint64_t>> Map;
|
||||
|
||||
Map values;
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
|
||||
template<class T>
|
||||
ICatalogue::Index<T>::Index():
|
||||
ICatalogue::AbstractIndex(T::type),
|
||||
values()
|
||||
{
|
||||
}
|
||||
|
||||
template<class T>
|
||||
ICatalogue::Index<T>::~Index()
|
||||
{
|
||||
}
|
||||
|
||||
template<class T>
|
||||
const std::set<uint64_t> & ICatalogue::Index<T>::find(const W::Object& value) const
|
||||
{
|
||||
if (value.getType() != valueType) {
|
||||
throw new TypeError("Unknown", "find", valueType, value.getType()); //todo replace that unknown stuff, find a way to provide index name
|
||||
}
|
||||
|
||||
const T& val = static_cast<const T&>(value);
|
||||
typename std::map<T, std::set<uint64_t>>::const_iterator itr = values.find(val);
|
||||
|
||||
if (itr == values.end()) {
|
||||
return ICatalogue::empty;
|
||||
} else {
|
||||
return itr->second;
|
||||
}
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void ICatalogue::Index<T>::add(const W::Object& value, uint64_t id)
|
||||
{
|
||||
if (value.getType() != valueType) {
|
||||
throw new TypeError("Unknown", "add", valueType, value.getType());
|
||||
}
|
||||
|
||||
const T& val = static_cast<const T&>(value);
|
||||
typename std::map<T, std::set<uint64_t>>::iterator itr = values.find(val);
|
||||
if (itr == values.end()) {
|
||||
itr = values.insert(std::make_pair(val, std::set<uint64_t>())).first;
|
||||
}
|
||||
itr->second.insert(id);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void ICatalogue::Index<T>::remove(const W::Object& value, uint64_t id)
|
||||
{
|
||||
if (value.getType() != valueType) {
|
||||
throw new TypeError("Unknown", "remove", valueType, value.getType());
|
||||
}
|
||||
const T& val = static_cast<const T&>(value);
|
||||
typename std::map<T, std::set<uint64_t>>::iterator itr = values.find(val);
|
||||
if (itr != values.end()) {
|
||||
std::set<uint64_t>& set = itr->second;
|
||||
if (set.size() == 1) {
|
||||
values.erase(itr);
|
||||
} else {
|
||||
std::set<uint64_t>::const_iterator hint = set.find(id);
|
||||
set.erase(hint);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void ICatalogue::Index<T>::clear()
|
||||
{
|
||||
values.clear();
|
||||
}
|
||||
|
||||
template<class T>
|
||||
W::Vector ICatalogue::Index<T>::sort(const std::set<uint64_t> & set, bool ascending) //TODO this needs an optimization
|
||||
{
|
||||
W::Vector res;
|
||||
std::set<uint64_t>::const_iterator sEnd = set.end();
|
||||
uint64_t size = set.size();
|
||||
|
||||
if (size == 0) {
|
||||
return res;
|
||||
} else if (size == 1) {
|
||||
res.push(W::Uint64(*(set.begin())));
|
||||
return res;
|
||||
}
|
||||
if (ascending) {
|
||||
typename std::map<T, std::set<uint64_t>>::const_iterator itr = values.begin();
|
||||
typename std::map<T, std::set<uint64_t>>::const_iterator end = values.end();
|
||||
|
||||
for (; itr != end; ++itr) {
|
||||
if (size == res.size()) {
|
||||
break;
|
||||
}
|
||||
const std::set<uint64_t>& chunk = itr->second;
|
||||
|
||||
std::set<uint64_t>::const_iterator cItr = chunk.begin();
|
||||
std::set<uint64_t>::const_iterator cEnd = chunk.end();
|
||||
for (; cItr != cEnd; ++cItr) {
|
||||
uint64_t id = *cItr;
|
||||
if (set.find(id) != sEnd) {
|
||||
res.push(W::Uint64(id));
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
typename std::map<T, std::set<uint64_t>>::reverse_iterator itr = values.rbegin();
|
||||
typename std::map<T, std::set<uint64_t>>::reverse_iterator end = values.rend();
|
||||
|
||||
for (; itr != end; ++itr) {
|
||||
if (size == res.size()) {
|
||||
break;
|
||||
}
|
||||
const std::set<uint64_t>& chunk = itr->second;
|
||||
|
||||
std::set<uint64_t>::const_iterator cItr = chunk.begin();
|
||||
std::set<uint64_t>::const_iterator cEnd = chunk.end();
|
||||
for (; cItr != cEnd; ++cItr) {
|
||||
uint64_t id = *cItr;
|
||||
if (set.find(id) != sEnd) {
|
||||
res.push(W::Uint64(id));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
uint64_t ICatalogue::Index<T>::getNext(uint64_t id, const W::Object& value)
|
||||
{
|
||||
if (value.getType() != valueType) {
|
||||
throw new TypeError("Unknown", "getNext", valueType, value.getType());
|
||||
}
|
||||
const T& val = static_cast<const T&>(value);
|
||||
typename std::map<T, std::set<uint64_t>>::iterator itr = values.find(val);
|
||||
if (itr == values.end()) {
|
||||
throw 2; //this is not suppose to happen!
|
||||
}
|
||||
const std::set<uint64_t>& set = itr->second;
|
||||
std::set<uint64_t>::const_iterator sItr = set.find(id);
|
||||
if (sItr == set.end()) {
|
||||
throw 2; //not suppose to happen!
|
||||
}
|
||||
++sItr;
|
||||
if (sItr == set.end()) {
|
||||
++itr;
|
||||
bool found = false;
|
||||
while (itr != values.end()) {
|
||||
if (itr->second.size() != 0) {
|
||||
sItr = set.begin();
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
++itr;
|
||||
}
|
||||
if (!found) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return *sItr;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
uint64_t ICatalogue::Index<T>::getPrev(uint64_t id, const W::Object& value)
|
||||
{
|
||||
if (value.getType() != valueType) {
|
||||
throw new TypeError("Unknown", "getPrev", valueType, value.getType());
|
||||
}
|
||||
const T& val = static_cast<const T&>(value);
|
||||
typename std::map<T, std::set<uint64_t>>::iterator itr = values.find(val);
|
||||
if (itr == values.end()) {
|
||||
throw 2; //this is not suppose to happen!
|
||||
}
|
||||
const std::set<uint64_t>& set = itr->second;
|
||||
std::set<uint64_t>::const_iterator sItr = set.find(id);
|
||||
if (sItr == set.end()) {
|
||||
throw 2; //not suppose to happen!
|
||||
}
|
||||
if (sItr == set.begin()) {
|
||||
bool found = false;
|
||||
while (itr != values.begin()) {
|
||||
--itr;
|
||||
if (itr->second.size() != 0) {
|
||||
sItr = set.end();
|
||||
--sItr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
--sItr;
|
||||
}
|
||||
return *sItr;
|
||||
}
|
||||
}
|
||||
|
||||
#endif // ICATALOGUE_H
|
Loading…
Add table
Add a link
Reference in a new issue