Promote SchemaSourceRepresentation
[yangtools.git] / yang / yang-repo-spi / src / main / java / org / opendaylight / yangtools / yang / model / repo / spi / GuavaSchemaSourceCache.java
1 /*
2  * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.yangtools.yang.model.repo.spi;
9
10 import com.google.common.annotations.Beta;
11 import com.google.common.base.FinalizablePhantomReference;
12 import com.google.common.base.FinalizableReferenceQueue;
13 import com.google.common.cache.Cache;
14 import com.google.common.cache.CacheBuilder;
15 import com.google.common.util.concurrent.FluentFuture;
16 import java.time.Duration;
17 import java.util.ArrayList;
18 import java.util.Collections;
19 import java.util.List;
20 import java.util.concurrent.TimeUnit;
21 import org.eclipse.jdt.annotation.NonNull;
22 import org.opendaylight.yangtools.util.concurrent.FluentFutures;
23 import org.opendaylight.yangtools.yang.model.api.source.SourceIdentifier;
24 import org.opendaylight.yangtools.yang.model.api.source.SourceRepresentation;
25 import org.opendaylight.yangtools.yang.model.repo.api.MissingSchemaSourceException;
26
27 /**
28  * A simple {@link AbstractSchemaSourceCache} based on {@link Cache Guava Cache}.
29  *
30  * @param <T> {@link SourceRepresentation} type stored in this cache
31  * @deprecated This class has a rather complicated and ugly design. Use {@link SoftSchemaSourceCache} instead.
32  */
33 @Beta
34 @Deprecated(since = "7.0.13", forRemoval = true)
35 public final class GuavaSchemaSourceCache<T extends SourceRepresentation> extends AbstractSchemaSourceCache<T>
36         implements AutoCloseable {
37     // FIXME: 7.0.0: use a java.util.Cleaner?
38     private final List<FinalizablePhantomReference<T>> regs = Collections.synchronizedList(new ArrayList<>());
39     private final FinalizableReferenceQueue queue = new FinalizableReferenceQueue();
40     private final Cache<SourceIdentifier, T> cache;
41
42     private GuavaSchemaSourceCache(final SchemaSourceRegistry consumer, final Class<T> representation,
43             final CacheBuilder<Object, Object> cacheBuilder) {
44         super(consumer, representation, PotentialSchemaSource.Costs.IMMEDIATE);
45         cache = cacheBuilder.build();
46     }
47
48     public static <R extends SourceRepresentation> @NonNull GuavaSchemaSourceCache<R> createSoftCache(
49             final SchemaSourceRegistry consumer, final Class<R> representation) {
50         return new GuavaSchemaSourceCache<>(consumer, representation, CacheBuilder.newBuilder().softValues());
51     }
52
53     public static <R extends SourceRepresentation> @NonNull GuavaSchemaSourceCache<R> createSoftCache(
54             final SchemaSourceRegistry consumer, final Class<R> representation, final long lifetime,
55             final TimeUnit units) {
56         return new GuavaSchemaSourceCache<>(consumer, representation, CacheBuilder.newBuilder().softValues()
57             .expireAfterAccess(lifetime, units));
58     }
59
60     public static <R extends SourceRepresentation> @NonNull GuavaSchemaSourceCache<R> createSoftCache(
61             final SchemaSourceRegistry consumer, final Class<R> representation, final Duration duration) {
62         return new GuavaSchemaSourceCache<>(consumer, representation, CacheBuilder.newBuilder().softValues()
63             .expireAfterAccess(duration));
64     }
65
66     @Override
67     public FluentFuture<? extends T> getSource(final SourceIdentifier sourceId) {
68         final T present = cache.getIfPresent(sourceId);
69         return present != null ? FluentFutures.immediateFluentFuture(present)
70                 : FluentFutures.immediateFailedFluentFuture(
71                     new MissingSchemaSourceException("Source not found", sourceId));
72     }
73
74     @Override
75     protected void offer(final T source) {
76         final var srcId = source.sourceId();
77         if (cache.getIfPresent(srcId) != null) {
78             // We already have this source, do not track it
79             return;
80         }
81
82         // Make the source available
83         cache.put(srcId, source);
84         final var reg = register(srcId);
85
86         final var ref = new FinalizablePhantomReference<>(source, queue) {
87             @Override
88             public void finalizeReferent() {
89                 reg.close();
90                 regs.remove(this);
91             }
92         };
93
94         regs.add(ref);
95     }
96
97     @Override
98     public void close() {
99         while (!regs.isEmpty()) {
100             final FinalizablePhantomReference<?> ref = regs.get(0);
101             ref.finalizeReferent();
102         }
103
104         cache.invalidateAll();
105         queue.close();
106     }
107 }