blob: 81e5958e6276eef0e6134e124094b3b61c70f16a [file] [log] [blame]
/*=============================================================================#
# Copyright (c) 2012, 2021 Stephan Wahlbrink and others.
#
# This program and the accompanying materials are made available under the
# terms of the Eclipse Public License 2.0 which is available at
# https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
# which is available at https://www.apache.org/licenses/LICENSE-2.0.
#
# SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
#
# Contributors:
# Stephan Wahlbrink <sw@wahlbrink.eu> - initial API and implementation
#=============================================================================*/
package org.eclipse.statet.rj.renv.core;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.eclipse.statet.jcommons.collections.SortedArraySet;
import org.eclipse.statet.jcommons.lang.NonNull;
import org.eclipse.statet.jcommons.lang.NonNullByDefault;
import org.eclipse.statet.jcommons.lang.Nullable;
@NonNullByDefault
public class BasicRPkgCompilation<T extends RPkg> implements RPkgCompilation<T> {
/** Package sources */
private final List<String> sources;
/** Packages by sources */
private final List<RPkgList<T>> pkgLists;
private @Nullable volatile List<String> names;
public BasicRPkgCompilation(final int size) {
this.sources= new ArrayList<>(size);
this.pkgLists= new ArrayList<>(size);
}
public void add(final String source, final RPkgList<T> list) {
this.sources.add((source != null) ? source : ""); //$NON-NLS-1$
this.pkgLists.add(list);
}
public RPkgList<T> getOrAdd(final String source) {
RPkgList<T> list= getBySource(source);
if (list == null) {
list= newPkgList();
add(source, list);
}
return list;
}
protected RPkgList<T> newPkgList() {
return new BasicRPkgList<>(4);
}
@Override
@SuppressWarnings("null")
public List<String> getNames() {
if (this.names == null) {
createNames();
}
return this.names;
}
private synchronized void createNames() {
if (this.names != null) {
return;
}
if (this.pkgLists.isEmpty()) {
this.names= Collections.emptyList();
return;
}
{ final SortedArraySet<String> names= new SortedArraySet<>(
new @NonNull String[Math.min(16, this.pkgLists.get(0).size())], 0,
RPkgUtils.NAMES_COLLATOR );
for (final RPkgList<? extends RPkg> list : this.pkgLists) {
for (int i= 0; i < list.size(); i++) {
names.addE(list.get(i).getName());
}
}
this.names= Collections.unmodifiableList(names);
}
}
@Override
public boolean contains(final String name) {
for (final RPkgList<? extends RPkg> list : this.pkgLists) {
final int idx= list.indexOf(name);
if (idx >= 0) {
return true;
}
}
return false;
}
@Override
public @Nullable T getFirst(final String name) {
for (final RPkgList<T> list : this.pkgLists) {
final int idx= list.indexOf(name);
if (idx >= 0) {
return list.get(idx);
}
}
return null;
}
@Override
public List<T> get(final String name) {
List<T> result= null;
for (final RPkgList<T> list : this.pkgLists) {
final int idx= list.indexOf(name);
if (idx >= 0) {
if (result == null) {
result= new ArrayList<>(2);
}
result.add(list.get(idx));
}
}
return (result != null) ? result : Collections.<T>emptyList();
}
@Override
public List<String> getSources() {
return this.sources;
}
@Override
public @Nullable RPkgList<T> getBySource(final String source) {
final int idx= this.sources.indexOf(source);
return (idx >= 0) ? this.pkgLists.get(idx) : null;
}
@Override
public List<RPkgList<T>> getAll() {
return this.pkgLists;
}
}