<commit_before>package io.github.andrebeat.pool

import java.util.concurrent.atomic.AtomicBoolean
import scala.concurrent.duration.Duration

/**
  * A lease on an object requested from a [[io.github.andrebeat.pool.Pool]] allowing the object to
  * be accessed and then released back to the pool when no longer needed.
  *
  * @tparam A the type of object stored in this lease
  */
trait Lease[A <: AnyRef] {
  private[this] val dirty = new AtomicBoolean(false)
  protected[this] def a: A
  protected[this] def handleRelease(): Unit
  protected[this] def handleInvalidate(): Unit

  /**
    * Returns the object being leased by the pool. Throws an [[java.lang.IllegalStateException]]
    * if the lease has already been released or invalidated.
    * @return the object being leased by the pool.
    */
  def get(): A =
    if (!dirty.get()) a
    else throw new IllegalStateException("Tried to get an object from an already released or invalidated lease.")

  /**
    * Releases the object back to the pool for reuse. When releasing an object it is mandatory that
    * there are no references to the returned object.
    *
    * If the lease has already been released or invalidated this method does nothing.
    */
  def release(): Unit = if (dirty.compareAndSet(false, true)) handleRelease

  /**
    * Invalidates the current lease. The object is "destroyed" and is no longer eligible to be
    * returned to the pool. Additionally, the number of live objects in the pool is decremented.
    *
    * If the lease has already been released or invalidated this method does nothing.
    */
  def invalidate(): Unit = if (dirty.compareAndSet(false, true)) handleInvalidate

  /**
    * Gets the value from the lease, passing it onto the provided function and
    * releasing it back to the pool after the function is run.
    *
    * If needed, it is possible to invalidate the lease from inside the provided
    * function.
    *
    * @tparam B the type of object returned by the function `f`
    * @param f a function that uses the value stored in the lease to produce a new value
    * @return the value produced by the function `f`.
    */
  def use[B](f: A => B): B = try {
    f(get())
  } finally {
    release()
  }
}

/**
  * A pool of objects that may be leased. It is expected that all implementations of this trait are
  * thread-safe.
  *
  * @tparam A the type of object to pool
  */
trait Pool[A <: AnyRef] {
  /**
    * Factory method for creating new objects.
    * @return a new object.
    */
  protected def factory(): A
<commit_msg>extend "use" method scaladoc<commit_after>package io.github.andrebeat.pool

import java.util.concurrent.atomic.AtomicBoolean
import scala.concurrent.duration.Duration

/**
  * A lease on an object requested from a [[io.github.andrebeat.pool.Pool]] allowing the object to
  * be accessed and then released back to the pool when no longer needed.
  *
  * @tparam A the type of object stored in this lease
  */
trait Lease[A <: AnyRef] {
  private[this] val dirty = new AtomicBoolean(false)
  protected[this] def a: A
  protected[this] def handleRelease(): Unit
  protected[this] def handleInvalidate(): Unit

  /**
    * Returns the object being leased by the pool. Throws an [[java.lang.IllegalStateException]]
    * if the lease has already been released or invalidated.
    * @return the object being leased by the pool.
    */
  def get(): A =
    if (!dirty.get()) a
    else throw new IllegalStateException("Tried to get an object from an already released or invalidated lease.")

  /**
    * Releases the object back to the pool for reuse. When releasing an object it is mandatory that
    * there are no references to the returned object.
    *
    * If the lease has already been released or invalidated this method does nothing.
    */
  def release(): Unit = if (dirty.compareAndSet(false, true)) handleRelease

  /**
    * Invalidates the current lease. The object is "destroyed" and is no longer eligible to be
    * returned to the pool. Additionally, the number of live objects in the pool is decremented.
    *
    * If the lease has already been released or invalidated this method does nothing.
    */
  def invalidate(): Unit = if (dirty.compareAndSet(false, true)) handleInvalidate

  /**
    * Gets the value from the lease, passing it onto the provided function and
    * releasing it back to the pool after the function is run.
    *
    * If needed, it is possible to invalidate the lease from inside the provided
    * function.
    *
    * It is important that no references are kept to the leased object after
    * this method finishes. For example, the following code is invalid since the
    * variable `x` holds a reference to an object that was returned to the pool.
    *
    * {{{
    * val lease = pool.acquire()
    * val x = lease.use(identity)
    * }}}
    *
    * @tparam B the type of object returned by the function `f`
    * @param f a function that uses the value stored in the lease to produce a new value
    * @return the value produced by the function `f`.
    */
  def use[B](f: A => B): B = try {
    f(get())
  } finally {
    release()
  }
}

/**
  * A pool of objects that may be leased. It is expected that all implementations of this trait are
  * thread-safe.
  *
  * @tparam A the type of object to pool
  */
trait Pool[A <: AnyRef] {
  /**
    * Factory method for creating new objects.
    * @return a new object.
    */
  protected def factory(): A

{'fraction_non_alphanumeric': 0.08350119025819447, 'fraction_numerical': 0.0, 'mean_word_length': 3.0220913107511045, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3428906', 'n_tokens_mistral': 1522, 'n_tokens_neox': 1498, 'n_words': 714}