Package org.lealone.hbase.command

Source Code of org.lealone.hbase.command.CommandParallel

/*
* Copyright 2011 The Apache Software Foundation
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you 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.
*/
package org.lealone.hbase.command;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import org.apache.hadoop.hbase.util.Threads;
import org.lealone.command.CommandInterface;
import org.lealone.command.CommandRemote;
import org.lealone.command.Prepared;
import org.lealone.command.dml.Select;
import org.lealone.engine.Session;
import org.lealone.hbase.command.dml.SQLRoutingInfo;
import org.lealone.hbase.command.dml.WithWhereClause;
import org.lealone.hbase.command.merge.HBaseMergedResult;
import org.lealone.hbase.result.HBaseSerializedResult;
import org.lealone.hbase.result.HBaseSortedResult;
import org.lealone.hbase.util.HBaseUtils;
import org.lealone.message.DbException;
import org.lealone.result.ResultInterface;
import org.lealone.util.New;

import static org.lealone.hbase.engine.HBaseConstants.*;

public class CommandParallel {
    private final static ThreadPoolExecutor pool = initPool();

    private static ThreadPoolExecutor initPool() {
        int corePoolSize = HBaseUtils.getConfiguration().getInt(COMMAND_PARALLEL_CORE_POOL_SIZE,
                DEFAULT_COMMAND_PARALLEL_CORE_POOL_SIZE);
        int maxPoolSize = HBaseUtils.getConfiguration().getInt(COMMAND_PARALLEL_MAX_POOL_SIZE,
                DEFAULT_COMMAND_PARALLEL_MAX_POOL_SIZE);
        int keepAliveTime = HBaseUtils.getConfiguration().getInt(COMMAND_PARALLEL_KEEP_ALIVE_TIME,
                DEFAULT_COMMAND_PARALLEL_KEEP_ALIVE_TIME);

        ThreadPoolExecutor pool = new ThreadPoolExecutor(corePoolSize, maxPoolSize, keepAliveTime, TimeUnit.SECONDS,
                new SynchronousQueue<Runnable>(), Threads.newDaemonThreadFactory(CommandParallel.class.getSimpleName()));
        pool.allowCoreThreadTimeOut(true);

        return pool;
    }

    public static ThreadPoolExecutor getThreadPoolExecutor() {
        return pool;
    }

    public static ResultInterface executeQuery(Session session, SQLRoutingInfo sqlRoutingInfo, Select select, final int maxRows,
            final boolean scrollable) {

        List<CommandInterface> commands = new ArrayList<CommandInterface>();
        if (sqlRoutingInfo.remoteCommands != null) {
            commands.addAll(sqlRoutingInfo.remoteCommands);
        }
        if (sqlRoutingInfo.localRegions != null) {
            for (String regionName : sqlRoutingInfo.localRegions) {
                Prepared p = session.prepare(HBaseUtils.getPlanSQL(select), true);
                p.setExecuteDirec(true);
                p.setFetchSize(select.getFetchSize());
                if (p instanceof WithWhereClause) {
                    ((WithWhereClause) p).getWhereClauseSupport().setRegionName(regionName);
                }
                commands.add(new CommandWrapper(p));
            }
        }
        //originalSelect.isGroupQuery()如果是false,那么按org.apache.hadoop.hbase.client.ClientScanner的功能来实现。
        //只要Select语句中出现聚合函数、groupBy、Having三者之一都被认为是GroupQuery,
        //对于GroupQuery需要把Select语句同时发给相关的RegionServer,得到结果后再合并。
        if (!select.isGroupQuery() && select.getSortOrder() == null)
            return new HBaseSerializedResult(commands, maxRows, scrollable, select);

        int size = commands.size();
        List<Future<ResultInterface>> futures = New.arrayList(size);
        List<ResultInterface> results = New.arrayList(size);
        for (int i = 0; i < size; i++) {
            final CommandInterface c = commands.get(i);
            futures.add(pool.submit(new Callable<ResultInterface>() {
                public ResultInterface call() throws Exception {
                    return c.executeQuery(maxRows, scrollable);
                }
            }));
        }
        try {
            for (int i = 0; i < size; i++) {
                results.add(futures.get(i).get());
            }
        } catch (Exception e) {
            throwException(e);
        }

        if (!select.isGroupQuery() && select.getSortOrder() != null)
            return new HBaseSortedResult(maxRows, session, select, results);

        String newSQL = select.getPlanSQL(true);
        Select newSelect = (Select) session.prepare(newSQL, true);
        newSelect.setExecuteDirec(true);

        return new HBaseMergedResult(results, newSelect, select);
    }

    public static int executeUpdate(List<CommandInterface> commands) {
        if (commands.size() == 1) {
            CommandInterface c = commands.get(0);
            return c.executeUpdate();
        }
        int updateCount = 0;
        int size = commands.size();
        List<Future<Integer>> futures = New.arrayList(size);
        for (int i = 0; i < size; i++) {
            final CommandInterface c = commands.get(i);
            futures.add(pool.submit(new Callable<Integer>() {
                public Integer call() throws Exception {
                    return c.executeUpdate();
                }
            }));
        }
        try {
            for (int i = 0; i < size; i++) {
                updateCount += futures.get(i).get();
            }
        } catch (Exception e) {
            throwException(e);
        }
        return updateCount;
    }

    public static int executeUpdate(SQLRoutingInfo sqlRoutingInfo, Callable<Integer> call) {
        int updateCount = 0;
        List<CommandRemote> commands = sqlRoutingInfo.remoteCommands;
        int size = commands.size() + 1;
        List<Future<Integer>> futures = New.arrayList(size);
        futures.add(pool.submit(call));
        for (int i = 0; i < size - 1; i++) {
            final CommandInterface c = commands.get(i);
            futures.add(pool.submit(new Callable<Integer>() {
                public Integer call() throws Exception {
                    return c.executeUpdate();
                }
            }));
        }
        try {
            for (int i = 0; i < size; i++) {
                updateCount += futures.get(i).get();
            }
        } catch (Exception e) {
            throwException(e);
        }
        return updateCount;
    }

    public static <T> void execute(List<Callable<T>> calls) {
        int size = calls.size();
        List<Future<T>> futures = New.arrayList(size);
        for (int i = 0; i < size; i++) {
            futures.add(pool.submit(calls.get(i)));
        }
        try {
            for (int i = 0; i < size; i++) {
                futures.get(i).get();
            }
        } catch (Exception e) {
            throwException(e);
        }
    }

    private static void throwException(Throwable e) {
        if (e instanceof ExecutionException)
            e = ((ExecutionException) e).getCause();
        throw DbException.convert(e);
    }
}
TOP

Related Classes of org.lealone.hbase.command.CommandParallel

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.