All Downloads are FREE. Search and download functionalities are using the official Maven repository.

jetbrains.exodus.tree.TreeMetaInfo Maven / Gradle / Ivy

There is a newer version: 10.5.0.78949
Show newest version
/**
 * Copyright 2010 - 2022 JetBrains s.r.o.
 *
 * 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
 *
 * https://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 jetbrains.exodus.tree;

import jetbrains.exodus.ByteIterable;
import jetbrains.exodus.ByteIterator;
import jetbrains.exodus.env.EnvironmentImpl;
import jetbrains.exodus.env.StoreConfig;
import jetbrains.exodus.log.CompressedUnsignedLongByteIterable;
import jetbrains.exodus.log.Log;
import jetbrains.exodus.tree.btree.BTreeMetaInfo;
import jetbrains.exodus.tree.patricia.PatriciaMetaInfo;
import jetbrains.exodus.util.LightOutputStream;
import org.jetbrains.annotations.NotNull;

public abstract class TreeMetaInfo {

    public static final TreeMetaInfo EMPTY = new Empty(0);

    protected static final int DUPLICATES_BIT = 1;
    protected static final int KEY_PREFIXING_BIT = 2;

    public final boolean duplicates;
    public final int structureId;
    public final Log log;

    protected TreeMetaInfo(final Log log, final boolean duplicates, final int structureId) {
        this.log = log;
        this.duplicates = duplicates;
        this.structureId = structureId;
    }

    public boolean hasDuplicates() {
        return duplicates;
    }

    public abstract boolean isKeyPrefixing();

    public int getStructureId() {
        return structureId;
    }

    public ByteIterable toByteIterable() { // TODO: generify and extract BTree and Patricia-related stuff to methods
        byte flags = (byte) (duplicates ? DUPLICATES_BIT : 0);
        if (isKeyPrefixing()) {
            flags += KEY_PREFIXING_BIT;
        }
        final LightOutputStream output = new LightOutputStream(10);
        output.write(flags);
        CompressedUnsignedLongByteIterable.fillBytes(0, output); // legacy format
        CompressedUnsignedLongByteIterable.fillBytes(structureId, output);
        return output.asArrayByteIterable();
    }

    public abstract TreeMetaInfo clone(final int newStructureId);

    public static StoreConfig toConfig(@NotNull final TreeMetaInfo metaInfo) {
        if (metaInfo.getStructureId() < 0) {
            return StoreConfig.TEMPORARY_EMPTY;
        }
        return StoreConfig.getStoreConfig(metaInfo.duplicates, metaInfo.isKeyPrefixing());
    }

    public static TreeMetaInfo load(@NotNull final EnvironmentImpl environment,
                                    final boolean duplicates,
                                    final boolean keyPrefixing,
                                    final int structureId) {
        if (keyPrefixing) {
            return new PatriciaMetaInfo(environment.getLog(), duplicates, structureId);
        } else {
            return new BTreeMetaInfo(environment, duplicates, structureId);
        }
    }

    public static TreeMetaInfo load(@NotNull final EnvironmentImpl environment, @NotNull final ByteIterable iterable) {
        final ByteIterator it = iterable.iterator();
        final byte flagsByte = it.next();
        if ((flagsByte & KEY_PREFIXING_BIT) == 0) {
            return BTreeMetaInfo.load(environment, flagsByte, it);
        } else {
            return PatriciaMetaInfo.load(environment, flagsByte, it);
        }
    }

    @NotNull
    public static ExpiredLoggableCollection getTreeLoggables(@NotNull final ITree tree) {
        if (tree.getSize() > 100000) {
            return ExpiredLoggableCollection.getFROM_SCRATCH();
        }
        final ExpiredLoggableCollection result = new ExpiredLoggableCollection();
        final LongIterator it = tree.addressIterator();
        final Log log = tree.getLog();
        while (it.hasNext()) {
            final long nextAddress = it.next();
            result.add(log.readNotNull(tree.getDataIterator(nextAddress), nextAddress));
        }
        return result;
    }

    private static final class Empty extends TreeMetaInfo {
        private Empty(final int structureId) {
            super(null, false, structureId);
        }

        @Override
        public boolean isKeyPrefixing() {
            return false;
        }

        @Override
        public TreeMetaInfo clone(final int newStructureId) {
            return new Empty(newStructureId);
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy