From e2f541c98dfa4081fa3ab3d28f08ea2309281884 Mon Sep 17 00:00:00 2001 From: tpearson Date: Mon, 15 Mar 2010 17:32:48 +0000 Subject: Added KDE3 version of kdesvn git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/applications/kdesvn@1103685 283d02a7-25f6-0310-bc7c-ecb5cbfe19da --- src/svnfrontend/cacheentry.h | 581 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 581 insertions(+) create mode 100644 src/svnfrontend/cacheentry.h (limited to 'src/svnfrontend/cacheentry.h') diff --git a/src/svnfrontend/cacheentry.h b/src/svnfrontend/cacheentry.h new file mode 100644 index 0000000..2ab422b --- /dev/null +++ b/src/svnfrontend/cacheentry.h @@ -0,0 +1,581 @@ +/*************************************************************************** + * Copyright (C) 2005-2007 by Rajko Albrecht * + * ral@alwins-world.de * + * * + * 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 2 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, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ +#ifndef HELPERSCACHEENTRY_H +#define HELPERSCACHEENTRY_H + +#include "src/svnqt/svnqttypes.hpp" +#include "src/svnqt/shared_pointer.hpp" +#include "src/svnqt/status.hpp" + +// std::map 'cause QMap isn't usable +#include +#include +#include +#include + +namespace helpers { + +/** + Class for fast search of path based items. + + @author Rajko Albrecht +*/ +template class cacheEntry { +public: + typedef cacheEntry cache_type; + typedef typename std::map cache_map_type; + typedef typename cache_map_type::const_iterator citer; + typedef typename cache_map_type::iterator iter; + +protected: + QString m_key; + bool m_isValid; + C m_content; + cache_map_type m_subMap; + +public: + cacheEntry(); + cacheEntry(const QString&key); + cacheEntry(const cacheEntry&other); + + virtual ~cacheEntry(){}; + + virtual bool find(QStringList&,QLIST&)const; + //! Checks if cache contains a specific item + /*! + * the keylist will manipulated - so copy-operations aren't needed. + * \param what Stringlist containing the components to search for + * \return true if found (may or may not valid!) otherwise false + */ + virtual bool find(QStringList&what)const; + //! Checks if cache contains a specific valid item + /*! + * if yes, the content will stored in st + * \param what the keylist to search for + * \param st target status to store content if found + * \return true if found + */ + virtual bool findSingleValid(QStringList&what,C&st)const; + //! Checks if cache contains a specific valid item + /*! + * in difference to virtual bool find(QStringList&,svn::StatusEntries&)const no copy operations + * are made inside so it works much faster for simple find. + * \param what the keylist to search for + * \param check_valid_subs if true, return true if a subitem is valid even the item isn't valid + * \return true if found + */ + virtual bool findSingleValid(QStringList&what,bool check_valid_subs)const; + template void listsubs_if(QStringList&_what,T&oper)const; + + virtual void appendValidSub(QLIST&)const; + virtual bool isValid()const + { + return m_isValid; + } + virtual const C&content()const + { + return m_content; + } + virtual bool deleteKey(QStringList&,bool exact); + virtual void insertKey(QStringList&,const C&); + virtual void setValidContent(const QString&key,const C&st) + { + kdDebug()<<"Insert for "<& operator=(const cacheEntry&other); +#if 0 + void dump_tree(int level=0)const + { + QString pre; + pre.fill('-',level); + std::map::const_iterator it; + for (it=m_subMap.begin();it!=m_subMap.end();++it) { + std::cout<first.latin1() << " (" << it->second.m_key.latin1() << ")"<second.dump_tree(level+1); + } + } +#endif +}; + +typedef cacheEntry statusEntry; + +template inline cacheEntry::cacheEntry() + : m_key(""),m_isValid(false),m_content() +{ +} + +template inline cacheEntry::cacheEntry(const QString&key) + : m_key(key),m_isValid(false),m_content() +{ +} + +template inline cacheEntry::cacheEntry(const cacheEntry&other) + : m_key(other.m_key),m_isValid(other.m_isValid), + m_content(other.m_content),m_subMap(other.m_subMap) +{ +} + +template inline cacheEntry& cacheEntry::operator=(const cacheEntry&other) +{ + m_key=other.m_key; + m_isValid = other.m_isValid; + m_content = other.m_content; + m_subMap = other.m_subMap; + return *this; +} + +template inline bool cacheEntry::find(QStringList&what,QLIST&t)const +{ + if (what.count()==0) { + return false; + } + citer it; + it = m_subMap.find(what[0]); + if (it==m_subMap.end()) { + // kdDebug()<second.m_key == what[0]) { + /* the item itself */ + if (it->second.isValid()) { + t.append(it->second.content()); + } + /* and now check valid subitems */ + // kdDebug()<<"Appending valid subs"<second.appendValidSub(t); + // kdDebug()<<"Appended valid subs"<second.find(what,t); +} + +template inline bool cacheEntry::find(QStringList&what)const +{ + if (what.count()==0) { + return false; + } + citer it = m_subMap.find(what[0]); + if (it==m_subMap.end()) { + return false; + } + if (what.count()==1) { + return true; + } + what.erase(what.begin()); + return it->second.find(what); +} + +template inline bool cacheEntry::findSingleValid(QStringList&what,C&t)const +{ + if (what.count()==0) { + return false; + } + //kdDebug()<<"cacheEntry::findSingleValid(QStringList&what,C&t)"<< what << endl; + citer it; + it = m_subMap.find(what[0]); + if (it==m_subMap.end()) { + //kdDebug()<<"Not found here..."<second.isValid()<second.content(); + return it->second.isValid(); + } + what.erase(what.begin()); + //kdDebug()<<"Search next stage down..."<second.findSingleValid(what,t); +} + +template inline bool cacheEntry::findSingleValid(QStringList&what,bool check_valid_subs)const +{ + if (what.count()==0) { + return false; + } + // kdDebug()<<"cacheEntry::findSingleValid(QStringList&what,svn::Status&t)"<< what << endl; + citer it = m_subMap.find(what[0]); + if (it==m_subMap.end()) { + return false; + } + if (what.count()==1) { + return it->second.isValid()||(check_valid_subs&&it->second.hasValidSubs()); + } + what.erase(what.begin()); + return it->second.findSingleValid(what,check_valid_subs); +} + +template inline void cacheEntry::appendValidSub(QLIST&t)const +{ + citer it; + for (it=m_subMap.begin();it!=m_subMap.end();++it) { + if (it->second.isValid()) { + // kdDebug()<<"Appending single sub"<second.content()); + } else { + // kdDebug()<second.key()<<" isnt valid"<second.appendValidSub(t); + } +} + +template inline bool cacheEntry::deleteKey(QStringList&what,bool exact) +{ + if (what.count()==0) { + return true; + } + iter it=m_subMap.find(what[0]); + if (it==m_subMap.end()) { + return true; + } + bool caller_must_check = false; + /* first stage - we are the one holding the right key */ + if (what.count()==1){ + if (!exact || !it->second.hasValidSubs()) { + m_subMap.erase(it); + caller_must_check = true; + } else { + it->second.markInvalid(); + } + } else { + /* otherwise go trough tree */ + what.erase(what.begin()); + bool b = it->second.deleteKey(what,exact); + if (b && !it->second.hasValidSubs()) { + m_subMap.erase(it); + caller_must_check = true; + } + } + return caller_must_check; +} + +template inline bool cacheEntry::hasValidSubs()const +{ + citer it; + for (it=m_subMap.begin();it!=m_subMap.end();++it) { + if (it->second.isValid()||it->second.hasValidSubs()) { + return true; + } + } + return false; +} + +template inline void cacheEntry::insertKey(QStringList&what,const C&st) +{ + if (what.count()==0) { + return; + } + //kdDebug()<<"inserting "< template inline void cacheEntry::listsubs_if(QStringList&what,T&oper)const +{ + if (what.count()==0) { + /* we are the one to get the list for*/ + oper = for_each(m_subMap.begin(),m_subMap.end(),oper); + return; + } + /* otherwise find next */ + citer it = m_subMap.find(what[0]); + if (it==m_subMap.end()) { + /* not found */ + return; + } + what.erase(what.begin()); + it->second.listsubs_if(what,oper); +} + +template class itemCache +{ +public: + typedef cacheEntry cache_type; + typedef typename std::map cache_map_type; + typedef typename cache_map_type::const_iterator citer; + typedef typename cache_map_type::iterator iter; + +protected: + cache_map_type m_contentMap; + +public: + itemCache():m_contentMap(){} + virtual ~itemCache(){}; + + void setContent(const QLIST&dlist); + void clear(){m_contentMap.clear();} + //! Checks if cache contains a specific item + /*! + * the keylist will manipulated - so copy-operations aren't needed. + * \param what Stringlist containing the components to search for + * \return true if found (may or may not valid!) otherwise false + */ + virtual bool find(const QString&what)const; + virtual bool find(const QString&,QLIST&)const; + + virtual void deleteKey(const QString&what,bool exact); + virtual void insertKey(const C&,const QString&path); + virtual bool findSingleValid(const QString&what,C&)const; + virtual bool findSingleValid(const QString&what,bool check_valid_subs)const; + + templatevoid listsubs_if(const QString&what,T&oper)const; + + void dump_tree(); +}; + +template inline void itemCache::setContent(const QLIST&dlist) +{ + m_contentMap.clear(); + citer it; + for (it=dlist.begin();it!=dlist.end();++it) { + QStringList _keys = QStringList::split("/",(*it).path()); + if (_keys.count()==0) { + continue; + } + m_contentMap[_keys[0]]=statusEntry(_keys[0]); + if (_keys.count()==1) { + m_contentMap[_keys[0]].setValidContent(_keys[0],(*it)); + } else { + _keys.erase(_keys.begin()); + m_contentMap[_keys[0]].insertKey(_keys,(*it)); + } + } +} + +template inline void itemCache::insertKey(const C&st,const QString&path) +{ + // kdDebug()<<"Inserting "< inline bool itemCache::find(const QString&what)const +{ + if (m_contentMap.size()==0) { + return false; + } + QStringList _keys = QStringList::split("/",what); + if (_keys.count()==0) { + return false; + } + citer it=m_contentMap.find(_keys[0]); + if (it==m_contentMap.end()) { + return false; + } + if (_keys.count()==1) { + return true; + } + _keys.erase(_keys.begin()); + return it->second.find(_keys); +} + +template inline bool itemCache::find(const QString&_what,QLIST&dlist)const +{ + if (m_contentMap.size()==0) { + return false; + } + QStringList what = QStringList::split("/",_what); + if (what.count()==0) { + return false; + } + citer it=m_contentMap.find(what[0]); + if (it==m_contentMap.end()) { + return false; + } + what.erase(what.begin()); + // kdDebug()<<"itemCache::find(const QString&_what,svn::StatusEntries&dlist) "<second.find(what,dlist); +} + +template inline void itemCache::deleteKey(const QString&_what,bool exact) +{ + if (m_contentMap.size()==0) { + return; + } + QStringList what = QStringList::split("/",_what); + if (what.count()==0) { + return; + } + iter it=m_contentMap.find(what[0]); + if (it==m_contentMap.end()) { + return; + } + /* first stage - we are the one holding the right key */ + if (what.count()==1){ + if (!exact || !it->second.hasValidSubs()) { + /* if it has no valid subs delete it */ + m_contentMap.erase(it); + } else { + /* otherwise mark as invalid */ + it->second.markInvalid(); + } + return; + } else { + /* otherwise go trough tree */ + what.erase(what.begin()); + bool b = it->second.deleteKey(what,exact); + if (b && !it->second.hasValidSubs()) { + m_contentMap.erase(it); + } + } +} + +template inline void itemCache::dump_tree() +{ + citer it; + for (it=m_contentMap.begin();it!=m_contentMap.end();++it) { +// std::cout<first.latin1() << " (" << it->second.key().latin1() << ")"<second.dump_tree(1); + } +} + +template inline bool itemCache::findSingleValid(const QString&_what,C&st)const +{ + if (m_contentMap.size()==0) { + return false; + } + QStringList what = QStringList::split("/",_what); + if (what.count()==0) { + return false; + } + //kdDebug()<<"Itemcache What: "<second.isValid()) { + st=it->second.content(); + return true; + } + return false; + } + //kdDebug()<<"Stage down"<second.findSingleValid(what,st); +} + +template inline bool itemCache::findSingleValid(const QString&_what,bool check_valid_subs)const +{ + if (m_contentMap.size()==0) { + return false; + } + QStringList what = QStringList::split("/",_what); + if (what.count()==0) { + return false; + } + citer it=m_contentMap.find(what[0]); + if (it==m_contentMap.end()) { + return false; + } + if (what.count()==1) { + return it->second.isValid()||(check_valid_subs&&it->second.hasValidSubs()); + } + what.erase(what.begin()); + return it->second.findSingleValid(what,check_valid_subs); +} + +template template inline void itemCache::listsubs_if(const QString&_what,T&oper)const +{ + if (m_contentMap.size()==0) { + return; + } + QStringList what = QStringList::split("/",_what); + if (what.count()==0) { + return; + } + citer it=m_contentMap.find(what[0]); + + if (it==m_contentMap.end()) { + return; + } + if (what.count()==1) { + oper = for_each(m_contentMap.begin(),m_contentMap.end(),oper); + return; + } + what.erase(what.begin()); + it->second.listsubs_if(what,oper); +} + +typedef cacheEntry ptrEntry; +typedef itemCache statusCache; + +class ValidRemoteOnly +{ + svn::StatusEntries m_List; +public: + ValidRemoteOnly():m_List(){} + void operator()(const std::pair&_data) + { + if(_data.second.isValid() && _data.second.content()->validReposStatus()&&!_data.second.content()->validLocalStatus()) { + m_List.push_back(_data.second.content()); + } + } + const svn::StatusEntries&liste()const{return m_List;} +}; + +} + +#endif -- cgit v1.2.3