/*
* Licensed 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 com.addthis.hydra.data.tree;
import javax.annotation.Nonnull;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.util.Objects;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import com.addthis.codec.config.Configs;
import com.addthis.codec.jackson.Jackson;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import static com.google.common.base.Objects.toStringHelper;
/**
* Holds tree configuration settings. Expected use case is decode this object from a job config, use it during
* processing, and to write to a file in the tree directory for later debugging or use by the query system. This means
* there is no need for it to be deserialized from local storage during task processing, but this is not guaranteed to
* be the case forever (it may be useful).
* <p/>
* All settings that are currently a mix of various system properties should probably be moved here over time.
*/
public final class TreeConfig {
private static final Logger log = LoggerFactory.getLogger(TreeConfig.class);
private static final Path CONFIG_FILE = Paths.get("tree.config");
/** How much (query) cache space should be reserved for this tree relative to normal. */
public final double cacheWeight;
/** (dangerous!) Forces a (query) cache weight of zero regardless of actual memory usage or cache ratio. */
public final boolean unevictable;
public TreeConfig(@JsonProperty("cacheWeight") double cacheWeight,
@JsonProperty("unevictable") boolean unevictable) {
this.cacheWeight = cacheWeight;
this.unevictable = unevictable;
}
@JsonIgnore public double cacheWeight() {
if (unevictable) {
return 0;
} else {
return cacheWeight;
}
}
@Nonnull public static TreeConfig readFromDataDirectory(Path dir) {
Path path = dir.resolve(CONFIG_FILE);
try {
if (Files.exists(path)) {
return Jackson.defaultMapper().readValue(path.toFile(), TreeConfig.class);
} else {
return Configs.newDefault(TreeConfig.class);
}
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
public static void writeConfigToDataDirectory(Path dir, TreeConfig config) {
Path path = dir.resolve(CONFIG_FILE);
try {
Jackson.defaultMapper().writeValue(path.toFile(), config);
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
@Override public boolean equals(Object o) {
if (this == o) {
return true;
}
if ((o == null) || (this.getClass() != o.getClass())) {
return false;
}
TreeConfig config = (TreeConfig) o;
return Objects.equals(this.cacheWeight, config.cacheWeight) &&
Objects.equals(this.unevictable, config.unevictable);
}
@Override public int hashCode() {
return Objects.hash(this.cacheWeight, this.unevictable);
}
@Override public String toString() {
return toStringHelper(this)
.add("cacheWeight", cacheWeight)
.add("unevictable", unevictable)
.toString();
}
}