forked from apache/cassandra
-
Notifications
You must be signed in to change notification settings - Fork 21
CNDB-11613 SAI compressed indexes #1474
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
pkolaczk
wants to merge
2
commits into
main
Choose a base branch
from
c11613-sai-compression
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -18,6 +18,7 @@ | |
|
||
package org.apache.cassandra.index.sai; | ||
|
||
import java.io.IOException; | ||
import java.nio.ByteBuffer; | ||
import java.util.ArrayList; | ||
import java.util.Collection; | ||
|
@@ -36,7 +37,10 @@ | |
import java.util.concurrent.Callable; | ||
import java.util.concurrent.CompletableFuture; | ||
import java.util.concurrent.Future; | ||
import java.util.function.BiFunction; | ||
import java.util.function.BooleanSupplier; | ||
import java.util.function.Function; | ||
import java.util.function.Supplier; | ||
import java.util.stream.Collectors; | ||
|
||
import com.google.common.annotations.VisibleForTesting; | ||
|
@@ -99,6 +103,7 @@ | |
import org.apache.cassandra.io.sstable.format.SSTableFlushObserver; | ||
import org.apache.cassandra.io.sstable.format.SSTableReader; | ||
import org.apache.cassandra.schema.ColumnMetadata; | ||
import org.apache.cassandra.schema.CompressionParams; | ||
import org.apache.cassandra.schema.IndexMetadata; | ||
import org.apache.cassandra.schema.TableMetadata; | ||
import org.apache.cassandra.service.ClientWarn; | ||
|
@@ -200,6 +205,8 @@ public List<SecondaryIndexBuilder> getParallelIndexBuildTasks(ColumnFamilyStore | |
NonTokenizingOptions.ASCII, | ||
// For now, we leave this for backward compatibility even though it's not used | ||
IndexContext.ENABLE_SEGMENT_COMPACTION_OPTION_NAME, | ||
IndexContext.KEY_COMPRESSION_OPTION_NAME, | ||
IndexContext.VALUE_COMPRESSION_OPTION_NAME, | ||
IndexTarget.TARGET_OPTION_NAME, | ||
IndexTarget.CUSTOM_INDEX_OPTION_NAME, | ||
IndexWriterConfig.POSTING_LIST_LVL_MIN_LEAVES, | ||
|
@@ -228,7 +235,6 @@ public List<SecondaryIndexBuilder> getParallelIndexBuildTasks(ColumnFamilyStore | |
ImmutableSet.of(OrderPreservingPartitioner.class, LocalPartitioner.class, ByteOrderedPartitioner.class, RandomPartitioner.class); | ||
|
||
private final ColumnFamilyStore baseCfs; | ||
private final IndexMetadata config; | ||
private final IndexContext indexContext; | ||
|
||
// Tracks whether or not we've started the index build on initialization. | ||
|
@@ -243,7 +249,6 @@ public List<SecondaryIndexBuilder> getParallelIndexBuildTasks(ColumnFamilyStore | |
public StorageAttachedIndex(ColumnFamilyStore baseCfs, IndexMetadata config) | ||
{ | ||
this.baseCfs = baseCfs; | ||
this.config = config; | ||
TableMetadata tableMetadata = baseCfs.metadata(); | ||
Pair<ColumnMetadata, IndexTarget.Type> target = TargetParser.parse(tableMetadata, config); | ||
this.indexContext = new IndexContext(tableMetadata.keyspace, | ||
|
@@ -320,6 +325,27 @@ public static Map<String, String> validateOptions(Map<String, String> options, T | |
if (duplicateCount > 1) | ||
throw new InvalidRequestException(String.format("Cannot create duplicate storage-attached index on column: %s", target.left)); | ||
|
||
// Get to validate only; will throw IRE if option is invalid | ||
CompressionParams valueCompression = getCompressionOptionChecked(options, IndexContext.VALUE_COMPRESSION_OPTION_NAME); | ||
Comment on lines
+328
to
+329
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nit: We could put this below, after getting the key compression, and right before checking the format version. That is, immediately before its first usage. |
||
|
||
// Check for existence of other indexes with different key_compression: | ||
CompressionParams keyCompression = getCompressionOptionChecked(options, IndexContext.KEY_COMPRESSION_OPTION_NAME); | ||
for (IndexMetadata other : metadata.indexes) | ||
{ | ||
CompressionParams otherCompression = getCompressionOptionUnchecked(other.options, IndexContext.KEY_COMPRESSION_OPTION_NAME); | ||
if (other.getIndexClassName().equals(StorageAttachedIndex.class.getName()) | ||
&& !otherCompression.equals(keyCompression)) | ||
{ | ||
throw new InvalidRequestException(String.format("Cannot create storage-attached index on column %s with different key_compression than existing index %s. Expected: %s", | ||
target.left, other.name, keyCompression.asMap())); | ||
} | ||
} | ||
|
||
if ((valueCompression.isEnabled() || keyCompression.isEnabled()) && !Version.current().onOrAfter(Version.EC)) | ||
throw new InvalidRequestException("Cannot create compressed storage-attached index. " + | ||
"Enabling index compression requires at least SAI version 'ec'. " + | ||
"Your current index version is set to '" + Version.current() + '\''); | ||
|
||
// Analyzer is not supported against PK columns | ||
if (isAnalyzed) | ||
{ | ||
|
@@ -380,8 +406,68 @@ else if (!SUPPORTED_TYPES.contains(type.asCQL3Type()) && !TypeUtil.isFrozen(type | |
throw new InvalidRequestException("Unsupported type for SAI: " + type.asCQL3Type()); | ||
} | ||
|
||
return Collections.emptyMap(); | ||
return unknown; | ||
} | ||
|
||
/** | ||
* Gets compression params from index metadata option. Does not throw exception if the option is invalid, | ||
* but returns no compression instead. | ||
* | ||
* @param options index options | ||
* @param optionName index option key containing compression params map in JSON format | ||
*/ | ||
public static CompressionParams getCompressionOptionUnchecked(Map<String, String> options, String optionName) | ||
pkolaczk marked this conversation as resolved.
Show resolved
Hide resolved
|
||
{ | ||
return getCompressionOption(options, optionName, (compression,e) -> | ||
{ | ||
logger.error("Invalid value of {}: {} ({}). Falling back to no compression.", | ||
optionName, compression, e.getMessage()); | ||
return CompressionParams.noCompression(); | ||
}); | ||
} | ||
/** | ||
* Gets compression params from index metadata option. | ||
* Returns no compression if the compression option is missing. | ||
* Throws {@link InvalidRequestException} if the compression option is invalid. | ||
* | ||
* @param options index options | ||
* @param optionName index option key containing compression params map in JSON format | ||
*/ | ||
public static CompressionParams getCompressionOptionChecked(Map<String, String> options, String optionName) | ||
{ | ||
return getCompressionOption(options, optionName, (compression,e) -> | ||
{ | ||
throw new InvalidRequestException(String.format("Invalid value of %s: %s (%s)", | ||
optionName, compression, e.getMessage())); | ||
}); | ||
} | ||
|
||
/** | ||
* Gets compression params from index metadata option. | ||
* Returns no compression if the compression option is missing. | ||
* Delegates to onParseError if the compression option is invalid. | ||
* | ||
* @param options index options | ||
* @param optionName index option key containing compression params map in JSON format | ||
*/ | ||
private static CompressionParams getCompressionOption(Map<String, String> options, | ||
String optionName, | ||
BiFunction<String, IOException, CompressionParams> onParseError) | ||
{ | ||
String compression = options.get(optionName); | ||
if (compression == null) | ||
return CompressionParams.noCompression(); | ||
|
||
try | ||
{ | ||
return CompressionParams.fromJson(compression); | ||
} | ||
catch (IOException e) | ||
{ | ||
return onParseError.apply(compression, e); | ||
} | ||
} | ||
|
||
|
||
@Override | ||
public void register(IndexRegistry registry) | ||
|
@@ -399,7 +485,7 @@ public void unregister(IndexRegistry registry) | |
@Override | ||
public IndexMetadata getIndexMetadata() | ||
{ | ||
return config; | ||
return indexContext.getConfig(); | ||
} | ||
|
||
@Override | ||
|
@@ -904,6 +990,7 @@ public IndexContext getIndexContext() | |
@Override | ||
public String toString() | ||
{ | ||
IndexMetadata config = indexContext.getConfig(); | ||
return String.format("%s.%s.%s", baseCfs.keyspace.getName(), baseCfs.name, config == null ? "?" : config.name); | ||
} | ||
|
||
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.