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

jolie.lang.parse.module.ModuleRecordCache Maven / Gradle / Ivy

/*
 * Copyright (C) 2022  Narongrit Unwerawattana 
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 * MA 02110-1301  USA
 */
package jolie.lang.parse.module;

import java.net.URI;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

public class ModuleRecordCache {

	/**
	 * Module record Cache
	 */
	private final Map< URI, ModuleRecord > cache = new ConcurrentHashMap<>();

	/*
	 * Dependencies loaded from parsing Module 
	 */
	private final Map< URI, Set< URI > > dependenciesLoadedFrom = new ConcurrentHashMap<>();

	/*
	 * Dependencies needed by the module 
	 */
	private final Map< URI, Set< URI > > dependenciesNeededBy = new ConcurrentHashMap<>();

	/**
	 * Register dependency graph of the module's URI and its dependencies
	 * 
	 * @param moduleURI target module
	 * @param dependencies list of dependencies needed by moduleURI
	 */
	private void putDependencies( URI moduleURI, List< URI > dependencies ) {
		dependenciesLoadedFrom.putIfAbsent( moduleURI, new HashSet<>() );
		dependenciesLoadedFrom.get( moduleURI ).addAll( dependencies );
		dependencies.forEach( d -> {
			dependenciesNeededBy.putIfAbsent( d, new HashSet<>() );
			dependenciesNeededBy.get( d ).add( moduleURI );
		} );
	}

	protected void put( ModuleRecord mc, List< URI > dependencies ) {
		cache.put( mc.uri(), mc );
		this.putDependencies( mc.uri(), dependencies );
	}

	protected boolean contains( URI source ) {
		return cache.containsKey( source );
	}

	protected ModuleRecord get( URI source ) {
		return cache.get( source );
	}

	/**
	 * Handle dependency graph when removing a cache entry
	 * 
	 * @param source target module to remove cache
	 */
	private void removeDependencies( URI source ) {
		Optional< Set< URI > > dependenciesSet = Optional.ofNullable( dependenciesLoadedFrom.remove( source ) );
		dependenciesSet.ifPresent( dependency -> {
			dependency.forEach( d -> {
				Optional< Set< URI > > neededBySet = Optional.ofNullable( dependenciesNeededBy.get( d ) );
				neededBySet.ifPresent( s -> s.remove( source ) );
				if( neededBySet.isEmpty() ) {
					this.remove( d );
				}
			} );
		} );
	}

	protected void remove( URI source ) {
		if( source != null ) {
			try {
				if( cache.remove( source ) != null ) {
					this.removeDependencies( source );
				}
			} catch( ClassCastException e ) {
			}
		}
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy