maedhroz commented on code in PR #2267: URL: https://github.com/apache/cassandra/pull/2267#discussion_r1180582480
########## src/java/org/apache/cassandra/io/sstable/format/bti/PartitionIndexBuilder.java: ########## @@ -0,0 +1,235 @@ +/* + * 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.io.sstable.format.bti; + +import java.io.IOException; +import java.util.function.Consumer; + +import org.apache.cassandra.db.DecoratedKey; +import org.apache.cassandra.io.tries.IncrementalTrieWriter; +import org.apache.cassandra.io.tries.Walker; +import org.apache.cassandra.io.util.FileHandle; +import org.apache.cassandra.io.util.SequentialWriter; +import org.apache.cassandra.utils.ByteBufferUtil; +import org.apache.cassandra.utils.bytecomparable.ByteComparable; + +/** + * Partition index builder: stores index or data positions in an incrementally built, page aware on-disk trie. + * <p> + * The files created by this builder are read by {@link PartitionIndex}. + */ +class PartitionIndexBuilder implements AutoCloseable +{ + private final SequentialWriter writer; + private final IncrementalTrieWriter<PartitionIndex.Payload> trieWriter; + private final FileHandle.Builder fhBuilder; + + // the last synced data file position + private long dataSyncPosition; + // the last synced row index file position + private long rowIndexSyncPosition; + // the last synced partition index file position + private long partitionIndexSyncPosition; + + // Partial index can only be used after all three files have been synced to the required positions. + private long partialIndexDataEnd; + private long partialIndexRowEnd; + private long partialIndexPartitionEnd; + private IncrementalTrieWriter.PartialTail partialIndexTail; + private Consumer<PartitionIndex> partialIndexConsumer; + private DecoratedKey partialIndexLastKey; + + private int lastDiffPoint; + private DecoratedKey firstKey; + private DecoratedKey lastKey; + private DecoratedKey lastWrittenKey; + private PartitionIndex.Payload lastPayload; + + public PartitionIndexBuilder(SequentialWriter writer, FileHandle.Builder fhBuilder) + { + this.writer = writer; + this.trieWriter = IncrementalTrieWriter.open(PartitionIndex.TRIE_SERIALIZER, writer); + this.fhBuilder = fhBuilder; + } + + /* + * Called when partition index has been flushed to the given position. + * If this makes all required positions for a partial view flushed, this will call the partialIndexConsumer. + */ + public void markPartitionIndexSynced(long upToPosition) + { + partitionIndexSyncPosition = upToPosition; + refreshReadableBoundary(); + } + + /* + * Called when row index has been flushed to the given position. + * If this makes all required positions for a partial view flushed, this will call the partialIndexConsumer. + */ + public void markRowIndexSynced(long upToPosition) + { + rowIndexSyncPosition = upToPosition; + refreshReadableBoundary(); + } + + /* + * Called when data file has been flushed to the given position. + * If this makes all required positions for a partial view flushed, this will call the partialIndexConsumer. + */ + public void markDataSynced(long upToPosition) + { + dataSyncPosition = upToPosition; + refreshReadableBoundary(); + } + + private void refreshReadableBoundary() + { + if (partialIndexConsumer == null) + return; + if (dataSyncPosition < partialIndexDataEnd) + return; + if (rowIndexSyncPosition < partialIndexRowEnd) + return; + if (partitionIndexSyncPosition < partialIndexPartitionEnd) + return; + + try (FileHandle fh = fhBuilder.withLengthOverride(writer.getLastFlushOffset()).complete()) + { + @SuppressWarnings({ "resource", "RedundantSuppression" }) + PartitionIndex pi = new PartitionIndexEarly(fh, partialIndexTail.root(), partialIndexTail.count(), firstKey, partialIndexLastKey, partialIndexTail.cutoff(), partialIndexTail.tail()); + partialIndexConsumer.accept(pi); + partialIndexConsumer = null; + } + finally + { + fhBuilder.withLengthOverride(-1); + } + + } + + /** + * @param decoratedKey the key for this record + * @param position the position to write with the record: + * - positive if position points to an index entry in the index file + * - negative if ~position points directly to the key in the data file + */ + public PartitionIndexBuilder addEntry(DecoratedKey decoratedKey, long position) throws IOException Review Comment: nit: return value is never used? -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected] --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]

