All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.simiacryptus.mindseye.lang.ObjectRegistry Maven / Gradle / Ivy

There is a newer version: 2.1.0
Show newest version
/*
 * Copyright (c) 2019 by Andrew Charneski.
 *
 * The author licenses this file to you under the
 * Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance
 * with the License.  You may obtain a copy
 * of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package com.simiacryptus.mindseye.lang;

import com.google.common.util.concurrent.ThreadFactoryBuilder;
import com.simiacryptus.ref.lang.RefAware;
import com.simiacryptus.ref.lang.RefUtil;
import com.simiacryptus.ref.lang.ReferenceCountingBase;
import com.simiacryptus.ref.wrappers.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.annotation.Nonnull;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public final class ObjectRegistry {
  private static final Logger logger = LoggerFactory.getLogger(ObjectRegistry.class);
  private static final RefMap, ObjectRecords> cache = new RefConcurrentHashMap<>();
  private static final ScheduledExecutorService maintenanceThread = Executors.newScheduledThreadPool(1,
      new ThreadFactoryBuilder().setDaemon(true).build());

  {
    maintenanceThread.scheduleAtFixedRate(() -> {
      RefCollection> values = cache.values();
      try {
        values.forEach(v -> {
          try {
            v.maintain();
          } finally {
            RefUtil.freeRef(v);
          }
        });
      } finally {
        values.freeRef();
      }
    }, 10000, 10000, TimeUnit.MILLISECONDS);
  }

  //  public RegisteredObjectBase() {
  //    register();
  //  }

  @Nonnull
  public static  RefStream getLivingInstances(@Nonnull final Class k) {
    return getInstances(k).filter(x -> {
      boolean temp_32_0001 = !x.isFreed();
      x.freeRef();
      return temp_32_0001;
    });
  }

  @Nonnull
  public static  RefStream getInstances(@Nonnull final Class k) {
    return stream(cache.entrySet()).filter(e -> {
      Class aClass = e.getKey();
      RefUtil.freeRef(e);
      return k.isAssignableFrom(aClass);
    }).flatMap(recordsEntry -> {
      ObjectRecords value = recordsEntry.getValue();
      RefUtil.freeRef(recordsEntry);
      RefStream> stream = value.stream();
      value.freeRef();
      return stream;
    }).map((RefWeakReference x) -> {
      return (T) x.get();
    }).filter(x -> {
      if (x != null) {
        x.freeRef();
        return true;
      } else {
        return false;
      }
    });
  }

  public static void register(ReferenceCountingBase registeredObjectBase) {
    ObjectRegistry.ObjectRecords objectRecords = cache.computeIfAbsent(registeredObjectBase.getClass(),
        k -> new ObjectRecords<>());
    objectRecords.add(RefWeakReference.wrap(registeredObjectBase));
    objectRecords.freeRef();
  }

  private static  RefStream stream(RefSet entries) {
    RefStream refStream = entries.stream();
    entries.freeRef();
    return refStream;
  }

  private static class ObjectRecords
      extends RefConcurrentLinkedDeque> {
    private volatile boolean dirty = false;

    @Override
    public boolean add(final @RefAware RefWeakReference tWeakReference) {
      dirty = true;
      return super.add(tWeakReference);
    }

    @Override
    public RefStream> stream() {
      dirty = true;
      return super.stream();
    }

    public @SuppressWarnings("unused")
    void _free() {
      super._free();
    }

    @Nonnull
    public @Override
    @SuppressWarnings("unused")
    ObjectRecords addRef() {
      return (ObjectRecords) super.addRef();
    }

    private void maintain() {
      if (dirty) {
        this.removeIf(ref -> {
          T t = ref.get();
          RefUtil.freeRef(ref);
          boolean notNull = null != t;
          RefUtil.freeRef(t);
          return notNull;
        });
        dirty = false;
      }
    }
  }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy