Uploaded image for project: 'AppFormer'
  1. AppFormer
  2. AF-1620

Create an efficient data structure and algorithm to consolidate all build information

XMLWordPrintable

    • Icon: Task Task
    • Resolution: Unresolved
    • Icon: Major Major
    • None
    • None
    • Build mechanism
    • None
    • 2018 Week 39-41, 2018 Week 42-44, 2018 Week 45-47, 2018 Week 48-50, 2019 Week 02-04, 2018 Week 51-01, 2019 Week 05-07, 2019 Week 08-10
    • 8
    • NEW
    • NEW

      In the codebase today we have a variety of different caches spread everywhere to store different data structures that at the end of the day, all are based on the results of a build (DMO, ClassLoader, etc).
      Maintain all those caches is complex and error-prone, likely that we're doing more builds than we'd need.

      So, in other words: the current build system has a very decentralized cache around it. This creates a lot of problems, so all this should be unified into a single build cache.

      However, the build system has quite a lot of potential data outcome that has their own lifecycle like the dependencies classloader or PackageDataModelOracle (see [1]). So.. in order to be efficient and provide a reliable solution we need, what we could call two-level cache.

      The first is the aggregator of the build system, that we could consider more or less this data type[2], but this is not the data structure that this JIRA specs.

      This JIRA specs the 2nd level of cache, the one that will hold individually multiple data, basically all items listed in [1].

      This data should be an efficient, thread-safe data structure+algo that lazily provides a memoizer that would check if an existing cache exists, returns it automatically otherwise it would compute the value and store it. This is more or less a pseudo-code that this type would look like:

      ComputedValue <T> {
       SpecialSuplier<T> suplier;
       ConcurrentMap<Class<?>, T> map = new ConcurrentHashMap<>(1);
       AtomicReference<T> localCache;
       
       ComputedValue(SpecialSuplier<T> suplier){
        this.suplier = suplier;
       }
      
       T get(){
          V result = localCache.get();
          if (result == null) {
              return this.map.computeIfAbsent(CacheContent.class, k -> this.suplier.apply(localCache));
          }
          return result; 
       }
      
       void invalidate(){
         map.clear();
       }
      
       void invalidateAll(){
         localCache.set(null);
         map.clear();
       }
      }
      
      SpecialSuplier<T> extends Function<T,T> {
       apply(AtomicReference<T> oldValue) {
         if (value != null){
             asyncUpdate(value);
             return value;
         }
         
         asyncUpdate(AtomicReference<T> oldValue) {
             Thread t1 = new Thread(() -> oldValue.set(this.get()));
             t1.start();
         }
       }
       abstract T get();
      }
      

      In the above code, we can consider the localCache data a value that, except in the first time, will always provide some data for the UI, what sometimes means that this data might not be the most up to date, but we won't block UI for the most updated one. The map is where new data is created in case of need, but it's also created in an efficient memoized way, so we just rebuild if the content has been cleaned (invalidate or invalidateAll) or never executed before (first time).

      The original code linked in [1] have the places where the ComputedValue data structure would be useful and needed.

      [1] - https://github.com/porcelli-forks/kie-wb-common/blob/maven-integration-latest/kie-wb-common-services/kie-wb-common-services-backend/src/main/java/org/kie/workbench/common/services/backend/builder/ModuleBuildDataImpl.java#L102-L124

      [2] - https://github.com/porcelli-forks/kie-wb-common/blob/maven-integration-latest/kie-wb-common-services/kie-wb-common-services-backend/src/main/java/org/kie/workbench/common/services/backend/builder/ModuleBuildDataImpl.java

              Unassigned Unassigned
              abakos@redhat.com Alexandre Porcelli
              Votes:
              0 Vote for this issue
              Watchers:
              1 Start watching this issue

                Created:
                Updated: