diff options
| author | Matthias P. Braendli <matthias.braendli@mpb.li> | 2017-02-12 19:02:45 +0100 | 
|---|---|---|
| committer | Matthias P. Braendli <matthias.braendli@mpb.li> | 2017-02-12 19:02:45 +0100 | 
| commit | b396a7eff34173fd4a9e48d8e4cfa5bab7fa603f (patch) | |
| tree | 34e1d78c8c358cf329aa6c049e5ca02bcf87d82f /src/OrderedQueue.cpp | |
| download | ODR-SourceCompanion-b396a7eff34173fd4a9e48d8e4cfa5bab7fa603f.tar.gz ODR-SourceCompanion-b396a7eff34173fd4a9e48d8e4cfa5bab7fa603f.tar.bz2 ODR-SourceCompanion-b396a7eff34173fd4a9e48d8e4cfa5bab7fa603f.zip | |
Add initial copy-pasted code
Diffstat (limited to 'src/OrderedQueue.cpp')
| -rw-r--r-- | src/OrderedQueue.cpp | 158 | 
1 files changed, 158 insertions, 0 deletions
| diff --git a/src/OrderedQueue.cpp b/src/OrderedQueue.cpp new file mode 100644 index 0000000..2aad726 --- /dev/null +++ b/src/OrderedQueue.cpp @@ -0,0 +1,158 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 2017 AVT GmbH - Fabien Vercasson + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *    http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ + +#include "OrderedQueue.h" +#include <cstring> +#include <cstdio> +#include <stdint.h> + +#define DEBUG(fmt, A...)   fprintf(stderr, "OrderedQueue: " fmt, ##A) +//#define DEBUG(x...) +#define ERROR(fmt, A...)   fprintf(stderr, "OrderedQueue: ERROR " fmt, ##A) + +/* + *  + */ +OrderedQueue::OrderedQueue(int countModulo, size_t capacity) +    :   _countModulo(countModulo), +        _capacity(capacity), +        _duplicated(0), +        _overruns(0), +        _lastCount(-1) +{ +} + +/* + *  + */ +OrderedQueue::~OrderedQueue() +{ +    StockIterator it = _stock.begin(); +    while (it != _stock.end()) { +        delete it->second; +        it++; +    } +} + +/* + *  + */ +void OrderedQueue::push(int32_t count, const uint8_t* buf, size_t size) +{ +//    DEBUG("OrderedQueue::push count=%d\n", count); +    count = (count+_countModulo) % _countModulo; +     +    // First frame makes the count initialisation. +    if( _lastCount == -1 ) +    { +        _lastCount = (count+_countModulo-1)%_countModulo; +    } + +    if (_stock.size() < _capacity) { +        StockIterator it = _stock.find(count); +        OrderedQueueData* oqd = new OrderedQueueData(buf, size); +        if (it == _stock.end()) { +            if (_stock.insert(std::make_pair(count, oqd)).second == false) { +                ERROR("%d not inserted\n", count); +                delete oqd; +            } +        } +        else { +            // count already exists, duplicated frame +            // Replace the old one by the new one. +            // the old one could a an old frame from the previous count loop +            delete it->second; +            it->second = oqd; +            _duplicated++; +            DEBUG("Duplicated count=%d\n", count); +        } +    } +    else { +        _overruns++; +        if (_overruns < 100) +            DEBUG("Overruns (size=%zu) count=%d not inserted\n", _stock.size(), count); +        else if (_overruns == 100) +            DEBUG("stop displaying Overruns\n");            +    } +} + +/* + *  + */ +bool OrderedQueue::availableData() +{ +    // TODO Wait for filling gaps +    return _stock.size() > 0; +} + +/* + *  + */ +size_t OrderedQueue::pop(std::vector<uint8_t>& buf, int32_t* retCount) +{     +    size_t nbBytes = 0; +    uint32_t gap = 0; +     +    if (_stock.size() > 0) { +        int32_t nextCount = (_lastCount+1)%_countModulo;   +        bool found = false; +        do { +            StockIterator it = _stock.find(nextCount); +            if (it != _stock.end()) { +                OrderedQueueData* oqd = it->second; +                buf.resize(oqd->getSize()); +                memcpy(buf.data(), oqd->getData(), oqd->getSize()); +                nbBytes = oqd->getSize(); +                delete oqd; +                _stock.erase(it); +                _lastCount = nextCount; +                if (retCount) *retCount = _lastCount; +                found = true; +            } else +            { +                if( _stock.size() < _capacity ) found = true; +                else { +                    // Search for the new reference count, starting from the current one                     +                    // This could be optimised, but the modulo makes things +                    // not easy. +                    gap++; +                    nextCount = (nextCount+1)%_countModulo; +                } +            } +        } while( !found ); +    } + +    if( gap > 0 ) +    { +        DEBUG("Count jump of %d\n", gap); +    } +//    if (nbBytes > 0 && retCount) DEBUG("OrderedQueue::pop count=%d\n", *retCount); +    return nbBytes; +} + +OrderedQueueData::OrderedQueueData(const uint8_t* data, size_t size) +{ +    _data = new uint8_t[size]; +    memcpy(_data, data, size); +    _size = size; +} + +OrderedQueueData::~OrderedQueueData() +{ +    delete [] _data; +} | 
