void Clipping::clipBottom(Coordinates& input, Coordinates& output){
    if(output.size() > 0)
        output.clear();
    if(input.size() == 0)
        return;

    double clipY = m_w->minY;
    input.push_back(input[0]);
    for(unsigned int i = 0; i < input.size()-1; i++){
        Coordinate c0 = input[i];
        Coordinate c1 = input[i+1];

        //Caso 1: out -> out
        if(c0.y < clipY && c1.y < clipY){
            continue;
        }

        //Caso 2: in -> in
        if(c0.y >= clipY && c1.y >= clipY){
            output.push_back(c1);
            continue;
        }

        double y = clipY;
        double m = (c1.x-c0.x)/(c1.y-c0.y);
        double x = m * (y-c0.y) + c0.x;

        //Caso 3: in -> out
        if(c0.y >= clipY && c1.y < clipY){
            output.emplace_back(x,y);
            continue;
        }

        //Caso 4: out -> in
        if(c0.y < clipY && c1.y >= clipY){
            output.emplace_back(x,y);
            output.push_back(c1);
        }
    }
}
void Clipping::clipRight(Coordinates& input, Coordinates& output){
    if(output.size() > 0)
        output.clear();
    if(input.size() == 0)
        return;

    double clipX = m_w->maxX;
    input.push_back(input[0]);
    for(unsigned int i = 0; i < input.size()-1; i++){
        Coordinate c0 = input[i];
        Coordinate c1 = input[i+1];

        //Caso 1: out -> out
        if(c0.x > clipX && c1.x > clipX){
            continue;
        }

        //Caso 2: in -> in
        if(c0.x <= clipX && c1.x <= clipX){
            output.push_back(c1);
            continue;
        }

        double x = clipX;
        double m = (c1.y-c0.y)/(c1.x-c0.x);
        double y = m * (x-c0.x) + c0.y;

        //Caso 3: in -> out
        if(c0.x <= clipX && c1.x > clipX){
            output.emplace_back(x,y);
            continue;
        }

        //Caso 4: out -> in
        if(c0.x > clipX && c1.x <= clipX){
            output.emplace_back(x,y);
            output.push_back(c1);
        }
    }
}
void MessageHandleJob::handleChunkReplica()
{
    boost::shared_ptr<scidb_msg::Chunk> chunkRecord = _messageDesc->getRecord<scidb_msg::Chunk>();

    const int compMethod = chunkRecord->compression_method();
    const size_t decompressedSize = chunkRecord->decompressed_size();
    const AttributeID attributeID = chunkRecord->attribute_id();
    const size_t count = chunkRecord->count();

    assert(_query);
    RWLock::ErrorChecker noopEc;
    ScopedRWLockRead shared(_query->queryLock, noopEc);
    Coordinates coordinates;
    for (int i = 0; i < chunkRecord->coordinates_size(); i++) {
        coordinates.push_back(chunkRecord->coordinates(i));
    }

    shared_ptr<ArrayDesc> desc = SystemCatalog::getInstance()->getArrayDesc(chunkRecord->array_id());
    if(chunkRecord->tombstone())
    { // tombstone record
        StorageManager::getInstance().removeLocalChunkVersion(*desc, coordinates);
    }
    else if (decompressedSize == 0)
    { // clone of replica
        shared_ptr<ArrayDesc> sourceDesc = SystemCatalog::getInstance()->getArrayDesc(chunkRecord->source_array_id());
        StorageManager::getInstance().cloneChunk(coordinates, *desc, attributeID, *sourceDesc, chunkRecord->source_attribute_id());
    }
    else 
    { // regular chunk
        boost::shared_ptr<ArrayIterator> outputIter = StorageManager::getInstance().getArrayIterator(*desc, attributeID, _query);
        boost::shared_ptr<CompressedBuffer> compressedBuffer = dynamic_pointer_cast<CompressedBuffer>(_messageDesc->getBinary());
        compressedBuffer->setCompressionMethod(compMethod);
        compressedBuffer->setDecompressedSize(decompressedSize);
        Chunk& outChunk = outputIter->newChunk(coordinates, compMethod);
        outChunk.setSparse(chunkRecord->sparse());
        outChunk.setRLE(chunkRecord->rle());
        outChunk.decompress(*compressedBuffer); // TODO: it's better avoid decompression. It can be written compressed
        outChunk.setCount(count);
        outChunk.write(_query);
    }
    if (static_cast<MessageType>(_messageDesc->getMessageType()) != mtChunkReplica) {
       return;
    }
    assert(sourceId != INVALID_INSTANCE);
    if (_query->chunkReplicasReqs[sourceId].decrement()) {
        boost::shared_ptr<MessageDesc> resultMessage = boost::make_shared<MessageDesc>(mtReplicaSyncResponse);
        resultMessage->setQueryID(_query->getQueryID());
        networkManager.sendMessage(_messageDesc->getSourceInstanceID(), resultMessage);
    }
}
        Graph GeneratorRANDOM::Generate(int n, int m)
        {
            if(m > n*(n-1)/2)
                throw "cannot have more than n*(n-1)/2 edges";
            srand(time(NULL));

            Graph G(n);
            for(VertexIterator v = G.BeginVertices(); v != G.EndVertices(); v++)
            {
                Coordinates coords;
                coords.push_back( (rand() % 200) / 10.0f );
                coords.push_back( (rand() % 200) / 10.0f );
                (*v)->SetCoordinates(coords);
            }

            // initialize vector "allindices"
            vector<int> allindices(n*(n-1)/2);
            for(int i = (n*(n-1)/2)-1; i >= 0; i--)
                allindices[i] = i;

            // randomize vector "allindices"
            for(int i = (n*(n-1)/2)-1; i > 0; i--)
            {
                int rand_idx = rand() % (i+1);
                int temp = allindices[i];
                allindices[i] = allindices[rand_idx];
                allindices[rand_idx] = temp;
            }

            // select first m indices from randomized "allindices"
            set<int> selected_indices;
            for(int i = m-1; i >= 0; i--)
                selected_indices.insert(allindices[i]);

            // insert the edges with the selected indices into the graph
            int i = 0;
            for(VertexIterator v = G.BeginVertices(); v != G.EndVertices(); v++)
            {
                VertexIterator v1 = v;
                for(v1++; v1 != G.EndVertices(); v1++)
                {
                    if(selected_indices.find(i) != selected_indices.end())
                        G.AddEdge(v,v1);
                    i++;
                }
            }

            return G;
        }
