Project

General

Profile

Statistics
| Branch: | Revision:

root / src / scave / idlist.cc @ a3be1d55

History | View | Annotate | Download (15.9 KB)

1
//=========================================================================
2
//  IDLIST.CC - part of
3
//                  OMNeT++/OMNEST
4
//           Discrete System Simulation in C++
5
//
6
//  Author: Andras Varga, Tamas Borbely
7
//
8
//=========================================================================
9

    
10
/*--------------------------------------------------------------*
11
  Copyright (C) 2006-2008 OpenSim Ltd.
12

13
  This file is distributed WITHOUT ANY WARRANTY. See the file
14
  `license' for details on this and other legal matters.
15
*--------------------------------------------------------------*/
16

    
17
// turn off 'Deprecated std::copy()' warning (MSVC80)
18
#ifdef _MSC_VER
19
#pragma warning(disable:4996)
20
#endif
21

    
22
#include <stdlib.h>
23
#include <algorithm>
24
#include <functional>
25
#include "idlist.h"
26
#include "resultfilemanager.h"
27
#include "stringutil.h"
28
#include "scaveutils.h"
29

    
30
#ifdef THREADED
31
#include "rwlock.h"
32
#define READER_MUTEX Mutex __reader_mutex_(mgr->getReadLock());
33
#else
34
#define READER_MUTEX
35
#endif
36

    
37
USING_NAMESPACE
38

    
39
IDList::IDList(const IDList& ids)
40
{
41
    ids.checkV();
42
    v = ids.v;
43
    const_cast<IDList&>(ids).v = NULL;
44
}
45

    
46
void IDList::set(const IDList& ids)
47
{
48
    ids.checkV();
49
    delete v;
50
    v = new V(ids.v->size());
51
    *v = *ids.v;  // copy contents
52
}
53

    
54
void IDList::add(ID x)
55
{
56
    checkV();
57
    if (std::find(v->begin(), v->end(), x)==v->end())
58
        v->push_back(x);
59
}
60

    
61
/* XXX it is not used, and bogus anyway
62
void IDList::set(int i, ID x)
63
{
64
    checkV();
65
    V::iterator it = std::find(v->begin(), v->end(), x);
66
    if (it==v->end())
67
        v->at(i) = x;  // at() includes bounds check
68
    else
69
        v->erase(it); // x is already in there -- just delete the element it replaces
70
}
71
*/
72

    
73
void IDList::erase(int i)
74
{
75
    checkV();
76
    v->at(i);  // bounds check
77
    v->erase(v->begin()+i);
78
}
79

    
80
int IDList::indexOf(ID x) const
81
{
82
    checkV();
83
    V::iterator it = std::find(v->begin(), v->end(), x);
84
    if (it != v->end())
85
        return (int)(it - v->begin());
86
    else
87
        return -1;
88
}
89

    
90
void IDList::substract(ID x)
91
{
92
    checkV();
93
    V::iterator it = std::find(v->begin(), v->end(), x);
94
    if (it!=v->end())
95
        v->erase(it);
96
}
97

    
98
void IDList::merge(IDList& ids)
99
{
100
    checkV();
101
    ids.checkV();
102

    
103
    // sort both vectors so that we can apply set_union
104
    std::sort(v->begin(), v->end());
105
    std::sort(ids.v->begin(), ids.v->end());
106

    
107
    // allocate a new vector, and merge the two vectors into it
108
    V *v2 = new V;
109
    v2->resize(v->size() + ids.v->size());
110
    V::iterator v2end = std::set_union(v->begin(), v->end(), ids.v->begin(), ids.v->end(), v2->begin());
111
    v2->resize(v2end - v2->begin());
112

    
113
    // replace the vector with the result
114
    delete v;
115
    v = v2;
116
}
117

    
118
void IDList::substract(IDList& ids)
119
{
120
    checkV();
121
    ids.checkV();
122

    
123
    // sort both vectors so that we can apply set_difference
124
    std::sort(v->begin(), v->end());
125
    std::sort(ids.v->begin(), ids.v->end());
126

    
127
    // allocate a new vector, and compute difference into it
128
    V *v2 = new V;
129
    v2->resize(v->size());
130
    V::iterator v2end = std::set_difference(v->begin(), v->end(), ids.v->begin(), ids.v->end(), v2->begin());
131
    v2->resize(v2end - v2->begin());
132

    
133
    // replace the vector with the result
134
    delete v;
135
    v = v2;
136
}
137

    
138
void IDList::intersect(IDList& ids)
139
{
140
    checkV();
141
    ids.checkV();
142

    
143
    // sort both vectors so that we can apply set_intersect
144
    std::sort(v->begin(), v->end());
145
    std::sort(ids.v->begin(), ids.v->end());
146

    
147
    // allocate a new vector, and compute intersection into it
148
    V *v2 = new V;
149
    v2->resize(v->size());
150
    V::iterator v2end = std::set_intersection(v->begin(), v->end(), ids.v->begin(), ids.v->end(), v2->begin());
151
    v2->resize(v2end - v2->begin());
152

    
153
    // replace the vector with the result
154
    delete v;
155
    v = v2;
156
}
157

    
158
IDList IDList::getSubsetByIndices(int *indices, int n) const
159
{
160
    checkV();
161
    IDList newList;
162
    for (int i=0; i<n; i++)
163
        newList.v->push_back(v->at(indices[i]));
164
    return newList;
165
}
166

    
167
IDList IDList::dup() const
168
{
169
    IDList newList;
170
    newList.set(*this);
171
    return newList;
172
}
173

    
174
void IDList::checkIntegrity(ResultFileManager *mgr) const
175
{
176
    checkV();
177
    for (V::const_iterator i=v->begin(); i!=v->end(); ++i)
178
        mgr->getItem(*i); // this will thow exception if id is not valid
179
}
180

    
181
void IDList::checkIntegrityAllScalars(ResultFileManager *mgr) const
182
{
183
    checkIntegrity(mgr);
184
    if (!areAllScalars())
185
        throw opp_runtime_error("These items are not all scalars");
186
}
187

    
188
void IDList::checkIntegrityAllVectors(ResultFileManager *mgr) const
189
{
190
    checkIntegrity(mgr);
191
    if (!areAllVectors())
192
        throw opp_runtime_error("These items are not all vectors");
193
}
194

    
195
void IDList::checkIntegrityAllHistograms(ResultFileManager *mgr) const
196
{
197
    checkIntegrity(mgr);
198
    if (!areAllHistograms())
199
        throw opp_runtime_error("These items are not all histograms");
200
}
201

    
202
class CmpBase : public std::binary_function<ID, ID, bool> {
203
    protected:
204
       ResultFileManager *mgr;
205
       bool less(const std::string& a, const std::string& b)
206
          {return strdictcmp(a.c_str(), b.c_str()) < 0;}
207
       const ResultItem& uncheckedGetItem(ID id) const { return mgr->uncheckedGetItem(id); }
208
       const ScalarResult& uncheckedGetScalar(ID id) const { return mgr->uncheckedGetScalar(id); }
209
       const VectorResult& uncheckedGetVector(ID id) const { return mgr->uncheckedGetVector(id); }
210
       const HistogramResult& uncheckedGetHistogram(ID id) const { return mgr->uncheckedGetHistogram(id); }
211
    public:
212
        CmpBase(ResultFileManager *m) {mgr = m;}
213
};
214

    
215
class FileAndRunLess : public CmpBase {
216
    public:
217
        FileAndRunLess(ResultFileManager *m) : CmpBase(m) {}
218
        bool operator()(ID a, ID b) { // implements operator<
219
            const FileRun *da = uncheckedGetItem(a).fileRunRef;
220
            const FileRun *db = uncheckedGetItem(b).fileRunRef;
221
            if (da==db)
222
                return false;
223
            else if (da->fileRef==db->fileRef)
224
                return da->runRef->runName < db->runRef->runName;
225
            else
226
                return da->fileRef->filePath < db->fileRef->filePath;
227
        }
228
};
229

    
230
class RunAndFileLess : public CmpBase {
231
    public:
232
        RunAndFileLess(ResultFileManager *m) : CmpBase(m) {}
233
        bool operator()(ID a, ID b) { // implements operator<
234
            const FileRun *da = uncheckedGetItem(a).fileRunRef;
235
            const FileRun *db = uncheckedGetItem(b).fileRunRef;
236
            if (da==db)
237
                return false;
238
            else if (da->runRef==db->runRef)
239
                return da->fileRef->filePath < db->fileRef->filePath;
240
            else
241
                return da->runRef->runName < db->runRef->runName;
242
        }
243
};
244

    
245
class RunAttributeLess : public CmpBase {
246
    private:
247
        const char* attrName;
248
    public:
249
        RunAttributeLess(ResultFileManager* m, const char* attrName)
250
            : CmpBase(m), attrName(attrName) {}
251
        bool operator()(ID a, ID b) {
252
            const char* aValue = uncheckedGetItem(a).fileRunRef->runRef->getAttribute(attrName);
253
            const char* bValue = uncheckedGetItem(b).fileRunRef->runRef->getAttribute(attrName);
254
            return ((aValue && bValue) ? less(aValue, bValue) : aValue!=NULL);
255
        }
256
};
257

    
258
#define CMP(clazz,method) class clazz : public CmpBase { \
259
    public: \
