/* * Licensed 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 com.facebook.presto.hive; import com.facebook.presto.hive.metastore.ExtendedHiveMetastore; import com.facebook.presto.hive.metastore.HivePageSinkMetadataProvider; import com.facebook.presto.spi.ConnectorInsertTableHandle; import com.facebook.presto.spi.ConnectorOutputTableHandle; import com.facebook.presto.spi.ConnectorPageSink; import com.facebook.presto.spi.ConnectorSession; import com.facebook.presto.spi.NodeManager; import com.facebook.presto.spi.PageIndexerFactory; import com.facebook.presto.spi.connector.ConnectorPageSinkProvider; import com.facebook.presto.spi.connector.ConnectorTransactionHandle; import com.facebook.presto.spi.type.TypeManager; import com.google.common.collect.ImmutableSet; import com.google.common.util.concurrent.ListeningExecutorService; import io.airlift.event.client.EventClient; import io.airlift.json.JsonCodec; import javax.inject.Inject; import java.util.OptionalInt; import java.util.Set; import static com.google.common.util.concurrent.MoreExecutors.listeningDecorator; import static io.airlift.concurrent.Threads.daemonThreadsNamed; import static java.util.Objects.requireNonNull; import static java.util.concurrent.Executors.newFixedThreadPool; public class HivePageSinkProvider implements ConnectorPageSinkProvider { private final Set<HiveFileWriterFactory> fileWriterFactories; private final HdfsEnvironment hdfsEnvironment; private final ExtendedHiveMetastore metastore; private final PageIndexerFactory pageIndexerFactory; private final TypeManager typeManager; private final int maxOpenPartitions; private final boolean immutablePartitions; private final LocationService locationService; private final ListeningExecutorService writeVerificationExecutor; private final JsonCodec<PartitionUpdate> partitionUpdateCodec; private final NodeManager nodeManager; private final EventClient eventClient; private final HiveSessionProperties hiveSessionProperties; @Inject public HivePageSinkProvider( Set<HiveFileWriterFactory> fileWriterFactories, HdfsEnvironment hdfsEnvironment, ExtendedHiveMetastore metastore, PageIndexerFactory pageIndexerFactory, TypeManager typeManager, HiveClientConfig config, LocationService locationService, JsonCodec<PartitionUpdate> partitionUpdateCodec, NodeManager nodeManager, EventClient eventClient, HiveSessionProperties hiveSessionProperties) { this.fileWriterFactories = ImmutableSet.copyOf(requireNonNull(fileWriterFactories, "fileWriterFactories is null")); this.hdfsEnvironment = requireNonNull(hdfsEnvironment, "hdfsEnvironment is null"); // TODO: this metastore should not have global cache // As a temporary workaround, always disable cache on the workers this.metastore = requireNonNull(metastore, "metastore is null"); this.pageIndexerFactory = requireNonNull(pageIndexerFactory, "pageIndexerFactory is null"); this.typeManager = requireNonNull(typeManager, "typeManager is null"); this.maxOpenPartitions = config.getMaxPartitionsPerWriter(); this.immutablePartitions = config.isImmutablePartitions(); this.locationService = requireNonNull(locationService, "locationService is null"); this.writeVerificationExecutor = listeningDecorator(newFixedThreadPool(config.getWriteValidationThreads(), daemonThreadsNamed("hive-write-validation-%s"))); this.partitionUpdateCodec = requireNonNull(partitionUpdateCodec, "partitionUpdateCodec is null"); this.nodeManager = requireNonNull(nodeManager, "nodeManager is null"); this.eventClient = requireNonNull(eventClient, "eventClient is null"); this.hiveSessionProperties = requireNonNull(hiveSessionProperties, "hiveSessionProperties is null"); } @Override public ConnectorPageSink createPageSink(ConnectorTransactionHandle transaction, ConnectorSession session, ConnectorOutputTableHandle tableHandle) { HiveWritableTableHandle handle = (HiveOutputTableHandle) tableHandle; return createPageSink(handle, true, session); } @Override public ConnectorPageSink createPageSink(ConnectorTransactionHandle transaction, ConnectorSession session, ConnectorInsertTableHandle tableHandle) { HiveInsertTableHandle handle = (HiveInsertTableHandle) tableHandle; return createPageSink(handle, false, session); } private ConnectorPageSink createPageSink(HiveWritableTableHandle handle, boolean isCreateTable, ConnectorSession session) { OptionalInt bucketCount = handle.getBucketProperty().isPresent() ? OptionalInt.of(handle.getBucketProperty().get().getBucketCount()) : OptionalInt.empty(); HiveWriterFactory writerFactory = new HiveWriterFactory( fileWriterFactories, handle.getSchemaName(), handle.getTableName(), isCreateTable, handle.getInputColumns(), handle.getTableStorageFormat(), handle.getPartitionStorageFormat(), bucketCount, handle.getLocationHandle(), locationService, handle.getFilePrefix(), new HivePageSinkMetadataProvider(handle.getPageSinkMetadata(), metastore), typeManager, hdfsEnvironment, immutablePartitions, session, nodeManager, eventClient, hiveSessionProperties); return new HivePageSink( writerFactory, handle.getInputColumns(), handle.getBucketProperty(), pageIndexerFactory, typeManager, hdfsEnvironment, maxOpenPartitions, writeVerificationExecutor, partitionUpdateCodec, session); } }