Example #5
0
void Coordinates_test::
t_readwrite()
{
    Coordinates c;
    c.clear();
    QCOMPARE(c.count(), 0);
    c << 1.0 << 3.0;
    c.clear();
    QCOMPARE(c.count(), 0);
    c << 1.0 << 3.0;
    c.erase(c.begin(), c.end());
    QCOMPARE(c.count(), 0);
    c << 1.0 << 0.0;
    Coordinates::iterator i= c.erase(c.begin());
    QCOMPARE(*i, 0.0);
    i= c.insert(c.end(), 1.0);
    QCOMPARE(*i, 1.0);
    QCOMPARE(c.count(), 2);
    c.pop_back();
    QCOMPARE(c.count(), 1);   // 0
    QCOMPARE(c[0], 0.0);
    c.push_back(2.0);
    QCOMPARE(c.count(), 2);
    c.append(3.0);
    QCOMPARE(c.count(), 3);   // 0, 2, 3
    QCOMPARE(c[2], 3.0);
    c.insert(0, 4.0);
    QCOMPARE(c[0], 4.0);
    QCOMPARE(c[3], 3.0);
    c.insert(c.count(), 5.0);
    QCOMPARE(c.count(), 5);   // 4, 0, 2, 3, 5
    QCOMPARE(c[4], 5.0);
    c.move(4, 0);
    QCOMPARE(c.count(), 5);   // 5, 4, 0, 2, 3
    QCOMPARE(c[0], 5.0);
    c.pop_front();
    QCOMPARE(c.count(), 4);
    QCOMPARE(c[0], 4.0);
    c.prepend(6.0);
    QCOMPARE(c.count(), 5);   // 6, 4, 0, 2, 3
    QCOMPARE(c[0], 6.0);
    c.push_front(7.0);
    QCOMPARE(c.count(), 6);
    QCOMPARE(c[0], 7.0);
    c.removeAt(1);
    QCOMPARE(c.count(), 5);   // 7, 4, 0, 2, 3
    QCOMPARE(c[1], 4.0);
    c.removeFirst();
    QCOMPARE(c.count(), 4);   // 4, 0, 2, 3
    QCOMPARE(c[0], 4.0);
    c.removeLast();
    QCOMPARE(c.count(), 3);
    QCOMPARE(c.last(), 2.0);
    c.replace(2, 8.0);
    QCOMPARE(c.count(), 3);   // 4, 0, 8
    QCOMPARE(c[2], 8.0);
    c.swap(0, 2);
    QCOMPARE(c[2], 4.0);
    double d= c.takeAt(2);
    QCOMPARE(c.count(), 2);   // 8, 0
    QCOMPARE(d, 4.0);
    double d2= c.takeFirst();
    QCOMPARE(c.count(), 1);   // 0
    QCOMPARE(d2, 8.0);
    double d3= c.takeLast();
    QVERIFY(c.isEmpty()); \
    QCOMPARE(d3, 0.0);
}//t_readwrite
void Viewport::transformCoordinates(const Coordinates& coords, Coordinates& output) const {
    for(const auto &c : coords)
        output.push_back(transformCoordinate(c));
}
void MessageHandleJob::_handleChunkOrAggregateChunk(bool isAggregateChunk)
{
    boost::shared_ptr<scidb_msg::Chunk> chunkRecord = _messageDesc->getRecord<scidb_msg::Chunk>();
    assert(!chunkRecord->eof());
    assert(_query);
    RWLock::ErrorChecker noopEc;
    ScopedRWLockRead shared(_query->queryLock, noopEc);

    try
    {
        if (! isAggregateChunk) {
            // TODO: Apply it to statistics of current SG
            currentStatistics->receivedSize += _messageDesc->getMessageSize();
            currentStatistics->receivedMessages++;
        }

        LOG4CXX_TRACE(logger, "Next chunk message was received")
        const int compMethod = chunkRecord->compression_method();
        const size_t decompressedSize = chunkRecord->decompressed_size();
        const AttributeID attributeID = chunkRecord->attribute_id();
        const size_t count = chunkRecord->count();

        boost::shared_ptr<SGContext> sgCtx = dynamic_pointer_cast<SGContext>(_query->getOperatorContext());
        if (sgCtx == NULL) {
            throw (SYSTEM_EXCEPTION(SCIDB_SE_INTERNAL, SCIDB_LE_UNKNOWN_CTX)
                   << typeid(*_query->getOperatorContext()).name());
        }

        boost::shared_ptr<Array> outputArray = sgCtx->_resultSG;
        ScopedMutexLock cs(_query->resultCS);
        boost::shared_ptr<ArrayIterator> outputIter = outputArray->getIterator(attributeID);

        const bool shouldCacheEmptyBitmap = sgCtx->_shouldCacheEmptyBitmap;
        const ArrayDesc& desc = outputArray->getArrayDesc();
        const size_t sourceId = _query->mapPhysicalToLogical(_messageDesc->getSourceInstanceID());
        const bool isEmptyable = (desc.getEmptyBitmapAttribute() != NULL);
        const bool isEmptyIndicator = isEmptyable && (attributeID+1==desc.getAttributes().size());
        const bool rle = chunkRecord->rle();

        if (isAggregateChunk) {
            assert(! isEmptyIndicator);
        }

        Coordinates coordinates;
        for (int i = 0; i < chunkRecord->coordinates_size(); i++) {
            coordinates.push_back(chunkRecord->coordinates(i));
        }

        if (!isAggregateChunk && sgCtx->_targetVersioned)
        {
            sgCtx->_newChunks.insert(coordinates);
        }

        boost::shared_ptr<CompressedBuffer> compressedBuffer = dynamic_pointer_cast<CompressedBuffer>(_messageDesc->getBinary());
        if (compressedBuffer) {
            assert(compressedBuffer->getData());
            PinBuffer pin(*compressedBuffer); // this line protects compressedBuffer->data from being freed, allowing MemChunk::decompressed(*compressedBuffer) to be called multiple times.

            compressedBuffer->setCompressionMethod(compMethod);
            compressedBuffer->setDecompressedSize(decompressedSize);
            Chunk* outChunk;

            // temporary MemArray objects
            shared_ptr<MemChunk> pTmpChunk = make_shared<MemChunk>();  // make it a shared pointer, because the bitmap chunk needs to be preserved across threads.
            MemChunk closure;

            // the PinBuffer objects protect tmpChunk and closure, respectively.
            shared_ptr<PinBuffer> pinTmpChunk, pinClosure;

            if (outputIter->setPosition(coordinates)) { // existing chunk
                outChunk = &outputIter->updateChunk();

                if (! isAggregateChunk) {
                    if (outChunk->getDiskChunk() != NULL) {
                        throw SYSTEM_EXCEPTION(SCIDB_SE_MERGE, SCIDB_LE_CANT_UPDATE_CHUNK);
                    }
                    outChunk->setCount(0); // unknown
                }

                // if (a) either dest is NULL or merge by bitwise-or is possible; and (b) src is not compressed
                char* dst = static_cast<char*>(outChunk->getData());
                if ( (dst == NULL || (outChunk->isPossibleToMergeByBitwiseOr() && !chunkRecord->sparse() && !chunkRecord->rle()))
                     &&
                     compMethod == 0 )
                {
                    char const* src = (char const*)compressedBuffer->getData();

                    // Special care is needed if shouldCacheEmptyBitmap.
                    // - If this is the empty bitmap, store it in the SGContext.
                    // - Otherwise, add the empty bitmap from the SGContext to the chunk's data.
                    if (shouldCacheEmptyBitmap) {
                        initMemChunkFromNetwork(pTmpChunk, pinTmpChunk, outputArray, coordinates, attributeID,
                                compMethod, chunkRecord->sparse() || outChunk->isSparse(), rle, compressedBuffer);

                        if (isEmptyIndicator) {
                            sgCtx->setCachedEmptyBitmapChunk(sourceId, pTmpChunk, coordinates);
                        } else {
                            shared_ptr<ConstRLEEmptyBitmap> cachedBitmap = sgCtx->getCachedEmptyBitmap(sourceId, coordinates);
                            assert(cachedBitmap);
                            pinClosure = make_shared<PinBuffer>(closure);
                            closure.initialize(*pTmpChunk);
                            pTmpChunk->makeClosure(closure, cachedBitmap);
                            src = static_cast<char const*>(closure.getData());
                        }
                    }

                    if (dst == NULL) {
                        outChunk->allocateAndCopy(src, decompressedSize, chunkRecord->sparse(), chunkRecord->rle(), count, _query);
                    } else {
                        outChunk->mergeByBitwiseOr(src, decompressedSize, _query);
                    }
                } else {
                    initMemChunkFromNetwork(pTmpChunk, pinTmpChunk, outputArray, coordinates, attributeID,
                            compMethod, chunkRecord->sparse() || outChunk->isSparse(), rle, compressedBuffer);

                    ConstChunk const* srcChunk = &(*pTmpChunk);

                    // Special care is needed if shouldCacheEmptyBitmap.
                    // - If this is the empty bitmap, store it in the SGContext.
                    // - Otherwise, add the empty bitmap from the SGContext to the chunk's data.
                    if (shouldCacheEmptyBitmap) {
                        if (isEmptyIndicator) {
                            sgCtx->setCachedEmptyBitmapChunk(sourceId, pTmpChunk, coordinates);
                        } else {
                            shared_ptr<ConstRLEEmptyBitmap> cachedBitmap = sgCtx->getCachedEmptyBitmap(sourceId, coordinates);
                            assert(cachedBitmap);
                            pinClosure = make_shared<PinBuffer>(closure);
                            closure.initialize(*pTmpChunk);
                            pTmpChunk->makeClosure(closure, cachedBitmap);
                            srcChunk = &closure;
                        }
                    }

                    if (isAggregateChunk) {
                        AggregatePtr aggregate = sgCtx->_aggregateList[attributeID];
                        if (!isEmptyable && rle) {
                            assert(!shouldCacheEmptyBitmap);
                            assert(srcChunk==&(*pTmpChunk));
                            outChunk->nonEmptyableAggregateMerge(*srcChunk, aggregate, _query);
                        } else {
                            outChunk->aggregateMerge(*srcChunk, aggregate, _query);
                        }
                    } else {
                        outChunk->merge(*srcChunk, _query);
                    }
                }
            } else { // new chunk
                outChunk = &outputIter->newChunk(coordinates, compMethod);
                outChunk->setSparse(chunkRecord->sparse());
                outChunk->setRLE(rle);
                shared_ptr<CompressedBuffer> myCompressedBuffer = compressedBuffer;

                // Special care is needed if shouldCacheEmptyBitmap.
                // - If this is the empty bitmap, store it in the SGContext.
                // - Otherwise, add the empty bitmap from the SGContext to the chunk's data.
                if (shouldCacheEmptyBitmap) {
                    initMemChunkFromNetwork(pTmpChunk, pinTmpChunk, outputArray, coordinates, attributeID,
                            compMethod, chunkRecord->sparse() || outChunk->isSparse(), rle, compressedBuffer);
                    if (isEmptyIndicator) {
                        sgCtx->setCachedEmptyBitmapChunk(sourceId, pTmpChunk, coordinates);
                    } else {
                        shared_ptr<ConstRLEEmptyBitmap> cachedBitmap = sgCtx->getCachedEmptyBitmap(sourceId, coordinates);
                        assert(cachedBitmap);
                        myCompressedBuffer = make_shared<CompressedBuffer>();
                        pTmpChunk->compress(*myCompressedBuffer, cachedBitmap);
                    }
                }
                outChunk->decompress(*myCompressedBuffer);
                outChunk->setCount(count);
                outChunk->write(_query);
            } // end if (outputIter->setPosition(coordinates))

            assert(checkChunkMagic(*outChunk));
        } // end if (compressedBuffer)

        sgSync();
        LOG4CXX_TRACE(logger, "Chunk was stored")
    }
    catch(const Exception& e)
    {
        sgSync();
        throw;
    }
}
        void TransformerSPRINGEMBEDDER::SpringEmbed(Graph& G, vector<float> dimension_limits, IntermediateStepHandler* intermediatestephandler)
        {
            vector<VectorND> tractions;
            int dimensions = dimension_limits.size();

            unstressed_spring_length = dimension_limits[0];
            for(int i = 1; i < dimensions; i++)
                unstressed_spring_length *= dimension_limits[i];
            unstressed_spring_length /= G.NumberOfVertices();
            unstressed_spring_length = pow(unstressed_spring_length, 1.0f/dimensions) / (dimensions * 2);

            // init
            srand ( time(NULL) );
            for(VertexIterator a = G.BeginVertices(); a != G.EndVertices(); a++)
            {
                Coordinates coordinates;
                for(int i = 0; i < dimensions; i++)
                    coordinates.push_back(fmod(rand(), dimension_limits[i]));
                (*a)->SetCoordinates(coordinates);

                // should make sure that no two vertices have the same position
                tractions.push_back(VectorND(dimensions));
            }

            float max_movement;
            iteration = 0;
            do
            {
                // compute movement
                max_movement = 0;
                int i = 0;
                for(VertexIterator a = G.BeginVertices(); a != G.EndVertices(); a++, i++)
                {

                    VectorND traction = tractions[i] * friction;

                    // compute forces on a by the other vertices
                    VectorND aCoordinates((*a)->GetCoordinates(0));
                    for(VertexIterator b = G.BeginVertices(); b != G.EndVertices(); b++)
                    {
                        if(b==a)
                            continue;

                        // force on a by vertex b
                        VectorND bCoordinates((*b)->GetCoordinates(0));
                        traction += coulomb(aCoordinates, bCoordinates);
                        if((*a)->Adjacent(*b))
                            traction += hooke(aCoordinates, bCoordinates);
                    }

                    tractions[i] = traction;
                }


                // execute movement
                VertexIterator a = G.BeginVertices();
                for(int i = 0; a != G.EndVertices(); a++, i++)
                {
                    Coordinates OldCoordinates = (*a)->GetCoordinates(0);
                    Coordinates NewCoordinates(dimensions);
                    for(int j = 0; j < dimensions; j++)
                        NewCoordinates[j] = max(0.0f,min(dimension_limits[j],   OldCoordinates[j] + delta * tractions[i][j]   ));
                    (*a)->SetCoordinates( NewCoordinates );

                    // for the loop-condition
                    float current_movement = 0.0f;
                    for(int j = 0; j < dimensions; j++)
                        current_movement += (OldCoordinates[j] - NewCoordinates[j]) * (OldCoordinates[j] - NewCoordinates[j]);
                    if(sqrt(current_movement) > max_movement)
                        max_movement = sqrt(current_movement);
                }


                if(intermediatestephandler != NULL)
                    intermediatestephandler->Handle(&G);

                if(++iteration > nextincrease)
                {
                    movement_threshold += 0.01f;
                    nextincrease *= 4;
                }
                if(iteration > max_iterations)
                    break;

            }
            while(max_movement > movement_threshold*unstressed_spring_length);

        }
