#ifndef CT_CLOUDINDEXREGISTRATIONMANAGERT_HPP #define CT_CLOUDINDEXREGISTRATIONMANAGERT_HPP #include "ct_cloudindex/tools/ct_cloudindexregistrationmanagert.h" #include "ct_cloudindex/registered/ct_standardmodifiablecloudindexregisteredt.h" #include "ct_cloudindex/registered/ct_standardnotmodifiablecloudindexregisteredt.h" #include "ct_cloudindex/ct_cloudindexlessmemoryt.h" #include "ct_cloud/tools/ct_globalcloudmanagert.h" template CT_CloudIndexRegistrationManagerT::CT_CloudIndexRegistrationManagerT(const CT_AbstractGlobalCloudManagerT &gcManager) : CT_AbstractCloudIndexRegistrationManagerT() { m_gcManager = (CT_AbstractGlobalCloudManagerT*)&gcManager; m_gcManager->addGlobalCloudListener(this); } template typename CT_CloudIndexRegistrationManagerT::CT_AbstractModifiableCIR CT_CloudIndexRegistrationManagerT::registerIndex(CT_AbstractModifiableCloudIndexT *index) { QMutexLocker locker(this->m_mutex); if(index == NULL) return CT_AbstractModifiableCIR(NULL); CT_AbstractModifiableCIR cir = CT_AbstractModifiableCIR(this->template createNewIndexRegistered< CT_StandardModifiableCloudIndexRegisteredT, CT_AbstractModifiableCloudIndexT >(index)); CT_AbstractCloudIndexRegistrationManagerT::registerIndex(cir); return cir; } template typename CT_CloudIndexRegistrationManagerT::CT_AbstractNotModifiableCIR CT_CloudIndexRegistrationManagerT::mergeCloudContiguous(const QList< CT_AbstractCIR > &cir_collection) { QMutexLocker locker(this->m_mutex); if(cir_collection.isEmpty()) return CT_AbstractNotModifiableCIR(NULL); size_t begin = cir_collection.first()->first(); size_t end = cir_collection.first()->last()+1; QListIterator< CT_AbstractCIR > it(cir_collection); it.next(); while(it.hasNext()) { CT_AbstractCIR cir = it.next(); if(cir->first() != end) return CT_AbstractNotModifiableCIR(NULL); end = cir->last()+1; } size_t size = end-begin; CT_AbstractNotModifiableCIR cir = CT_AbstractNotModifiableCIR(this->template createNewIndexRegistered< CT_StandardNotModifiableCloudIndexRegisteredT, CloudIndexLessMemory >(new CloudIndexLessMemory(begin, size))); CT_AbstractCloudIndexRegistrationManagerT::registerIndex(cir); return cir; } template void CT_CloudIndexRegistrationManagerT::cloudDeleted(const size_t &beginIndex, const size_t &size) { this->lockAllDocuments(); QMutexLocker locker(this->m_mutex); syncModifiableIndexRegistered(beginIndex, size); syncLessMemoryIndexRegistered(beginIndex, size); this->unlockAllDocuments(); } template void CT_CloudIndexRegistrationManagerT::syncModifiableIndexRegistered(const size_t &beginIndex, const size_t &size) { QList< CT_AbstractModifiableCloudIndexRegisteredT* > toUnregister; // fin du nuage qui va être supprimé size_t endIndex = (beginIndex+size)-1; // on parcours la liste des index enregistré QListIterator< CT_AbstractModifiableCloudIndexRegisteredT* > it(this->m_cirArray); while(it.hasNext()) { const CT_AbstractModifiableCloudIndexRegisteredT *cir = it.next(); CT_AbstractCloudIndexT *index = cir->abstractCloudIndexT(); size_t isize = index->size(); if(isize > 0) { if(index->sortType() == CT_AbstractCloudIndex::NotSorted) { CT_AbstractModifiableCloudIndexT *indexModif = cir->abstractModifiableCloudIndexT(); size_t shiftV = size; FindShiftRemoveContext context; context.beginIndex = beginIndex; context.endIndex = endIndex; indexModif->removeIfOrShiftIf(&CT_CloudIndexRegistrationManagerT::staticFindIf, &CT_CloudIndexRegistrationManagerT::staticRemoveIf, &CT_CloudIndexRegistrationManagerT::staticShiftIf, shiftV, true, &context); } else { size_t b; size_t e; index->indexAt(0, b); index->indexAt(isize-1, e); // si le nuage d'index se trouve entre le début et la fin du nuage supprimé if((b >= beginIndex) && (e <= endIndex)) { CT_AbstractModifiableCloudIndexT *indexModif = cir->abstractModifiableCloudIndexT(); // on supprime tout les index du nuage puisqu'ils ne sont plus valides indexModif->clear(); } // sinon si le nuage d'index est à cheval sur le nuage supprimé else if((b <= endIndex) && (e >= beginIndex)) { size_t i = 0; // recherche de l'emplacement de l'index qui est supérieur ou égual à la valeur beginIndex if(b < beginIndex) i = index->lowerBound(beginIndex); size_t j = isize; // recherche de l'emplacement de l'index qui est supérieur à la valeur endIndex if(e > endIndex) j = index->upperBound(endIndex); CT_AbstractModifiableCloudIndexT *indexModif = cir->abstractModifiableCloudIndexT(); // on décale les index entre j et la fin et on supprime les éléments entre i et j indexModif->eraseBetweenAndShiftRest(i, j-i, size, true); // on décale tous les index qui sont après la fin du nuage supprimé /*while(j < isize) { const ct_index_type &tmpIndex = indexModif->constIndexAt(j); indexModif->replaceIndex(i, tmpIndex - size, false); ++j; ++i; } // if(i < isize) indexModif->erase(i, isize-i);*/ } // sinon le nuage d'index est après le nuage supprimé else if(b >= endIndex) { // il faut juste décaler tout les éléments cir->abstractModifiableCloudIndexT()->shiftAll(size, true); } } } // on garde en mémoire les nuages qu'il faut enlever de l'enregistrement (puisqu'ils n'ont plus d'index) if(index->mustBeUnregisteredWhenIsEmpty() && (index->size() == 0)) toUnregister.append((CT_AbstractModifiableCloudIndexRegisteredT*)cir); } // on supprime les nuages qui n'ont plus d'index while(!toUnregister.isEmpty()) CT_AbstractCloudIndexRegistrationManagerT::unregisterIndex(toUnregister.takeFirst()); } template void CT_CloudIndexRegistrationManagerT::syncLessMemoryIndexRegistered(const size_t &beginIndex, const size_t &size) { QList< CT_AbstractNotModifiableCloudIndexRegisteredT* > toUnregister; // fin du nuage qui va être supprimé size_t endIndex = (beginIndex+size)-1; // on parcours la liste des index enregistré QListIterator< CT_AbstractNotModifiableCloudIndexRegisteredT* > it(this->m_cirMergedArray); while(it.hasNext()) { CT_AbstractNotModifiableCloudIndexRegisteredT *cir = it.next(); // on sait que c'est un CloudIndexLessMemory puisqu'on l'a créé dans mergeCloudContiguous(...) CloudIndexLessMemory *index = dynamic_cast(cir->abstractCloudIndexT()); size_t isize = index->size(); if(isize > 0) { size_t b; size_t e; index->indexAt(0, b); index->indexAt(isize-1, e); // si le nuage d'index se trouve entre le début et la fin du nuage supprimé if((b >= beginIndex) && (e <= endIndex)) { // le seul cas possible c'est si on a fait appel à la méthode mergeCloudContiguous() avec un seul nuage. // donc on doit supprimer ce nuage d'index. index->clear(); } // sinon si le nuage d'index est plus grand que le nuage qu'on supprime else if((b <= beginIndex) && (e >= endIndex)) { if(!index->cut(beginIndex, endIndex)) { qFatal("erreur de synchronisation d'un nuage d'index de type less memory. contacter le développeur ! (methode cut)"); } } // sinon le nuage d'index est après le nuage supprimé else if(b >= endIndex) { // il faut juste décaler tout les éléments index->shiftAll(size, true); } else { // impossible qFatal("erreur de synchronisation d'un nuage d'index de type less memory. contacter le développeur !"); } } // on garde en mémoire les nuages qu'il faut enlever de l'enregistrement (puisqu'ils n'ont plus d'index) if(index->mustBeUnregisteredWhenIsEmpty() && (index->size() == 0)) toUnregister.append(cir); } // on supprime les nuages qui n'ont plus d'index while(!toUnregister.isEmpty()) CT_AbstractCloudIndexRegistrationManagerT::unregisterIndex(toUnregister.takeFirst()); } template bool CT_CloudIndexRegistrationManagerT::staticFindIf(void *context, const size_t &value) { return value >= ((FindShiftRemoveContext*)context)->beginIndex; } template bool CT_CloudIndexRegistrationManagerT::staticShiftIf(void *context, const size_t &value) { return value > ((FindShiftRemoveContext*)context)->endIndex; } template bool CT_CloudIndexRegistrationManagerT::staticRemoveIf(void *context, const size_t &value) { return (value >= ((FindShiftRemoveContext*)context)->beginIndex) && (value <= ((FindShiftRemoveContext*)context)->endIndex); } #endif // CT_CLOUDINDEXREGISTRATIONMANAGERT_HPP