com.b2international.snowowl.datastore.index.ImmutableIndexCommitChangeSet.java Source code

Java tutorial

Introduction

Here is the source code for com.b2international.snowowl.datastore.index.ImmutableIndexCommitChangeSet.java

Source

/*
 * Copyright 2011-2016 B2i Healthcare Pte Ltd, http://b2i.sg
 * 
 * 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.b2international.snowowl.datastore.index;

import java.io.IOException;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import com.b2international.index.revision.Revision;
import com.b2international.index.revision.RevisionWriter;
import com.b2international.snowowl.core.ComponentIdentifier;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableMultimap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Multimap;
import com.google.common.collect.Sets;

/**
 * @since 5.0
 */
public final class ImmutableIndexCommitChangeSet implements IndexCommitChangeSet {

    private final Map<String, Object> rawMappings;
    private final Multimap<Class<?>, String> rawDeletions;
    private final Map<Long, Revision> revisionMappings;
    private final Multimap<Class<? extends Revision>, Long> revisionDeletions;
    private final Collection<ComponentIdentifier> newComponents;
    private final Collection<ComponentIdentifier> changedComponents;
    private final Collection<ComponentIdentifier> deletedComponents;

    private ImmutableIndexCommitChangeSet(final Map<String, Object> rawMappings,
            final Multimap<Class<?>, String> rawDeletions, final Map<Long, Revision> revisionMappings,
            final Multimap<Class<? extends Revision>, Long> revisionDeletions,
            final Collection<ComponentIdentifier> newComponents,
            final Collection<ComponentIdentifier> changedComponents,
            final Collection<ComponentIdentifier> deletedComponents) {
        this.rawMappings = rawMappings;
        this.rawDeletions = rawDeletions;
        this.revisionMappings = revisionMappings;
        this.revisionDeletions = revisionDeletions;
        this.newComponents = newComponents;
        this.changedComponents = changedComponents;
        this.deletedComponents = deletedComponents;
    }

    @Override
    public boolean isEmpty() {
        return rawMappings.isEmpty() && rawDeletions.isEmpty() && revisionMappings.isEmpty()
                && revisionDeletions.isEmpty();
    }

    @Override
    public Collection<ComponentIdentifier> getNewComponents() {
        return newComponents;
    }

    @Override
    public Collection<ComponentIdentifier> getChangedComponents() {
        return changedComponents;
    }

    @Override
    public Collection<ComponentIdentifier> getDeletedComponents() {
        return deletedComponents;
    }

    @Override
    public Map<String, Object> getRawMappings() {
        return rawMappings;
    }

    @Override
    public Multimap<Class<?>, String> getRawDeletions() {
        return rawDeletions;
    }

    @Override
    public Map<Long, Revision> getRevisionMappings() {
        return revisionMappings;
    }

    @Override
    public Multimap<Class<? extends Revision>, Long> getRevisionDeletions() {
        return revisionDeletions;
    }

    @Override
    public IndexCommitChangeSet merge(IndexCommitChangeSet indexCommitChangeSet) {
        return builder().from(this).from(indexCommitChangeSet).build();
    }

    /**
     * Apply this {@link ImmutableIndexCommitChangeSet} on the given {@link RevisionWriter index transaction}.
     * 
     * @param index
     * @throws IOException
     */
    @Override
    public void apply(RevisionWriter index) throws IOException {
        for (final Class<?> type : rawDeletions.keySet()) {
            final Map<Class<?>, Set<String>> map = Collections.<Class<?>, Set<String>>singletonMap(type,
                    Sets.newHashSet(rawDeletions.get(type)));
            index.writer().removeAll(map);
        }

        for (Entry<String, Object> doc : rawMappings.entrySet()) {
            if (!rawDeletions.containsValue(doc.getKey())) {
                index.writer().put(doc.getKey(), doc.getValue());
            }
        }

        final Multimap<Class<? extends Revision>, Long> copiedRevision = ImmutableMultimap
                .copyOf(revisionDeletions);
        for (Class<? extends Revision> type : copiedRevision.keySet()) {
            index.remove(type, copiedRevision.get(type));
        }

        for (Entry<Long, Revision> doc : revisionMappings.entrySet()) {
            if (!revisionDeletions.containsValue(doc.getKey())) {
                index.put(doc.getKey(), doc.getValue());
            }
        }
    }

