Search in sources :

Example 1 with FunctionBytesPtr

use of org.apache.phoenix.cache.GlobalCache.FunctionBytesPtr in project phoenix by apache.

the class MetaDataEndpointImpl method doGetFunctions.

private List<PFunction> doGetFunctions(List<byte[]> keys, long clientTimeStamp) throws IOException, SQLException {
    Cache<ImmutableBytesPtr, PMetaDataEntity> metaDataCache = GlobalCache.getInstance(this.env).getMetaDataCache();
    Region region = env.getRegion();
    Collections.sort(keys, new Comparator<byte[]>() {

        @Override
        public int compare(byte[] o1, byte[] o2) {
            return Bytes.compareTo(o1, o2);
        }
    });
    /*
         * Lock directly on key, though it may be an index table. This will just prevent a table
         * from getting rebuilt too often.
         */
    List<RowLock> rowLocks = new ArrayList<Region.RowLock>(keys.size());
    ;
    try {
        rowLocks = new ArrayList<Region.RowLock>(keys.size());
        for (int i = 0; i < keys.size(); i++) {
            Region.RowLock rowLock = region.getRowLock(keys.get(i), false);
            if (rowLock == null) {
                throw new IOException("Failed to acquire lock on " + Bytes.toStringBinary(keys.get(i)));
            }
            rowLocks.add(rowLock);
        }
        List<PFunction> functionsAvailable = new ArrayList<PFunction>(keys.size());
        int numFunctions = keys.size();
        Iterator<byte[]> iterator = keys.iterator();
        while (iterator.hasNext()) {
            byte[] key = iterator.next();
            PFunction function = (PFunction) metaDataCache.getIfPresent(new FunctionBytesPtr(key));
            if (function != null && function.getTimeStamp() < clientTimeStamp) {
                if (isFunctionDeleted(function)) {
                    return null;
                }
                functionsAvailable.add(function);
                iterator.remove();
            }
        }
        if (functionsAvailable.size() == numFunctions)
            return functionsAvailable;
        // Query for the latest table first, since it's not cached
        List<PFunction> buildFunctions = buildFunctions(keys, region, clientTimeStamp, false, Collections.<Mutation>emptyList());
        if (buildFunctions == null || buildFunctions.isEmpty()) {
            return null;
        }
        functionsAvailable.addAll(buildFunctions);
        if (functionsAvailable.size() == numFunctions)
            return functionsAvailable;
        return null;
    } finally {
        for (Region.RowLock lock : rowLocks) {
            lock.release();
        }
        rowLocks.clear();
    }
}
Also used : PFunction(org.apache.phoenix.parse.PFunction) ImmutableBytesPtr(org.apache.phoenix.hbase.index.util.ImmutableBytesPtr) ArrayList(java.util.ArrayList) IOException(java.io.IOException) DoNotRetryIOException(org.apache.hadoop.hbase.DoNotRetryIOException) PTinyint(org.apache.phoenix.schema.types.PTinyint) PSmallint(org.apache.phoenix.schema.types.PSmallint) PMetaDataEntity(org.apache.phoenix.schema.PMetaDataEntity) Region(org.apache.hadoop.hbase.regionserver.Region) RowLock(org.apache.hadoop.hbase.regionserver.Region.RowLock) RowLock(org.apache.hadoop.hbase.regionserver.Region.RowLock) FunctionBytesPtr(org.apache.phoenix.cache.GlobalCache.FunctionBytesPtr)

Example 2 with FunctionBytesPtr

use of org.apache.phoenix.cache.GlobalCache.FunctionBytesPtr in project phoenix by apache.

the class MetaDataEndpointImpl method buildFunctions.

