All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.cassandra.db.ReadOrderGroup Maven / Gradle / Ivy

There is a newer version: 3.11.12.3
Show newest version
/*
 * 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.apache.cassandra.db;

import org.apache.cassandra.index.Index;
import org.apache.cassandra.utils.concurrent.OpOrder;

public class ReadOrderGroup implements AutoCloseable
{
    // For every reads
    private final OpOrder.Group baseOp;

    // For index reads
    private final OpOrder.Group indexOp;
    private final OpOrder.Group writeOp;

    private ReadOrderGroup(OpOrder.Group baseOp, OpOrder.Group indexOp, OpOrder.Group writeOp)
    {
        this.baseOp = baseOp;
        this.indexOp = indexOp;
        this.writeOp = writeOp;
    }

    public OpOrder.Group baseReadOpOrderGroup()
    {
        return baseOp;
    }

    public OpOrder.Group indexReadOpOrderGroup()
    {
        return indexOp;
    }

    public OpOrder.Group writeOpOrderGroup()
    {
        return writeOp;
    }

    public static ReadOrderGroup emptyGroup()
    {
        return new ReadOrderGroup(null, null, null);
    }

    @SuppressWarnings("resource") // ops closed during group close
    public static ReadOrderGroup forCommand(ReadCommand command)
    {
        ColumnFamilyStore baseCfs = Keyspace.openAndGetStore(command.metadata());
        ColumnFamilyStore indexCfs = maybeGetIndexCfs(baseCfs, command);

        if (indexCfs == null)
        {
            return new ReadOrderGroup(baseCfs.readOrdering.start(), null, null);
        }
        else
        {
            OpOrder.Group baseOp = null, indexOp = null, writeOp = null;
            // OpOrder.start() shouldn't fail, but better safe than sorry.
            try
            {
                baseOp = baseCfs.readOrdering.start();
                indexOp = indexCfs.readOrdering.start();
                // TODO: this should perhaps not open and maintain a writeOp for the full duration, but instead only *try* to delete stale entries, without blocking if there's no room
                // as it stands, we open a writeOp and keep it open for the duration to ensure that should this CF get flushed to make room we don't block the reclamation of any room being made
                writeOp = Keyspace.writeOrder.start();
                return new ReadOrderGroup(baseOp, indexOp, writeOp);
            }
            catch (RuntimeException e)
            {
                // Note that must have writeOp == null since ReadOrderGroup ctor can't fail
                assert writeOp == null;
                try
                {
                    if (baseOp != null)
                        baseOp.close();
                }
                finally
                {
                    if (indexOp != null)
                        indexOp.close();
                }
                throw e;
            }
        }
    }

    private static ColumnFamilyStore maybeGetIndexCfs(ColumnFamilyStore baseCfs, ReadCommand command)
    {
        Index index = command.getIndex(baseCfs);
        return index == null ? null : index.getBackingTable().orElse(null);
    }

    public void close()
    {
        try
        {
            if (baseOp != null)
                baseOp.close();
        }
        finally
        {
            if (indexOp != null)
            {
                try
                {
                    indexOp.close();
                }
                finally
                {
                    writeOp.close();
                }
            }
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy