/*
 * 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.ignite.internal.binary;

import org.jetbrains.annotations.Nullable;

import java.util.HashMap;

/**
 * Binary schema registry. Contains all well-known object schemas.
 * <p>
 * We rely on the fact that usually object has only few different schemas. For this reason we inline several
 * of them with optional fallback to normal hash map lookup.
 *
 */
public class BinarySchemaRegistry {
    /** Empty schema ID. */
    private static final int EMPTY = 0;

    /** Whether registry still works in inline mode. */
    private volatile boolean inline = true;

    /** First schema ID. */
    private int schemaId1;

    /** Second schema ID. */
    private int schemaId2;

    /** Third schema ID. */
    private int schemaId3;

    /** Fourth schema ID. */
    private int schemaId4;

    /** First schema. */
    private BinarySchema schema1;

    /** Second schema. */
    private BinarySchema schema2;

    /** Third schema. */
    private BinarySchema schema3;

    /** Fourth schema. */
    private BinarySchema schema4;

    /** Schemas with COW semantics. */
    private volatile HashMap<Integer, BinarySchema> schemas;

    /**
     * Get schema for the given ID. We rely on very relaxed memory semantics here assuming that it is not critical
     * to return false-positive {@code null} values.
     *
     * @param schemaId Schema ID.
     * @return Schema or {@code null}.
     */
    @Nullable public BinarySchema schema(int schemaId) {
        if (inline) {
            if (schemaId == schemaId1)
                return schema1;
            else if (schemaId == schemaId2)
                return schema2;
            else if (schemaId == schemaId3)
                return schema3;
            else if (schemaId == schemaId4)
                return schema4;
        }
        else {
            HashMap<Integer, BinarySchema> schemas0 = schemas;

            // Null can be observed here due to either data race or race condition when switching to non-inlined mode.
            // Both of them are benign for us because they lead only to unnecessary schema re-calc.
            if (schemas0 != null)
                return schemas0.get(schemaId);
        }

        return null;
    }

    /**
     * Add schema.
     *
     * @param schemaId Schema ID.
     * @param schema Schema.
     */
    public void addSchema(int schemaId, BinarySchema schema) {
        synchronized (this) {
            if (inline) {
                // Check if this is already known schema.
                if (schemaId == schemaId1 || schemaId == schemaId2 || schemaId == schemaId3 || schemaId == schemaId4)
                    return;

                // Try positioning new schema in inline mode.
                if (schemaId1 == EMPTY) {
                    schemaId1 = schemaId;

                    schema1 = schema;

                    inline = true; // Forcing HB edge just in case.

                    return;
                }

                if (schemaId2 == EMPTY) {
                    schemaId2 = schemaId;

                    schema2 = schema;

                    inline = true; // Forcing HB edge just in case.

                    return;
                }

                if (schemaId3 == EMPTY) {
                    schemaId3 = schemaId;

                    schema3 = schema;

                    inline = true; // Forcing HB edge just in case.

                    return;
                }

                if (schemaId4 == EMPTY) {
                    schemaId4 = schemaId;

                    schema4 = schema;

                    inline = true; // Forcing HB edge just in case.

                    return;
                }

                // No luck, switching to hash map mode.
                HashMap<Integer, BinarySchema> newSchemas = new HashMap<>();

                newSchemas.put(schemaId1, schema1);
                newSchemas.put(schemaId2, schema2);
                newSchemas.put(schemaId3, schema3);
                newSchemas.put(schemaId4, schema4);

                newSchemas.put(schemaId, schema);

                schemas = newSchemas;

                inline = false;
            }
            else {
                HashMap<Integer, BinarySchema> newSchemas = new HashMap<>(schemas);

                newSchemas.put(schemaId, schema);

                schemas = newSchemas;
            }
        }
    }
}