private List<PFunction> buildFunctions(List<byte[]> keys, Region region, long clientTimeStamp, boolean isReplace, List<Mutation> deleteMutationsForReplace) throws IOException, SQLException {
    List<KeyRange> keyRanges = Lists.newArrayListWithExpectedSize(keys.size());
    for (byte[] key : keys) {
        byte[] stopKey = ByteUtil.concat(key, QueryConstants.SEPARATOR_BYTE_ARRAY);
        ByteUtil.nextKey(stopKey, stopKey.length);
        keyRanges.add(PVarbinary.INSTANCE.getKeyRange(key, true, stopKey, false));
    }
    Scan scan = new Scan();
    scan.setTimeRange(MIN_TABLE_TIMESTAMP, clientTimeStamp);
    ScanRanges scanRanges = ScanRanges.createPointLookup(keyRanges);
    scanRanges.initializeScan(scan);
    scan.setFilter(scanRanges.getSkipScanFilter());
    RegionScanner scanner = region.getScanner(scan);
    Cache<ImmutableBytesPtr, PMetaDataEntity> metaDataCache = GlobalCache.getInstance(this.env).getMetaDataCache();
    List<PFunction> functions = new ArrayList<PFunction>();
    PFunction function = null;
    try {
        for (int i = 0; i < keys.size(); i++) {
            function = null;
            function = getFunction(scanner, isReplace, clientTimeStamp, deleteMutationsForReplace);
            if (function == null) {
                return null;
            }
            byte[] functionKey = SchemaUtil.getFunctionKey(function.getTenantId() == null ? ByteUtil.EMPTY_BYTE_ARRAY : function.getTenantId().getBytes(), Bytes.toBytes(function.getFunctionName()));
            metaDataCache.put(new FunctionBytesPtr(functionKey), function);
            functions.add(function);
        }
        return functions;
    } finally {
        scanner.close();
    }
}
Also used : PFunction(org.apache.phoenix.parse.PFunction) KeyRange(org.apache.phoenix.query.KeyRange) ImmutableBytesPtr(org.apache.phoenix.hbase.index.util.ImmutableBytesPtr) ArrayList(java.util.ArrayList) ScanRanges(org.apache.phoenix.compile.ScanRanges) PTinyint(org.apache.phoenix.schema.types.PTinyint) PSmallint(org.apache.phoenix.schema.types.PSmallint) RegionScanner(org.apache.hadoop.hbase.regionserver.RegionScanner) PMetaDataEntity(org.apache.phoenix.schema.PMetaDataEntity) Scan(org.apache.hadoop.hbase.client.Scan) FunctionBytesPtr(org.apache.phoenix.cache.GlobalCache.FunctionBytesPtr)

Example 3 with FunctionBytesPtr

use of org.apache.phoenix.cache.GlobalCache.FunctionBytesPtr in project phoenix by apache.

the class MetaDataEndpointImpl method createFunction.

