/*
 * 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.index.transactions;

import org.apache.cassandra.db.DeletionTime;
import org.apache.cassandra.db.RangeTombstone;
import org.apache.cassandra.db.rows.Row;

/**
 * Handling of index updates on the write path.
 *
 * Instances of an UpdateTransaction are scoped to a single partition update
 * A new instance is used for every write, obtained from the
 * newUpdateTransaction(PartitionUpdate) method. Likewise, a single
 * CleanupTransaction instance is used for each partition processed during a
 * compaction or cleanup.
 *
 * We make certain guarantees about the lifecycle of each UpdateTransaction
 * instance. Namely that start() will be called before any other method, and
 * commit() will be called at the end of the update.
 * Each instance is initialized with 1..many Index.Indexer instances, one per
 * registered Index. As with the transaction itself, these are scoped to a
 * specific partition update, so implementations can be assured that all indexing
 * events they receive relate to the same logical operation.
 *
 * onPartitionDelete(), onRangeTombstone(), onInserted() and onUpdated()
 * calls may arrive in any order, but this should have no impact for the
 * Indexers being notified as any events delivered to a single instance
 * necessarily relate to a single partition.
 *
 * The typical sequence of events during a Memtable update would be:
 * start()                       -- no-op, used to notify Indexers of the start of the transaction
 * onPartitionDeletion(dt)       -- if the PartitionUpdate implies one
 * onRangeTombstone(rt)*         -- for each in the PartitionUpdate, if any
 *
 * then:
 * onInserted(row)*              -- called for each Row not already present in the Memtable
 * onUpdated(existing, updated)* -- called for any Row in the update for where a version was already present
 *                                  in the Memtable. It's important to note here that existing is the previous
 *                                  row from the Memtable & updated is the final version replacing it. It is
 *                                  *not* the incoming row, but the result of merging the incoming and existing
 *                                  rows.
 * commit()                      -- finally, finish is called when the new Partition is swapped into the Memtable
 */
public interface UpdateTransaction extends IndexTransaction
{
    void onPartitionDeletion(DeletionTime deletionTime);
    void onRangeTombstone(RangeTombstone rangeTombstone);
    void onInserted(Row row);
    void onUpdated(Row existing, Row updated);

    UpdateTransaction NO_OP = new UpdateTransaction()
    {
        public void start(){}
        public void onPartitionDeletion(DeletionTime deletionTime){}
        public void onRangeTombstone(RangeTombstone rangeTombstone){}
        public void onInserted(Row row){}
        public void onUpdated(Row existing, Row updated){}
        public void commit(){}
    };
}
