forked from apache/cassandra
-
Notifications
You must be signed in to change notification settings - Fork 22
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Allow custom SAI index component discovery
Refactor the code that "discover" which SAI components files an SSTable has to allow making that code customizable. The default behavior remains the existing one, that is the TOC file is consulted, with a fallback to scanning disk if the TOC file is missing or corrupted. The way to customize this behavior is similar to what `SSTableWatcher` does: a new system property, `-Dcassandra.sai.custom_components_discovery_class` allows to load a specific class (that extends the `IndexCoomponentDiscovery` class) instead of the default. As part of the refactor to make this new customisability easier, this introduces a new `ComponentsBuildId` class that is the pair of the version and generation of a group of components, since this is what ultimately defines a given component "group" build.
- Loading branch information
Showing
17 changed files
with
366 additions
and
236 deletions.
There are no files selected for viewing
This file contains 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 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 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 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 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 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
128 changes: 128 additions & 0 deletions
128
src/java/org/apache/cassandra/index/sai/disk/format/ComponentsBuildId.java
This file contains 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 |
---|---|---|
@@ -0,0 +1,128 @@ | ||
/* | ||
* 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.sai.disk.format; | ||
|
||
import java.util.Objects; | ||
import java.util.function.Predicate; | ||
|
||
import javax.annotation.Nullable; | ||
|
||
import org.apache.cassandra.db.SerializationHeader; | ||
import org.apache.cassandra.index.sai.IndexContext; | ||
|
||
/** | ||
* Identifies a particular build of a per-sstable or per-index group of SAI index components, aka a pair of the | ||
* {@link Version} built and the generation. | ||
*/ | ||
public class ComponentsBuildId implements Comparable<ComponentsBuildId> | ||
{ | ||
private static final ComponentsBuildId FOR_NEW_SSTABLE = ComponentsBuildId.latest(0); | ||
|
||
private final Version version; | ||
private final int generation; | ||
|
||
private ComponentsBuildId(Version version, int generation) | ||
{ | ||
this.version = version; | ||
this.generation = generation; | ||
} | ||
|
||
public static ComponentsBuildId of(Version version, int generation) | ||
{ | ||
return new ComponentsBuildId(version, generation); | ||
} | ||
|
||
public static ComponentsBuildId latest(int generation) | ||
{ | ||
return of(Version.latest(), generation); | ||
} | ||
|
||
public static ComponentsBuildId forNewSSTable() | ||
{ | ||
return FOR_NEW_SSTABLE; | ||
} | ||
|
||
public static ComponentsBuildId forNewBuild(@Nullable ComponentsBuildId previousBuild, Predicate<ComponentsBuildId> newBuildIsUsablePredicate) | ||
{ | ||
Version version = Version.latest(); | ||
// If we're not using immutable components, we always use generation 0, and we're fine if that overrides existing files | ||
if (!version.useImmutableComponentFiles()) | ||
return new ComponentsBuildId(version, 0); | ||
|
||
// Otherwise, if there is no previous build or the new build is for a new version, then we can "tentatively" | ||
// use generation 0, but if not, we need to bump the generation. | ||
int generation = previousBuild != null && previousBuild.version.equals(version) ? previousBuild.generation + 1 : 0; | ||
var candidate = new ComponentsBuildId(version, generation); | ||
|
||
// Usually, the candidate above is fine, but we want to avoid overriding existing file (it's theoretically | ||
// possible that the next generation was created at some other point, but then corrupted, and so we falled back | ||
// on the previous generation but some of those file for the next generation still exists). So we check, | ||
// repeatedly if that candidate is usable, incrementing the generation until we find one which is. | ||
while (!newBuildIsUsablePredicate.test(candidate)) | ||
candidate = new ComponentsBuildId(version, ++generation); | ||
|
||
return candidate; | ||
} | ||
|
||
public Version version() | ||
{ | ||
return version; | ||
} | ||
|
||
public int generation() | ||
{ | ||
return generation; | ||
} | ||
|
||
public String formatAsComponent(IndexComponentType indexComponentType, IndexContext indexContext) | ||
{ | ||
return version.fileNameFormatter().format(indexComponentType, indexContext, generation); | ||
} | ||
|
||
@Override | ||
public boolean equals(Object obj) | ||
{ | ||
if (!(obj instanceof ComponentsBuildId)) | ||
return false; | ||
ComponentsBuildId that = (ComponentsBuildId) obj; | ||
return this.version.equals(that.version) && this.generation == that.generation; | ||
} | ||
|
||
@Override | ||
public int hashCode() | ||
{ | ||
return Objects.hash(version, generation); | ||
} | ||
|
||
@Override | ||
public int compareTo(ComponentsBuildId that) | ||
{ | ||
if (this.version.equals(that.version)) | ||
return Integer.compare(generation, that.generation); | ||
|
||
return this.version.onOrAfter(that.version) ? 1 : -1; | ||
} | ||
|
||
@Override | ||
public String toString() | ||
{ | ||
return version + "@" + generation; | ||
} | ||
|
||
} |
Oops, something went wrong.