@Override
public void createFunction(RpcController controller, CreateFunctionRequest request, RpcCallback<MetaDataResponse> done) {
    MetaDataResponse.Builder builder = MetaDataResponse.newBuilder();
    byte[][] rowKeyMetaData = new byte[2][];
    byte[] functionName = null;
    try {
        List<Mutation> functionMetaData = ProtobufUtil.getMutations(request);
        boolean temporaryFunction = request.getTemporary();
        MetaDataUtil.getTenantIdAndFunctionName(functionMetaData, rowKeyMetaData);
        byte[] tenantIdBytes = rowKeyMetaData[PhoenixDatabaseMetaData.TENANT_ID_INDEX];
        functionName = rowKeyMetaData[PhoenixDatabaseMetaData.FUNTION_NAME_INDEX];
        byte[] lockKey = SchemaUtil.getFunctionKey(tenantIdBytes, functionName);
        Region region = env.getRegion();
        MetaDataMutationResult result = checkFunctionKeyInRegion(lockKey, region);
        if (result != null) {
            done.run(MetaDataMutationResult.toProto(result));
            return;
        }
        List<RowLock> locks = Lists.newArrayList();
        long clientTimeStamp = MetaDataUtil.getClientTimeStamp(functionMetaData);
        try {
            acquireLock(region, lockKey, locks);
            // Get as of latest timestamp so we can detect if we have a newer function that already
            // exists without making an additional query
            ImmutableBytesPtr cacheKey = new FunctionBytesPtr(lockKey);
            PFunction function = loadFunction(env, lockKey, cacheKey, clientTimeStamp, clientTimeStamp, request.getReplace(), functionMetaData);
            if (function != null) {
                if (function.getTimeStamp() < clientTimeStamp) {
                    // continue
                    if (!isFunctionDeleted(function)) {
                        builder.setReturnCode(MetaDataProtos.MutationCode.FUNCTION_ALREADY_EXISTS);
                        builder.setMutationTime(EnvironmentEdgeManager.currentTimeMillis());
                        builder.addFunction(PFunction.toProto(function));
                        done.run(builder.build());
                        if (!request.getReplace()) {
                            return;
                        }
                    }
                } else {
                    builder.setReturnCode(MetaDataProtos.MutationCode.NEWER_FUNCTION_FOUND);
                    builder.setMutationTime(EnvironmentEdgeManager.currentTimeMillis());
                    builder.addFunction(PFunction.toProto(function));
                    done.run(builder.build());
                    return;
                }
            }
            // Don't store function info for temporary functions.
            if (!temporaryFunction) {
                region.mutateRowsWithLocks(functionMetaData, Collections.<byte[]>emptySet(), HConstants.NO_NONCE, HConstants.NO_NONCE);
            }
            // Invalidate the cache - the next getFunction call will add it
            // TODO: consider loading the function that was just created here, patching up the parent function, and updating the cache
            Cache<ImmutableBytesPtr, PMetaDataEntity> metaDataCache = GlobalCache.getInstance(this.env).getMetaDataCache();
            metaDataCache.invalidate(cacheKey);
            // Get timeStamp from mutations - the above method sets it if it's unset
            long currentTimeStamp = MetaDataUtil.getClientTimeStamp(functionMetaData);
            builder.setReturnCode(MetaDataProtos.MutationCode.FUNCTION_NOT_FOUND);
            builder.setMutationTime(currentTimeStamp);
            done.run(builder.build());
            return;
        } finally {
            region.releaseRowLocks(locks);
        }
    } catch (Throwable t) {
        logger.error("createFunction failed", t);
        ProtobufUtil.setControllerException(controller, ServerUtil.createIOException(Bytes.toString(functionName), t));
    }
}
Also used : MetaDataResponse(org.apache.phoenix.coprocessor.generated.MetaDataProtos.MetaDataResponse) PFunction(org.apache.phoenix.parse.PFunction) ImmutableBytesPtr(org.apache.phoenix.hbase.index.util.ImmutableBytesPtr) PMetaDataEntity(org.apache.phoenix.schema.PMetaDataEntity) Region(org.apache.hadoop.hbase.regionserver.Region) Mutation(org.apache.hadoop.hbase.client.Mutation) RowLock(org.apache.hadoop.hbase.regionserver.Region.RowLock) FunctionBytesPtr(org.apache.phoenix.cache.GlobalCache.FunctionBytesPtr)

Example 4 with FunctionBytesPtr

use of org.apache.phoenix.cache.GlobalCache.FunctionBytesPtr in project phoenix by apache.

the class MetaDataEndpointImpl method doDropFunction.

