<div dir="auto">Hello Maurizio. Thanks for the quick response and explanation.<div dir="auto"><br></div><div dir="auto">So, in short the stable values are not mean for very dynamic scenarios because the API prioritize performance and efficiency at runtime and sacrifices flexibility in exchange; which translates as " the keys or at least the size of the stableValue must be know at compile time".</div><div dir="auto"><br></div><div dir="auto">It's a fair trade off, I am keeping it in mind for the next tests and experiments I do. </div><div dir="auto"><br></div><div dir="auto">Best regards.</div></div><br><div class="gmail_quote gmail_quote_container"><div dir="ltr" class="gmail_attr">El mar, 2 de sept de 2025, 6:14 p.m., Maurizio Cimadamore <<a href="mailto:maurizio.cimadamore@oracle.com">maurizio.cimadamore@oracle.com</a>> escribió:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><u></u>

  
  <div>
    <p>Hi David,<br>
      Thanks for your feedback.</p>
    <p>The factories that we provide, like StableValue::list and
      StableValue::map cover common cases where the list/map elements
      are known upfront, but should be computed lazily.</p>
    <p>In other words you might think of these factories as lazy
      variants of List::of and Map::of. Both kinds of factories return
      an unmodifiable collection -- that is a collection whose size is
      fixed, and that rejects update operations.</p>
    <p>I understand that you would like to create a "stable" map, whose
      key/values are not known upfront -- more specifically, where the
      keys are only known dynamically.</p>
    <p>I believe in these cases the "win" for using a stable map in the
      first place is much less obvious. If the map can grow dynamically
      (e.g. because you don't know how many entries you might be adding
      to it) you are probably looking at an implementation that has some
      way to "resize" itself -- which makes using something like a
      stable construct much harder. For instance, adding new entries on
      a map might cause the underlying array of buckets to be
      reallocated, and existing entries to be rehashed in the new
      (larger) bucket array. This means that the bucket array itself
      will need to be updated several times during the lifecycle of the
      map, making it not stable (remember: stable means "updated at most
      once").</p>
    <p>If some constraints are relaxed, e.g. maybe you know how many
      entries you are going to add in your map -- that might make the
      problem easier, as now we're back in a situation where we now the
      size of the underlying storage. For instance one can have a
      specialized hash table implementation backed by a linear array (of
      an appropriate size), and then use linear probing to store entries
      in the linear array. Since the size is bounded, the size of the
      entries linear array is also bounded, and we can then make that
      linear array stable (e.g. use a stable list). </p>
    <p>Since such a "fixed size" hash map would be quite specialized, we
      did not see yet enough motivation for adding it to the JDK --
      especially given that developers should be able to define such
      constructs on top of the StableValue API (in fact _all_ the
      existing provided factories are defined in terms of the Stable
      Value API).</p>
    <p>But it's not just about whether the size is known or not -- in
      order for the JVM to be able to apply any sort of constant-folding
      optimization to the map access, you need the key to be a constant
      (e.g. either some compile-time constant, or the value of a static
      final field, or the contents of some other stable value). Only
      then we can fold the entire map access expression (if we're
      lucky). But in the example you provide, the key provided to
      Map::get is just a random class name you get from the current
      stack. So there's very little for the JIT to optimize here. If the
      input (the key) is not known, then the access expression
      (Map::get) cannot be optimized.<br>
    </p>
    <p>In other words, the case of a fully dynamic list/map that you
      propose just doesn't seem a great fit for stability, in the sense
      that you likely won't get any performance improvement (over a
      concurrent hash map) by using some sort of stable map there.</p>
    <p>Maurizio<br>
    </p>
    <p><br>
    </p>
    <div>On 02/09/2025 02:45, david Grajales
      wrote:<br>
    </div>
    <blockquote type="cite">
      
      <div dir="ltr"><br>
        <br>
        <div class="gmail_quote">
          <div dir="ltr" class="gmail_attr">---------- Forwarded message
            ---------<br>
            De: <strong class="gmail_sendername" dir="auto">david
              Grajales</strong> <span dir="auto"><<a href="mailto:david.1993grajales@gmail.com" target="_blank" rel="noreferrer">david.1993grajales@gmail.com</a>></span><br>
            Date: lun, 1 sept 2025 a la(s) 8:43 p.m.<br>
            Subject: Feedback about StableValues(Preview)<br>
            To: <<a href="mailto:core-libs-dev@openjdk.org" target="_blank" rel="noreferrer">core-libs-dev@openjdk.org</a>><br>
          </div>
          <br>
          <br>
          <div dir="ltr">
            <p>Subject: Feedback and Questions on JEP 8359894 - Stable
              Values API</p>
            <p>Dear Java core-libs development team,</p>
            <p>Please accept my sincere gratitude and compliments for
              your ongoing dedication to improving the Java platform.
              The continuous innovation and thoughtful evolution of Java
              is truly appreciated by the developer community.</p>
            <p>I have been experimenting with the Stable Values API (JEP
              8359894) in a development branch of a service at my
              company, and I would like to share some observations and
              seek your guidance on a particular use case.</p>
            <p><br>
            </p>
            <h2>Current Implementation</h2>
            <p>
            </p>
            <p>Currently, I have a logging utility that follows a
              standard pattern for lazy value computation:</p>
            <div><br>
            </div>
            <div>class DbLogUtility {<br>
                  private static final ConcurrentMap<String,
              Logger> loggerCache = new ConcurrentHashMap<>();<br>
                  <br>
                  private DbLogUtility(){}<br>
              <br>
                  private static Logger getLogger() {<br>
                      var className =
              Thread.currentThread().getStackTrace()[3].getClassName();<br>
                      return loggerCache.computeIfAbsent(className,
              LoggerFactory::getLogger);<br>
                  }<br>
                  public static void logError(){<br>
                      //.... implementation detail<br>
                  }</div>
            <div>}</div>
            <div><br>
            </div>
            <div>
              <h2>Challenge with Stable Values API</h2>
              <p>When attempting to migrate this code to use the Stable
                Values API, I encountered a fundamental limitation: the
                API requires keys to be known at compile time. The
                current factory methods (<code>StableValue.function(Set<K>,
                  Function)</code> and <code>StableValue.intFunction(int,
                  IntFunction)</code>) expect predefined key sets or
                bounded integer ranges.</p>
              <p>This design constraint makes it challenging to handle
                dynamic key discovery scenarios, which are quite common
                in enterprise applications for:</p>
              <ul>
                <li>Logger caching by dynamically discovered class names</li>
                <li>Configuration caching by runtime-determined keys</li>
                <li>Resource pooling with dynamic identifiers</li>
                <li>Etc.</li>
              </ul>
            </div>
            <div><br>
            </div>
            <div>
              <h2>Questions and Feedback</h2>
              <ol>
                <li><strong>Am I missing an intended usage pattern?</strong>
                  Is there a recommended approach within the current API
                  design for handling dynamic key discovery while
                  maintaining the performance benefits of stable values?</li>
                <li> Would you consider any of these potential
                  enhancements:
                  <ul>
                    <li>Integration of stable value optimizations
                      directly into existing collection APIs (similar to
                      how some methods have been added to List and Map
                      interfaces for better discoverability)</li>
                    <li>A hybrid approach that provides stable value
                      benefits for dynamically discovered keys</li>
                  </ul>
                </li>
                <li>Do you envision the Stable Values API as primarily
                  serving compile-time-known scenarios, with dynamic use
                  cases continuing to rely on traditional concurrent
                  collections?</li>
              </ol>
              <div>
                <p>Thank you for your time and consideration. I would be
                  grateful for any guidance or clarification you might
                  provide on these questions. If there are planned
                  enhancements or alternative patterns I should
                  consider, I would very much appreciate your insights.</p>
                <p>Best regards, and always yours. </p>
                <p>David Grajales Cárdenas. </p>
              </div>
            </div>
            <div><br>
            </div>
          </div>
        </div>
      </div>
    </blockquote>
  </div>

</blockquote></div>