Example #9
0
    ConstChunk const& MatchArrayIterator::getChunk()
    {
        Coordinates const& currPos = inputIterator->getPosition();
        if (chunk.isInitialized() && currPos == chunk.getFirstPosition(false)) {
           return chunk;
        }
        ConstChunk const& srcChunk = inputIterator->getChunk();
        MatchArray& array = (MatchArray&)this->array;
        match = array.findMatch(currPos);
        Coordinates chunkPos = currPos;
        chunkPos.push_back(0);
        Address addr(attr, chunkPos);
        chunk.initialize(&array, &array.getArrayDesc(), addr, 0);

        std::shared_ptr<Query> emptyQuery;
        std::shared_ptr<ChunkIterator> dst = chunk.getIterator(emptyQuery, ChunkIterator::SEQUENTIAL_WRITE|ChunkIterator::NO_EMPTY_CHECK);

        if (match->initialized) {
            std::shared_ptr<ConstChunkIterator> src = srcChunk.getConstIterator(ConstChunkIterator::IGNORE_EMPTY_CELLS);
            int64_t itemNo = 0;
            if (attr < array.nPatternAttributes) {
                for (; !src->end(); ++(*src), ++itemNo) {
                    MatchHash::Elem* elem = match->find(itemNo);
                    if (elem != NULL) {
                        Coordinates elemPos(src->getPosition());
                        elemPos.push_back(0);
                        do {
                            if (elem->hash == itemNo) {
                                if (!dst->setPosition(elemPos)) {
                                    throw USER_EXCEPTION(SCIDB_SE_EXECUTION, SCIDB_LE_NO_CURRENT_POSITION);
                                }
                                dst->writeItem(src->getItem());
                                elemPos.back() += 1;
                            }
                            elem = elem->collisionChain;
                        } while (elem != NULL);
                    }
                }
            } else if (attr < array.nPatternAttributes + array.nCatalogAttributes) {
                if (catalogIterator->setPosition(currPos)) {
                    std::shared_ptr<ConstChunkIterator> ci = catalogIterator->getChunk().getConstIterator(ConstChunkIterator::IGNORE_EMPTY_CELLS);
                    for (; !src->end(); ++(*src), ++itemNo) {
                        MatchHash::Elem* elem = match->find(itemNo);
                        if (elem != NULL) {
                            Coordinates elemPos(src->getPosition());
                            elemPos.push_back(0);
                            do {
                                if (elem->hash == itemNo) {
                                    if (!dst->setPosition(elemPos)) {
                                        throw USER_EXCEPTION(SCIDB_SE_EXECUTION, SCIDB_LE_NO_CURRENT_POSITION);
                                    }
                                    if (!ci->setPosition(elem->coords)) {
                                        throw USER_EXCEPTION(SCIDB_SE_EXECUTION, SCIDB_LE_NO_CURRENT_POSITION);
                                    }
                                    dst->writeItem(ci->getItem());
                                    elemPos.back() += 1;
                                }
                                elem = elem->collisionChain;
                            } while (elem != NULL);
                        }
                    }
                }
            } else if (attr < array.nPatternAttributes + array.nCatalogAttributes + currPos.size()) {
                size_t dimNo = attr - array.nPatternAttributes - array.nCatalogAttributes;
                Value coordValue;
                for (; !src->end(); ++(*src), ++itemNo) {
                    MatchHash::Elem* elem = match->find(itemNo);
                    if (elem != NULL) {
                        Coordinates elemPos(src->getPosition());
                        elemPos.push_back(0);
                        do {
                            if (elem->hash == itemNo) {
                                if (!dst->setPosition(elemPos)) {
                                    throw USER_EXCEPTION(SCIDB_SE_EXECUTION, SCIDB_LE_NO_CURRENT_POSITION);
                                }
                                coordValue.setInt64(elem->coords[dimNo]);
                                dst->writeItem(coordValue);
                                elemPos.back() += 1;
                            }
                            elem = elem->collisionChain;
                        } while (elem != NULL);
                    }
                }
            } else {
                Value trueValue;
                trueValue.setBool(true);
                for (; !src->end(); ++(*src), ++itemNo) {
                    MatchHash::Elem* elem = match->find(itemNo);
                    if (elem != NULL) {
                        Coordinates elemPos(src->getPosition());
                        elemPos.push_back(0);
                        do {
                            if (elem->hash == itemNo) {
                                if (!dst->setPosition(elemPos)) {
                                    throw USER_EXCEPTION(SCIDB_SE_EXECUTION, SCIDB_LE_NO_CURRENT_POSITION);
                                }
                                dst->writeItem(trueValue);
                                elemPos.back() += 1;
                            }
                            elem = elem->collisionChain;
                        } while (elem != NULL);
                    }
                }
            }
        }
        dst->flush();
        return chunk;
    }
Coordinates Viewport::transformCoordinates(const Coordinates& coords) const{
    Coordinates vCoords;
    for(const auto &c : coords)
        vCoords.push_back(transformCoordinate(c));
    return vCoords;
}