View Javadoc
1   /*
2    * junixsocket
3    *
4    * Copyright 2009-2024 Christian Kohlschütter
5    *
6    * Licensed under the Apache License, Version 2.0 (the "License");
7    * you may not use this file except in compliance with the License.
8    * You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  package org.newsclub.net.unix.pool;
19  
20  import java.io.Closeable;
21  
22  import org.eclipse.jdt.annotation.NonNull;
23  import org.newsclub.net.unix.ThreadUtil;
24  
25  /**
26   * A pool of objects.
27   *
28   * @param <O> The object type.
29   * @author Christian Kohlschütter
30   */
31  public interface ObjectPool<O> {
32  
33    /**
34     * Creates a new {@link ObjectPool} that is used within a single thread; this may or may not be
35     * implemented using {@link ThreadLocal}, however the behavior should be comparable.
36     *
37     * @param <O> The object type.
38     * @param supplier The object supplier.
39     * @param sanitizer The object sanitizer.
40     * @return The object pool.
41     */
42    static <O> ObjectPool<O> newThreadLocalPool(ObjectSupplier<@NonNull O> supplier,
43        ObjectSanitizer<@NonNull O> sanitizer) {
44      if (ThreadUtil.isVirtualThreadSupported()) {
45        return new VirtualAwareThreadLocalObjectPool<>(supplier, sanitizer);
46      } else {
47        return new ThreadLocalObjectPool<>(supplier, sanitizer);
48      }
49    }
50  
51    /**
52     * Returns a {@link Lease} that is not backed by any object pool.
53     *
54     * @param <O> The object type.
55     * @param obj The object.
56     * @return The lease; closing/discarding has no effect.
57     */
58    static <O> Lease<O> unpooledLease(O obj) {
59      return new Lease<O>() {
60  
61        @Override
62        public O get() {
63          return obj;
64        }
65  
66        @Override
67        public void close() {
68        }
69  
70        @Override
71        public void discard() {
72        }
73      };
74    }
75  
76    /**
77     * Takes an exclusive lease of an object from the pool. If no existing object is available from
78     * the pool, a new one may be provided.
79     *
80     * @return The object.
81     */
82    Lease<O> take();
83  
84    /**
85     * Supplies a leased object.
86     *
87     * @param <T> The object type.
88     */
89    @FunctionalInterface
90    interface ObjectSupplier<T> {
91  
92      /**
93       * Gets a result.
94       *
95       * @return a result
96       */
97      T get();
98    }
99  
100   /**
101    * Sanitizes a previously leased object so it can be reused by the pool.
102    *
103    * @param <T> The object type.
104    */
105   @FunctionalInterface
106   interface ObjectSanitizer<T> {
107     /**
108      * Sanitizes a previously leased object so it can be reused by the pool; if the object should
109      * not be reused, {@code false} is returned.
110      *
111      * @param obj The object to sanitize.
112      * @return {@code true} if sanitization was successful, {@code false} if the object should not
113      *         be reused.
114      */
115     boolean sanitize(T obj);
116   }
117 
118   /**
119    * A lease for an object (obtained via {@link #get()}); working with the object is only permitted
120    * before {@link #close()}.
121    *
122    * @param <O> The object type.
123    */
124   interface Lease<O> extends Closeable {
125     /**
126      * Returns the leased object, potentially {@code null} when discarded/closed.
127      *
128      * @return The object, or {@code null}.
129      */
130     O get();
131 
132     /**
133      * Terminates the validity of this lease. Unless discarded via {@link #discard()}, the object
134      * may end up back in the object pool it was leased from; however that is decided by the pool.
135      */
136     @Override
137     void close();
138 
139     /**
140      * Marks the leased object as discarded, potentially preventing it from being reused in the
141      * object pool.
142      */
143     void discard();
144   }
145 }