Exemplo n.º 1
0
    /**
     * Perform operator-specific checks of input and return the shape of the output. Currently,
     * the output array must exist.
     * @param schemas the shapes of the input arrays
     * @param query the query context
     */
    ArrayDesc inferSchema(std::vector< ArrayDesc> schemas, std::shared_ptr< Query> query)
    {
        SCIDB_ASSERT(schemas.size() == 1);
        SCIDB_ASSERT(_parameters.size() == 1);

        string arrayNameOrg =
			((std::shared_ptr<OperatorParamReference>&)_parameters[0])->getObjectName();
        SCIDB_ASSERT(ArrayDesc::isNameUnversioned(arrayNameOrg));

        //Ensure attributes names uniqueness.

        std::string arrayName;
        std::string namespaceName;
        query->getNamespaceArrayNames(arrayNameOrg, namespaceName, arrayName);

        ArrayDesc dstDesc;
        ArrayDesc const& srcDesc = schemas[0];
        ArrayID arrayId = query->getCatalogVersion(namespaceName, arrayName);
        bool fArrayDesc = scidb::namespaces::Communicator::getArrayDesc(
            namespaceName, arrayName, arrayId, dstDesc, false);
        if (!fArrayDesc) {
            throw USER_EXCEPTION(SCIDB_SE_INFER_SCHEMA, SCIDB_LE_ARRAY_DOESNT_EXIST) << arrayName;
        }
        ArrayDesc::checkConformity(srcDesc, dstDesc,
                                   ArrayDesc::IGNORE_PSCHEME |
                                   ArrayDesc::IGNORE_OVERLAP |
                                   ArrayDesc::IGNORE_INTERVAL); // allows auto-repart()

        SCIDB_ASSERT(dstDesc.getId() == dstDesc.getUAId());
        SCIDB_ASSERT(dstDesc.getName() == arrayName);
        SCIDB_ASSERT(dstDesc.getUAId() > 0);
        return dstDesc;
    }
 DBArray::DBArray(ArrayDesc const& desc, const boost::shared_ptr<Query>& query) 
 : 
 _desc(desc),
 _query(query)
 {
     _desc.setPartitioningSchema(SystemCatalog::getInstance()->getPartitioningSchema(desc.getId()));
     if (query) { 
         query->sharedLock(getRealName());
     }
 }
Exemplo n.º 3
0
    void InputArray::redistributeShadowArray(boost::shared_ptr<Query> const& query)
    {
        SCIDB_ASSERT(shadowArray);

        //All arrays are currently stored as round-robin. Let's store shadow arrays round-robin as well
        //TODO: revisit this when we allow users to store arrays with specified distributions
        PartitioningSchema ps = psHashPartitioned;
        ArrayDesc shadowArrayDesc = shadowArray->getArrayDesc();
        string shadowArrayVersionName;

        LOG4CXX_DEBUG(logger, "Redistribute shadow array " << shadowArrayDesc.getName());

        if (! query->isCoordinator()) {
            // worker
            string shadowArrayName = shadowArrayDesc.getName();
            SCIDB_ASSERT(ArrayDesc::isNameUnversioned(shadowArrayName));

            shared_ptr<SystemCatalog::LockDesc> lock(new SystemCatalog::LockDesc(shadowArrayName,
                                                                                 query->getQueryID(),
                                                                                 Cluster::getInstance()->getLocalInstanceId(),
                                                                                 SystemCatalog::LockDesc::WORKER,
                                                                                 SystemCatalog::LockDesc::WR));

            shared_ptr<Query::ErrorHandler> ptr(new UpdateErrorHandler(lock));
            query->pushErrorHandler(ptr);

            Query::Finalizer f = bind(&UpdateErrorHandler::releaseLock, lock, _1);
            query->pushFinalizer(f);
            SystemCatalog::ErrorChecker errorChecker = bind(&Query::validate, query);
            if (!SystemCatalog::getInstance()->lockArray(lock, errorChecker)) {
                throw USER_EXCEPTION(SCIDB_SE_SYSCAT, SCIDB_LE_CANT_INCREMENT_LOCK) << shadowArrayName;
            }

            ArrayDesc desc;
            bool arrayExists = SystemCatalog::getInstance()->getArrayDesc(shadowArrayName, desc, false);
            VersionID lastVersion = 0;
            if (arrayExists) {
                lastVersion = SystemCatalog::getInstance()->getLastVersion(desc.getId());
            }
            VersionID version = lastVersion+1;

            lock->setArrayVersion(version);
            bool rc = SystemCatalog::getInstance()->updateArrayLock(lock);
            SCIDB_ASSERT(rc);

            LOG4CXX_DEBUG(logger, "Use version " << version << " of shadow array " << shadowArrayName);
            shadowArrayVersionName = ArrayDesc::makeVersionedName(shadowArrayName, version);
        } else {
            // coordinator
            shadowArrayVersionName = shadowArrayDesc.getName();
            SCIDB_ASSERT(ArrayDesc::isNameVersioned(shadowArrayVersionName));
        }

        shared_ptr<Array> persistentShadowArray(DBArray::newDBArray(shadowArrayVersionName, query));
        ArrayDesc const& dstArrayDesc = persistentShadowArray->getArrayDesc();

        query->getReplicationContext()->enableInboundQueue(dstArrayDesc.getId(),
                                                           persistentShadowArray);

        set<Coordinates, CoordinatesLess> newChunkCoordinates;
        redistributeToArray(shadowArray, persistentShadowArray,  &newChunkCoordinates,
                            query, ps,
                            ALL_INSTANCE_MASK,
                            boost::shared_ptr <DistributionMapper>(),
                            0,
                            shared_ptr<PartitioningSchemaData>());

        StorageManager::getInstance().removeDeadChunks(dstArrayDesc, newChunkCoordinates, query);
        query->getReplicationContext()->replicationSync(dstArrayDesc.getId());
        query->getReplicationContext()->removeInboundQueue(dstArrayDesc.getId());
        StorageManager::getInstance().flush();
        PhysicalBoundaries bounds = PhysicalBoundaries::createFromChunkList(persistentShadowArray,
                                                                            newChunkCoordinates);
        SystemCatalog::getInstance()->updateArrayBoundaries(dstArrayDesc, bounds);

        // XXX TODO: add: getInjectedErrorListener().check();
    }