1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164
|
// fgpickbest.cc
#include "fgpickbest.h"
#ifndef _FGALIST_H
#include "fgalist.h"
#endif
#ifndef _FGBDFNAME_H
#include "fgbdfname.h"
#endif
#ifndef _FGDLIST_H
#include "fgdlist.h"
#endif
#ifndef _FGMRANK_H
#include "fgmrank.h"
#endif
#ifndef _FGDLACTION_H
#include "fgdlaction.h"
#endif
#ifndef _FGDELACTION_H
#include "fgdelaction.h"
#endif
#include <assert.h>
struct FGPickBest::Internal_FGPickBest {
Internal_FGPickBest(const FGString& fname);
int mRevisionsCount;
FGBrokenDownFileName mFileBits;
};
FGPickBest::Internal_FGPickBest::Internal_FGPickBest(const FGString& fname)
: mFileBits(fname)
{
}
FGPickBest::FGPickBest(FGConnectionInterface* pConnIf, const FGString& match,
int count)
: FGFilePickerInterface(pConnIf)
{
assert(count > 0);
mpInternals = new Internal_FGPickBest(match);
mpInternals->mRevisionsCount = count;
}
FGActionList
FGPickBest::DecideActions(const FGDirListing& localDir,
const FGDirListing& remoteDir)
{
FGActionList ret;
// The best matches so far
typedef pair<FGFileInfo, FGMatchRanking> FGRankPair;
typedef vector<FGRankPair> FGBestFiles;
typedef FGBestFiles::const_iterator FGBestFilesCIterator;
FGBestFiles localBestVec;
FGBestFiles remoteBestVec;
vector<FGFileInfo>::const_iterator iFiles;
for (iFiles = localDir.begin(); iFiles != localDir.end(); iFiles++) {
// Rule based matching only considers files
if (!iFiles->IsRegularFile()) {
continue;
}
FGString fileName = iFiles->GetFileName();
FGMatchRanking thisRank = mpInternals->mFileBits.GetRanking(fileName);
if (thisRank.IsMatch()) {
FGRankPair newPair;
newPair.first = *iFiles;
newPair.second = thisRank;
localBestVec.push_back(newPair);
}
}
for (iFiles = remoteDir.begin(); iFiles != remoteDir.end(); iFiles++) {
FGString fileName = iFiles->GetFileName();
// Rule based matching only considers files
if (!iFiles->IsRegularFile()) {
continue;
}
FGMatchRanking thisRank = mpInternals->mFileBits.GetRanking(fileName);
// If we have less matches than we want, or the current match is
// better than our worst match yet, take it
if (thisRank.IsMatch() &&
(remoteBestVec.size() < mpInternals->mRevisionsCount ||
thisRank > remoteBestVec[0].second)) {
// Consume lowest ranking (if vector full)
if (remoteBestVec.size() == mpInternals->mRevisionsCount) {
remoteBestVec.erase(remoteBestVec.begin());
}
// Maintain order when inserting new ranking
int pos = 0;
while (pos < remoteBestVec.size() &&
thisRank > remoteBestVec[pos].second) {
pos++;
}
FGRankPair newPair;
newPair.first = *iFiles;
newPair.second = thisRank;
remoteBestVec.insert(remoteBestVec.begin() + pos, newPair);
}
}
// Make the actions if neccessary
// Grab everything in remote list not in local list
FGBestFilesCIterator iMatchFiles;
FGBestFilesCIterator iMatchFiles2;
for (iMatchFiles = remoteBestVec.begin();
iMatchFiles != remoteBestVec.end(); iMatchFiles++) {
bool found = false;
for (iMatchFiles2 = localBestVec.begin();
iMatchFiles2 != localBestVec.end(); iMatchFiles2++) {
if (iMatchFiles->first == iMatchFiles2->first) {
found = true;
break;
}
}
if (!found) {
ret.push_back(new FGDownloadAction(iMatchFiles->first.GetFileName(),
mpConnIf,
localDir.GetDirName(),
iMatchFiles->first.GetSize()));
}
}
// Delete everything in local list not in remote list
for (iMatchFiles = localBestVec.begin();
iMatchFiles != localBestVec.end(); iMatchFiles++) {
bool found = false;
for (iMatchFiles2 = remoteBestVec.begin();
iMatchFiles2 != remoteBestVec.end(); iMatchFiles2++) {
if (iMatchFiles->first == iMatchFiles2->first) {
found = true;
break;
}
}
if (!found) {
ret.push_back(new FGDeleteAction(iMatchFiles->first.GetFileName(),
localDir.GetDirName()));
}
}
return ret;
}
|