    /**
     * Returns a human-readable description of this changes containing the number of add/updated and deleted documents. 
     * @return
     */
    @Override
    public String getDescription() {
        return String.format("Indexed %d documents, deleted %d documents.",
                rawMappings.size() + revisionMappings.size(),
                rawDeletions.values().size() + revisionDeletions.values().size());
    }

    /**
     * Create a new {@link Builder} instance.
     * 
     * @return
     */
    public static Builder builder() {
        return new Builder();
    }

    /**
     * Builder to simplify construction of {@link ImmutableIndexCommitChangeSet} objects.
     * 
     * @since 5.0
     */
    public static class Builder {

        private final ImmutableMap.Builder<String, Object> rawMappings = ImmutableMap.builder();
        private final ImmutableMultimap.Builder<Class<?>, String> rawDeletions = ImmutableMultimap.builder();
        private final ImmutableMap.Builder<Long, Revision> revisionMappings = ImmutableMap.builder();
        private final ImmutableMultimap.Builder<Class<? extends Revision>, Long> revisionDeletions = ImmutableMultimap
                .builder();
        private final ImmutableSet.Builder<ComponentIdentifier> newComponents = ImmutableSet.builder();
        private final ImmutableSet.Builder<ComponentIdentifier> changedComponents = ImmutableSet.builder();
        private final ImmutableSet.Builder<ComponentIdentifier> deletedComponents = ImmutableSet.builder();

        private Builder() {
        }

        public Builder from(IndexCommitChangeSet indexCommitChangeSet) {
            this.rawMappings.putAll(indexCommitChangeSet.getRawMappings());
            this.rawDeletions.putAll(indexCommitChangeSet.getRawDeletions());
            this.revisionMappings.putAll(indexCommitChangeSet.getRevisionMappings());
            this.revisionDeletions.putAll(indexCommitChangeSet.getRevisionDeletions());
            this.newComponents.addAll(indexCommitChangeSet.getNewComponents());
            this.changedComponents.addAll(indexCommitChangeSet.getChangedComponents());
            this.deletedComponents.addAll(indexCommitChangeSet.getDeletedComponents());
            return this;
        }

        public Builder putNewComponents(ComponentIdentifier newComponent) {
            this.newComponents.add(newComponent);
            return this;
        }

        public Builder putChangedComponents(ComponentIdentifier changedComponent) {
            this.changedComponents.add(changedComponent);
            return this;
        }

        public Builder putDeletedComponents(ComponentIdentifier deletedComponent) {
            this.deletedComponents.add(deletedComponent);
            return this;
        }

        public Builder putRawMappings(String key, Object value) {
            this.rawMappings.put(key, value);
            return this;
        }

        public Builder putRawDeletions(Class<?> type, String key) {
            this.rawDeletions.put(type, key);
            return this;
        }

        public Builder putRawDeletions(Class<?> type, Iterable<? extends String> keys) {
            this.rawDeletions.putAll(type, keys);
            return this;
        }

        public Builder putRevisionMappings(Long key, Revision value) {
            this.revisionMappings.put(key, value);
            return this;
        }

        public Builder putRevisionMappings(Map<? extends Long, ? extends Revision> mappings) {
            this.revisionMappings.putAll(mappings);
            return this;
        }

        public Builder putRevisionDeletions(
                Multimap<? extends Class<? extends Revision>, ? extends Long> deletions) {
            this.revisionDeletions.putAll(deletions);
            return this;
        }

        public Builder putRevisionDeletions(Class<? extends Revision> type, Long storageKey) {
            this.revisionDeletions.put(type, storageKey);
            return this;
        }

        public Builder putRevisionDeletions(Class<? extends Revision> type, Iterable<? extends Long> storageKeys) {
            this.revisionDeletions.putAll(type, storageKeys);
            return this;
        }

        public IndexCommitChangeSet build() {
            return new ImmutableIndexCommitChangeSet(rawMappings.build(), rawDeletions.build(),
                    revisionMappings.build(), revisionDeletions.build(), newComponents.build(),
                    changedComponents.build(), deletedComponents.build());
        }

    }

}