/************************************************************************
* EOS - the CERN Disk Storage System *
* Copyright (C) 2018 CERN/Switzerland *
* *
* 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 3 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, see .*
************************************************************************/
//------------------------------------------------------------------------------
//! @author Georgios Bitzes
//! @brief Container map iterators
//------------------------------------------------------------------------------
#ifndef EOS_NS_CONTAINER_ITERATORS_HH
#define EOS_NS_CONTAINER_ITERATORS_HH
#include "namespace/Namespace.hh"
#include "namespace/interface/IContainerMD.hh"
#include "namespace/interface/IFileMD.hh"
EOSNSNAMESPACE_BEGIN
//------------------------------------------------------------------------------
//! Class FileMapIterator
//------------------------------------------------------------------------------
class FileMapIterator
{
public:
FileMapIterator(IContainerMDPtr cont)
: container(cont), iResized(false), iValid(false) {
iter = cont->filesBegin();
iGeneration = generation();
if (!iterEnd()) {
iValid = true;
iKey = iter->first;
iValue = iter->second;
iShown.insert(iKey);
}
}
bool valid() const {
return iValid;
}
bool iterEnd() const {
return (iter == container->filesEnd());
}
void next() {
IContainerMD::IContainerMDReadLocker readLocker(container);
// check for a re-sized map
if (generation() != iGeneration) {
iResized = true;
// the hash_map has been re-organized
iter = container->filesBegin();
if (iterEnd()) {
iValid = false;
return;
}
do {
if (!iShown.count(iter->first)) {
break;
} else {
iter++;
if (iterEnd()) {
iValid = false;
return;
}
}
} while (1);
iGeneration = generation();
} else {
// check for a re-sized map
if (iResized) {
// in this case we always have to check if a value was already shown
iter++;
if (!iterEnd()) {
do {
if (!iShown.count(iter->first)) {
break;
} else {
iter++;
if (iterEnd()) {
iValid = false;
return;
}
}
} while (1);
} else {
iValid = false;
return;
}
} else {
iter++;
}
}
if (!iterEnd()) {
iKey = iter->first;
iValue = iter->second;
iShown.insert(iKey);
} else {
iValid = false;
}
}
std::string key() const {
return iKey;
}
IFileMD::id_t value() const {
return iValue;
}
uint64_t generation() {
return container->getFileMapGeneration();
}
private:
IContainerMDPtr container;
eos::IContainerMD::FileMap::const_iterator iter;
std::set iShown;
std::string iKey;
uint64_t iValue;
uint64_t iGeneration;
bool iResized;
bool iValid;
};
//------------------------------------------------------------------------------
//! Class ContainerIterator
//------------------------------------------------------------------------------
class ContainerMapIterator
{
public:
ContainerMapIterator(IContainerMDPtr cont)
: container(cont), iResized(false), iValid(false) {
iter = cont->subcontainersBegin();
iGeneration = generation();
if (!iterEnd()) {
iValid = true;
iKey = iter->first;
iValue = iter->second;
iShown.insert(iKey);
}
}
bool valid() const {
return iValid;
}
bool iterEnd() const {
return (iter == container->subcontainersEnd());
}
void next() {
eos::IContainerMD::IContainerMDReadLocker readLocker(container);
// check for a re-sized map
if (generation() != iGeneration) {
iResized = true;
// the hash_map has been re-organized
iter = container->subcontainersBegin();
if (iterEnd()) {
iValid = false;
return;
}
do {
if (!iShown.count(iter->first)) {
break;
} else {
iter++;
if (iterEnd()) {
iValid = false;
return;
}
}
} while (1);
iGeneration = generation();
} else {
// check for a re-sized map
if (iResized) {
// in this case we always have to check if a value was already shown
iter++;
if (!iterEnd()) {
do {
if (!iShown.count(iter->first)) {
break;
} else {
iter++;
if (iterEnd()) {
iValid = false;
return;
}
}
} while (1);
} else {
iValid = false;
return;
}
} else {
iter++;
}
}
if (!iterEnd()) {
iKey = iter->first;
iValue = iter->second;
iShown.insert(iKey);
} else {
iValid = false;
}
}
std::string key() const {
return iKey;
}
IFileMD::id_t value() const {
return iValue;
}
uint64_t generation() {
return container->getContainerMapGeneration();
}
private:
IContainerMDPtr container;
eos::IContainerMD::ContainerMap::const_iterator iter;
std::set iShown;
std::string iKey;
uint64_t iValue;
uint64_t iGeneration;
bool iResized;
bool iValid;
};
EOSNSNAMESPACE_END
#endif