260
        clazz(ResultFileManager *m) : CmpBase(m) {} \
261
        bool operator()(const ID a, const ID b) {return method;} \
262
    };
263

    
264
CMP(DirectoryLess, less(uncheckedGetItem(a).fileRunRef->fileRef->directory, uncheckedGetItem(b).fileRunRef->fileRef->directory))
265
CMP(FileNameLess, less(uncheckedGetItem(a).fileRunRef->fileRef->fileName, uncheckedGetItem(b).fileRunRef->fileRef->fileName))
266
CMP(RunLess, less(uncheckedGetItem(a).fileRunRef->runRef->runName, uncheckedGetItem(b).fileRunRef->runRef->runName))
267
CMP(ModuleLess, less(*(uncheckedGetItem(a).moduleNameRef), *(uncheckedGetItem(b).moduleNameRef)))
268
CMP(NameLess, less(*(uncheckedGetItem(a).nameRef), *(uncheckedGetItem(b).nameRef)))
269
CMP(ValueLess, uncheckedGetScalar(a).value < uncheckedGetScalar(b).value)
270
CMP(VectorIdLess, uncheckedGetVector(a).vectorId < uncheckedGetVector(b).vectorId)
271
CMP(VectorCountLess, uncheckedGetVector(a).getCount() < uncheckedGetVector(b).getCount())
272
CMP(VectorMeanLess, uncheckedGetVector(a).getMean() < uncheckedGetVector(b).getMean())
273
CMP(VectorStddevLess, uncheckedGetVector(a).getStddev() < uncheckedGetVector(b).getStddev())
274
CMP(VectorMinLess, uncheckedGetVector(a).getMin() < uncheckedGetVector(b).getMin())
275
CMP(VectorMaxLess, uncheckedGetVector(a).getMax() < uncheckedGetVector(b).getMax())
276
CMP(VectorVarianceLess, uncheckedGetVector(a).getVariance() < uncheckedGetVector(b).getVariance())
277
CMP(StartTimeLess, uncheckedGetVector(a).startTime < uncheckedGetVector(b).startTime)
278
CMP(EndTimeLess, uncheckedGetVector(a).endTime < uncheckedGetVector(b).endTime)
279
CMP(HistogramCountLess, uncheckedGetHistogram(a).getCount() < uncheckedGetHistogram(b).getCount())
280
CMP(HistogramMeanLess, uncheckedGetHistogram(a).getMean() < uncheckedGetHistogram(b).getMean())
281
CMP(HistogramStddevLess, uncheckedGetHistogram(a).getStddev() < uncheckedGetHistogram(b).getStddev())
282
CMP(HistogramMinLess, uncheckedGetHistogram(a).getMin() < uncheckedGetHistogram(b).getMin())
283
CMP(HistogramMaxLess, uncheckedGetHistogram(a).getMax() < uncheckedGetHistogram(b).getMax())
284
CMP(HistogramVarianceLess, uncheckedGetHistogram(a).getVariance() < uncheckedGetHistogram(b).getVariance())
285

    
286
template <class T>
287
void IDList::sortBy(ResultFileManager *mgr, bool ascending, T& comparator)
288
{
289
    READER_MUTEX
290
    checkIntegrity(mgr);
291
    // optimization: maybe it's sorted the other way round, so we reverse it to speed up sorting
292
    if (v->size()>=2 && comparator(v->at(0), v->at(v->size()-1))!=ascending)
293
       reverse();
294
    if (ascending)
295
        std::sort(v->begin(), v->end(), comparator);
296
    else
297
        std::sort(v->begin(), v->end(), flipArgs(comparator));
298
}
299

    
300
template <class T>
301
void IDList::sortScalarsBy(ResultFileManager *mgr, bool ascending, T& comparator)
302
{
303
    READER_MUTEX
304
    checkIntegrityAllScalars(mgr);
305
    // optimization: maybe it's sorted the other way round, so we reverse it to speed up sorting
306
    if (v->size()>=2 && comparator(v->at(0), v->at(v->size()-1))!=ascending)
307
       reverse();
308
    if (ascending)
309
        std::sort(v->begin(), v->end(), comparator);
310
    else
311
        std::sort(v->begin(), v->end(), flipArgs(comparator));
312
}
313

    
314
template <class T>
315
void IDList::sortVectorsBy(ResultFileManager *mgr, bool ascending, T& comparator)
316
{
317
    READER_MUTEX
318
    checkIntegrityAllVectors(mgr);
319
    // optimization: maybe it's sorted the other way round, so we reverse it to speed up sorting
320
    if (v->size()>=2 && comparator(v->at(0), v->at(v->size()-1))!=ascending)
321
       reverse();
322
    if (ascending)
323
        std::sort(v->begin(), v->end(), comparator);
324
    else
325
        std::sort(v->begin(), v->end(), flipArgs(comparator));
326
}
327

    
328
template <class T>
329
void IDList::sortHistogramsBy(ResultFileManager *mgr, bool ascending, T& comparator)
330
{
331
    READER_MUTEX
332
    checkIntegrityAllHistograms(mgr);
333
    // optimization: maybe it's sorted the other way round, so we reverse it to speed up sorting
334
    if (v->size()>=2 && comparator(v->at(0), v->at(v->size()-1))!=ascending)
335
       reverse();
336
    if (ascending)
337
        std::sort(v->begin(), v->end(), comparator);
338
    else
339
        std::sort(v->begin(), v->end(), flipArgs(comparator));
340
}
341

    
342

    
343
void IDList::sortByFileAndRun(ResultFileManager *mgr, bool ascending)
344
{
345
    FileAndRunLess compare(mgr);
346
    sortBy(mgr, ascending, compare);
347
}
348

    
349
void IDList::sortByRunAndFile(ResultFileManager *mgr, bool ascending)
350
{
351
    RunAndFileLess compare(mgr);
352
    sortBy(mgr, ascending, compare);
353
}
354

    
355
void IDList::sortByDirectory(ResultFileManager *mgr, bool ascending)
356
{
357
    DirectoryLess compare(mgr);
358
    sortBy(mgr, ascending, compare);
359
}
360

    
361
void IDList::sortByFileName(ResultFileManager *mgr, bool ascending)
362
{
363
    FileNameLess compare(mgr);
364
    sortBy(mgr, ascending, compare);
365
}
366

    
367
void IDList::sortByRun(ResultFileManager *mgr, bool ascending)
368
{
369
    RunLess compare(mgr);
370
    sortBy(mgr, ascending, compare);
371
}
372

    
373
void IDList::sortByModule(ResultFileManager *mgr, bool ascending)
374
{
375
    ModuleLess compare(mgr);
376
    sortBy(mgr, ascending, compare);
377
}
378

    
379
void IDList::sortByName(ResultFileManager *mgr, bool ascending)
380
{
381
    NameLess compare(mgr);
382
    sortBy(mgr, ascending, compare);
383
}
384

    
385
void IDList::sortScalarsByValue(ResultFileManager *mgr, bool ascending)
386
{
387
    ValueLess compare(mgr);
388
    sortScalarsBy(mgr, ascending, compare);
389
}
390

    
391
void IDList::sortVectorsByVectorId(ResultFileManager *mgr, bool ascending)
392
{
393
    VectorIdLess compare(mgr);
394
    sortVectorsBy(mgr, ascending, compare);
395
}
396

    
397
void IDList::sortVectorsByLength(ResultFileManager *mgr, bool ascending)
398
{
399
        VectorCountLess compare(mgr);
400
    sortVectorsBy(mgr, ascending, compare);
401
}
402

    
403
void IDList::sortVectorsByMean(ResultFileManager *mgr, bool ascending)
404
{
405
        VectorMeanLess compare(mgr);
406
    sortVectorsBy(mgr, ascending, compare);
407
}
408

    
409
void IDList::sortVectorsByStdDev(ResultFileManager *mgr, bool ascending)
410
{
411
        VectorStddevLess compare(mgr);
412
    sortVectorsBy(mgr, ascending, compare);
413
}
414

    
415
void IDList::sortVectorsByMin(ResultFileManager *mgr, bool ascending)
416
{
417
        VectorMinLess compare(mgr);
418
    sortVectorsBy(mgr, ascending, compare);
419
}
420

    
421
void IDList::sortVectorsByMax(ResultFileManager *mgr, bool ascending)
422
{
423
        VectorMaxLess compare(mgr);
424
    sortVectorsBy(mgr, ascending, compare);
425
}
426

    
427
void IDList::sortVectorsByVariance(ResultFileManager *mgr, bool ascending)
428
{
429
        VectorVarianceLess compare(mgr);
430
    sortVectorsBy(mgr, ascending, compare);
431
}
432

    
433
void IDList::sortVectorsByStartTime(ResultFileManager *mgr, bool ascending)
434
{
435
    StartTimeLess compare(mgr);
436
    sortVectorsBy(mgr, ascending, compare);
437
}
438

    
439
void IDList::sortVectorsByEndTime(ResultFileManager *mgr, bool ascending)
440
{
441
    EndTimeLess compare(mgr);
442
    sortVectorsBy(mgr, ascending, compare);
443
}
444

    
445
void IDList::sortHistogramsByLength(ResultFileManager *mgr, bool ascending)
446
{
447
        HistogramCountLess compare(mgr);
448
    sortHistogramsBy(mgr, ascending, compare);
449
}
450

    
451
void IDList::sortHistogramsByMean(ResultFileManager *mgr, bool ascending)
452
{
453
        HistogramMeanLess compare(mgr);
454
    sortHistogramsBy(mgr, ascending, compare);
455
}
456

    
457
void IDList::sortHistogramsByStdDev(ResultFileManager *mgr, bool ascending)
458
{
459
        HistogramStddevLess compare(mgr);
460
    sortHistogramsBy(mgr, ascending, compare);
461
}
462

    
463
void IDList::sortHistogramsByMin(ResultFileManager *mgr, bool ascending)
464
{
465
        HistogramMinLess compare(mgr);
466
    sortHistogramsBy(mgr, ascending, compare);
467
}
468

    
469
void IDList::sortHistogramsByMax(ResultFileManager *mgr, bool ascending)
470
{
471
        HistogramMaxLess compare(mgr);
472
    sortHistogramsBy(mgr, ascending, compare);
473
}
474

    
475
void IDList::sortHistogramsByVariance(ResultFileManager *mgr, bool ascending)
476
{
477
        HistogramVarianceLess compare(mgr);
478
    sortHistogramsBy(mgr, ascending, compare);
479
}
480

    
481
void IDList::sortByRunAttribute(ResultFileManager *mgr, const char* runAttribute, bool ascending) {
482
    RunAttributeLess compare(mgr, runAttribute);
483
    sortBy(mgr, ascending, compare);
484
}
485

    
486
void IDList::reverse()
487
{
488
    checkV();
489
    std::reverse(v->begin(), v->end());
490
}
491

    
492
int IDList::getItemTypes() const
493
{
494
    checkV();
495
    int types = 0;
496
    for (V::const_iterator i=v->begin(); i!=v->end(); ++i)
497
        types |= ResultFileManager::_type(*i);
498
    return types;
499
}
500

    
501
bool IDList::areAllScalars() const
502
{
503
    int types = getItemTypes();
504
    return !types || types==ResultFileManager::SCALAR;
505
}
506

    
507
bool IDList::areAllVectors() const
508
{
509
    int types = getItemTypes();
510
    return !types || types==ResultFileManager::VECTOR;
511
}
512

    
513
bool IDList::areAllHistograms() const
514
{
515
    int types = getItemTypes();
516
    return !types || types==ResultFileManager::HISTOGRAM;
517
}
518

    
519
void IDList::toByteArray(char *array, int n) const
520
{
521
    checkV();
522
    if (n != (int)v->size()*8)
523
        throw opp_runtime_error("byteArray is of wrong size -- must be 8*numIDs");
524
    std::copy(v->begin(), v->end(), (ID*)array);  //XXX VC8.0: warning C4996: 'std::_Copy_opt' was declared deprecated
525
}
526

    
527
void IDList::fromByteArray(char *array, int n)
528
{
529
    checkV();
530
    if (n%8 != 0)
531
        throw opp_runtime_error("byteArray size must be multiple of 8");
532
    v->resize(n/8);
533
    ID *a = (ID *)array;
534
    std::copy(a, a+n/8, v->begin());
535
}
536

    
537