// Copyright 2014 Google Inc. All rights reserved. // // 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.google.devtools.build.lib.collect.nestedset; import com.google.common.collect.ImmutableCollection; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; import java.util.List; import java.util.Set; /** * A NestedSet that keeps a memoized uniquifier so that it is faster to fill a set. * *

This class does not keep the memoized object itself so that we can take advantage of the * memory field alignment (Memory alignment does not put in the same structure the fields of a * class and its extensions). */ public abstract class MemoizedUniquefierNestedSet extends NestedSet { @Override public List toList() { ImmutableList.Builder builder = new ImmutableList.Builder<>(); memoizedFill(builder); return builder.build(); } @Override public Set toSet() { ImmutableSet.Builder builder = new ImmutableSet.Builder<>(); memoizedFill(builder); return builder.build(); } /** * It does not make sense to have a {@code MemoizedUniquefierNestedSet} if it is empty. */ @Override public boolean isEmpty() { return false; } abstract Object getMemo(); abstract void setMemo(Object object); /** * Fill a collection builder by using a memoized {@code Uniqueifier} for faster uniqueness check. */ final void memoizedFill(ImmutableCollection.Builder builder) { Uniqueifier memoed; synchronized (this) { Object memo = getMemo(); if (memo == null) { RecordingUniqueifier uniqueifier = new RecordingUniqueifier(); getOrder().expander().expandInto(this, uniqueifier, builder); setMemo(uniqueifier.getMemo()); return; } else { memoed = RecordingUniqueifier.createReplayUniqueifier(memo); } } getOrder().expander().expandInto(this, memoed, builder); } }