Exemplo n.º 1
0
 void Chunk::merge(ConstChunk const& with, boost::shared_ptr<Query>& query)
 {
     if (getDiskChunk() != NULL)
         throw USER_EXCEPTION(SCIDB_SE_MERGE, SCIDB_LE_CHUNK_ALREADY_EXISTS);
     setCount(0); // unknown
     AttributeDesc const& attr = getAttributeDesc();
     char* dst = (char*)getData();
     Value const& defaultValue = attr.getDefaultValue();
     if (dst != NULL && (isSparse() || isRLE() || with.isSparse() || with.isRLE() || attr.isNullable() || TypeLibrary::getType(attr.getType()).variableSize()
                         || !defaultValue.isZero()))
     {
         int sparseMode = isSparse() ? ChunkIterator::SPARSE_CHUNK : 0;
         boost::shared_ptr<ChunkIterator> dstIterator = getIterator(query, sparseMode|ChunkIterator::APPEND_CHUNK|ChunkIterator::NO_EMPTY_CHECK);
         boost::shared_ptr<ConstChunkIterator> srcIterator = with.getConstIterator(ChunkIterator::IGNORE_EMPTY_CELLS|ChunkIterator::IGNORE_DEFAULT_VALUES);
         if (getArrayDesc().getEmptyBitmapAttribute() != NULL) { 
             while (!srcIterator->end()) {
                 if (!dstIterator->setPosition(srcIterator->getPosition()))
                     throw SYSTEM_EXCEPTION(SCIDB_SE_MERGE, SCIDB_LE_OPERATION_FAILED) << "setPosition";
                 Value const& value = srcIterator->getItem();
                 dstIterator->writeItem(value);
                 ++(*srcIterator);
             }
         } else { // ignore default values
             while (!srcIterator->end()) {
                 Value const& value = srcIterator->getItem();
                 if (value != defaultValue) {
                     if (!dstIterator->setPosition(srcIterator->getPosition()))
                         throw SYSTEM_EXCEPTION(SCIDB_SE_MERGE, SCIDB_LE_OPERATION_FAILED) << "setPosition";
                     dstIterator->writeItem(value);
                 }
                 ++(*srcIterator);
             }            
         }
         dstIterator->flush();
     } else {
         PinBuffer scope(with);
         char* src = (char*)with.getData();
         if (dst == NULL) {
             allocate(with.getSize());
             setSparse(with.isSparse());
             setRLE(with.isRLE());
             memcpy(getData(), src, getSize());
         } else {
             if (getSize() != with.getSize())
                 throw USER_EXCEPTION(SCIDB_SE_MERGE, SCIDB_LE_CANT_MERGE_CHUNKS_WITH_VARYING_SIZE);
             for (size_t j = 0, n = getSize(); j < n; j++) {
                 dst[j] |= src[j];
             }
         }
         write(query);
     }
 }
Exemplo n.º 2
0
    void Chunk::aggregateMerge(ConstChunk const& with, AggregatePtr const& aggregate, boost::shared_ptr<Query>& query)
    {
        if (getDiskChunk() != NULL)
            throw USER_EXCEPTION(SCIDB_SE_MERGE, SCIDB_LE_CHUNK_ALREADY_EXISTS);

        if (isReadOnly())
            throw USER_EXCEPTION(SCIDB_SE_MERGE, SCIDB_LE_CANT_UPDATE_READ_ONLY_CHUNK);

        AttributeDesc const& attr = getAttributeDesc();

        if (aggregate->getStateType().typeId() != attr.getType())
            throw SYSTEM_EXCEPTION(SCIDB_SE_MERGE, SCIDB_LE_TYPE_MISMATCH_BETWEEN_AGGREGATE_AND_CHUNK);

        if (!attr.isNullable())
            throw SYSTEM_EXCEPTION(SCIDB_SE_INTERNAL, SCIDB_LE_AGGREGATE_STATE_MUST_BE_NULLABLE);//enforce equivalency w above merge()

        setCount(0);
        char* dst = (char*)getData();
        if (dst != NULL)
        {
            int sparseMode = isSparse() ? ChunkIterator::SPARSE_CHUNK : 0;
            boost::shared_ptr<ChunkIterator>dstIterator = getIterator(query, sparseMode|ChunkIterator::APPEND_CHUNK|ChunkIterator::NO_EMPTY_CHECK);
            boost::shared_ptr<ConstChunkIterator> srcIterator = with.getConstIterator(ChunkIterator::IGNORE_NULL_VALUES);
            while (!srcIterator->end())
            {
                Value& val = srcIterator->getItem();
                if (!val.isNull())
                {
                    if (!dstIterator->setPosition(srcIterator->getPosition()))
                        throw SYSTEM_EXCEPTION(SCIDB_SE_MERGE, SCIDB_LE_OPERATION_FAILED) << "setPosition";
                    Value& val2 = dstIterator->getItem();
                    if (!val2.isNull())
                    {
                        aggregate->merge(val, val2);
                    }
                    dstIterator->writeItem(val);
                }
                ++(*srcIterator);
            }
            dstIterator->flush();
        }
        else
        {
            PinBuffer scope(with);
            char* src = (char*)with.getData();
            allocate(with.getSize());
            setSparse(with.isSparse());
            setRLE(with.isRLE());
            memcpy(getData(), src, getSize());
            write(query);
        }
    }