private MetaDataMutationResult doDropFunction(long clientTimeStamp, List<byte[]> keys, List<Mutation> functionMetaData, List<ImmutableBytesPtr> invalidateList) throws IOException, SQLException {
    List<byte[]> keysClone = new ArrayList<byte[]>(keys);
    List<PFunction> functions = doGetFunctions(keysClone, clientTimeStamp);
    // there was a table, but it's been deleted. In either case we want to return.
    if (functions == null || functions.isEmpty()) {
        if (buildDeletedFunction(keys.get(0), new FunctionBytesPtr(keys.get(0)), env.getRegion(), clientTimeStamp) != null) {
            return new MetaDataMutationResult(MutationCode.FUNCTION_ALREADY_EXISTS, EnvironmentEdgeManager.currentTimeMillis(), null);
        }
        return new MetaDataMutationResult(MutationCode.FUNCTION_NOT_FOUND, EnvironmentEdgeManager.currentTimeMillis(), null);
    }
    if (functions != null && !functions.isEmpty()) {
        if (functions.get(0).getTimeStamp() < clientTimeStamp) {
            // continue
            if (isFunctionDeleted(functions.get(0))) {
                return new MetaDataMutationResult(MutationCode.FUNCTION_NOT_FOUND, EnvironmentEdgeManager.currentTimeMillis(), null);
            }
            invalidateList.add(new FunctionBytesPtr(keys.get(0)));
            Region region = env.getRegion();
            Scan scan = MetaDataUtil.newTableRowsScan(keys.get(0), MIN_TABLE_TIMESTAMP, clientTimeStamp);
            List<Cell> results = Lists.newArrayList();
            try (RegionScanner scanner = region.getScanner(scan)) {
                scanner.next(results);
                if (results.isEmpty()) {
                    // Should not be possible
                    return new MetaDataMutationResult(MutationCode.FUNCTION_NOT_FOUND, EnvironmentEdgeManager.currentTimeMillis(), null);
                }
                do {
                    Cell kv = results.get(0);
                    Delete delete = new Delete(kv.getRowArray(), kv.getRowOffset(), kv.getRowLength(), clientTimeStamp);
                    functionMetaData.add(delete);
                    results.clear();
                    scanner.next(results);
                } while (!results.isEmpty());
            }
            return new MetaDataMutationResult(MutationCode.FUNCTION_ALREADY_EXISTS, EnvironmentEdgeManager.currentTimeMillis(), functions, true);
        }
    }
    return new MetaDataMutationResult(MutationCode.FUNCTION_NOT_FOUND, EnvironmentEdgeManager.currentTimeMillis(), null);
}
Also used : Delete(org.apache.hadoop.hbase.client.Delete) PFunction(org.apache.phoenix.parse.PFunction) RegionScanner(org.apache.hadoop.hbase.regionserver.RegionScanner) ArrayList(java.util.ArrayList) Region(org.apache.hadoop.hbase.regionserver.Region) Scan(org.apache.hadoop.hbase.client.Scan) Cell(org.apache.hadoop.hbase.Cell) FunctionBytesPtr(org.apache.phoenix.cache.GlobalCache.FunctionBytesPtr)

Aggregations

FunctionBytesPtr (org.apache.phoenix.cache.GlobalCache.FunctionBytesPtr)4 PFunction (org.apache.phoenix.parse.PFunction)4 ArrayList (java.util.ArrayList)3 Region (org.apache.hadoop.hbase.regionserver.Region)3 ImmutableBytesPtr (org.apache.phoenix.hbase.index.util.ImmutableBytesPtr)3 PMetaDataEntity (org.apache.phoenix.schema.PMetaDataEntity)3 Scan (org.apache.hadoop.hbase.client.Scan)2 RowLock (org.apache.hadoop.hbase.regionserver.Region.RowLock)2 RegionScanner (org.apache.hadoop.hbase.regionserver.RegionScanner)2 PSmallint (org.apache.phoenix.schema.types.PSmallint)2 PTinyint (org.apache.phoenix.schema.types.PTinyint)2 IOException (java.io.IOException)1 Cell (org.apache.hadoop.hbase.Cell)1 DoNotRetryIOException (org.apache.hadoop.hbase.DoNotRetryIOException)1 Delete (org.apache.hadoop.hbase.client.Delete)1 Mutation (org.apache.hadoop.hbase.client.Mutation)1 ScanRanges (org.apache.phoenix.compile.ScanRanges)1 MetaDataResponse (org.apache.phoenix.coprocessor.generated.MetaDataProtos.MetaDataResponse)1 KeyRange (org.apache.phoenix.query.KeyRange)1