From a17f5203eeedc44c0917b7dcddf26413d0855b89 Mon Sep 17 00:00:00 2001 From: Nicolas Gaud Date: Wed, 25 Mar 2020 10:00:47 +0100 Subject: [PATCH] Cleaning management of weak and strong repository as well as Space with participants --- .../src/io/sarl/lang/core/Space.java | 18 ++++ .../src/main/sarl/io/sarl/sre/Kernel.sarl | 6 +- .../sre/services/lifecycle/AgentLife.sarl | 1 + .../namespace/AbstractNamespaceFinder.sarl | 24 +++--- .../sarl/sre/spaces/AbstractEventSpace.sarl | 85 +++++++++++-------- .../io/sarl/sre/spaces/LocalEventSpaces.sarl | 22 +---- .../sre/spaces/SpaceWithParticipants.sarl | 47 +++++----- 7 files changed, 103 insertions(+), 100 deletions(-) diff --git a/main/coreplugins/io.sarl.lang.core/src/io/sarl/lang/core/Space.java b/main/coreplugins/io.sarl.lang.core/src/io/sarl/lang/core/Space.java index 0d03df8378..6b385cd12c 100644 --- a/main/coreplugins/io.sarl.lang.core/src/io/sarl/lang/core/Space.java +++ b/main/coreplugins/io.sarl.lang.core/src/io/sarl/lang/core/Space.java @@ -93,6 +93,16 @@ default boolean isPseudoEmpty() { @Pure int getNumberOfStrongParticipants(); + /** + * Replies the number of strong participants to the space. + * This function ignores the weak participants. + * + * @return the number of participants. + * @since 0.11 + */ + @Pure + int getNumberOfWeakParticipants(); + /** Apply the given procedure to each of the strong participants. * This function ignores the weak participants. * @@ -101,4 +111,12 @@ default boolean isPseudoEmpty() { */ void forEachStrongParticipant(Procedure1 callback); + /** Apply the given procedure to each of the weak participants. + * This function ignores the strong participants. + * + * @param callback the lambda to invoke. + * @since 0.11 + */ + void forEachWeakParticipant(Procedure1 callback); + } diff --git a/sre/io.janusproject/io.janusproject.plugin/src/main/sarl/io/sarl/sre/Kernel.sarl b/sre/io.janusproject/io.janusproject.plugin/src/main/sarl/io/sarl/sre/Kernel.sarl index 47f19f0237..eb004de12b 100644 --- a/sre/io.janusproject/io.janusproject.plugin/src/main/sarl/io/sarl/sre/Kernel.sarl +++ b/sre/io.janusproject/io.janusproject.plugin/src/main/sarl/io/sarl/sre/Kernel.sarl @@ -234,8 +234,8 @@ class Kernel { val context = iter.next val ^space = context.defaultSpace as SpaceWithParticipants - for (participant : ^space.internalStrongParticipantStructure.values) { - val listener = participant.participant + ^space.forEachStrongParticipant [ id, p | + val listener = p.participant if (listener instanceof InformedEventListener) { val ag = listener.ownerInstance assert ag !== null @@ -243,7 +243,7 @@ class Kernel { agents += ag } } - } + ] } diff --git a/sre/io.janusproject/io.janusproject.plugin/src/main/sarl/io/sarl/sre/services/lifecycle/AgentLife.sarl b/sre/io.janusproject/io.janusproject.plugin/src/main/sarl/io/sarl/sre/services/lifecycle/AgentLife.sarl index 695e4328ad..40bbbc4cf5 100644 --- a/sre/io.janusproject/io.janusproject.plugin/src/main/sarl/io/sarl/sre/services/lifecycle/AgentLife.sarl +++ b/sre/io.janusproject/io.janusproject.plugin/src/main/sarl/io/sarl/sre/services/lifecycle/AgentLife.sarl @@ -229,6 +229,7 @@ final class AgentLife { protected def attachAgentToPlatform(spawningContext : Context) : InternalEventBusCapacity { // Set up the internal bus val eb = getEventBus + assert(eb !== null) // // Register the agent on its parent default space. var defaultSpace = spawningContext.defaultSpace diff --git a/sre/io.janusproject/io.janusproject.plugin/src/main/sarl/io/sarl/sre/services/namespace/AbstractNamespaceFinder.sarl b/sre/io.janusproject/io.janusproject.plugin/src/main/sarl/io/sarl/sre/services/namespace/AbstractNamespaceFinder.sarl index cab8e3de5a..2e7883f11d 100644 --- a/sre/io.janusproject/io.janusproject.plugin/src/main/sarl/io/sarl/sre/services/namespace/AbstractNamespaceFinder.sarl +++ b/sre/io.janusproject/io.janusproject.plugin/src/main/sarl/io/sarl/sre/services/namespace/AbstractNamespaceFinder.sarl @@ -1,17 +1,17 @@ -/* +/* * $Id$ - * + * * SARL is an general-purpose agent programming language. * More details on http://www.sarl.io - * + * * Copyright (C) 2014-2020 the original authors or authors. - * + * * Licensed 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 - * + * + * 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. @@ -83,13 +83,9 @@ abstract class AbstractNamespaceFinder implements INamesp } } if (^space instanceof SpaceWithParticipants) { - var participantMap = ^space.internalStrongParticipantStructure - var participant = participantMap.get(agentId) - if (participant !== null) { - var listener = participant.participant - if (listener instanceof InformedEventListener) { - return listener.ownerInstance - } + var listener = ^space.getListenerFromStrongParticipant(agentId) + if ((listener !== null) && (listener instanceof InformedEventListener)) { + return (listener as InformedEventListener).ownerInstance } } } diff --git a/sre/io.janusproject/io.janusproject.plugin/src/main/sarl/io/sarl/sre/spaces/AbstractEventSpace.sarl b/sre/io.janusproject/io.janusproject.plugin/src/main/sarl/io/sarl/sre/spaces/AbstractEventSpace.sarl index 74277fe707..e758ec4b09 100644 --- a/sre/io.janusproject/io.janusproject.plugin/src/main/sarl/io/sarl/sre/spaces/AbstractEventSpace.sarl +++ b/sre/io.janusproject/io.janusproject.plugin/src/main/sarl/io/sarl/sre/spaces/AbstractEventSpace.sarl @@ -30,6 +30,7 @@ import io.sarl.lang.core.SpaceID import io.sarl.sre.services.logging.LoggingService import java.text.MessageFormat import java.util.UUID +import java.util.concurrent.ConcurrentHashMap import java.util.concurrent.ConcurrentLinkedDeque import java.util.logging.Level import javax.inject.Inject @@ -67,6 +68,10 @@ abstract class AbstractEventSpace extends AbstractSpace implements EventSpace, S @Accessors(PUBLIC_GETTER) var spaceParticipantListener : SpaceParticipantListener + val strongRepository = new ConcurrentHashMap + + val weakRepository = new ConcurrentHashMap + /** Constructor. * * @param id identifier of the space. @@ -103,11 +108,12 @@ abstract class AbstractEventSpace extends AbstractSpace implements EventSpace, S var id = entity.ID var address = new Address(this.spaceID, id) var participant = Participant::createAndInit(address, entity) - + assert(id !== null) + assert(participant !== null) if (weakParticipant) { - ensureInternalWeakParticipantStructure.put(id, participant) + this.weakRepository.putIfAbsent(id, participant) } else { - internalStrongParticipantStructure.put(id, participant) + this.strongRepository.putIfAbsent(id, participant) } getSpaceParticipantListener?.participantJoined(participant) @@ -119,15 +125,13 @@ abstract class AbstractEventSpace extends AbstractSpace implements EventSpace, S var participant : Participant = null var becomesEmpty : boolean - var structure = this.internalStrongParticipantStructure + var structure = this.strongRepository participant = structure.remove(entity.ID) becomesEmpty = structure.empty if (participant === null) { // Try a weak listener - structure = this.internalWeakParticipantStructure - if (structure !== null) { - participant = structure.remove(entity.ID) - } + structure = this.weakRepository + participant = structure.remove(entity.ID) } if (participant !== null) { @@ -144,12 +148,12 @@ abstract class AbstractEventSpace extends AbstractSpace implements EventSpace, S assert id !== null var participant : Participant = null - participant = this.internalStrongParticipantStructure.get(id) + participant = this.strongRepository.get(id) if (participant !== null) { return participant.address } - participant = this.internalWeakParticipantStructure?.get(id) + participant = this.weakRepository?.get(id) if (participant !== null) { return participant.address } @@ -196,29 +200,15 @@ abstract class AbstractEventSpace extends AbstractSpace implements EventSpace, S protected def getScopedParticipants(scope : Scope) : ConcurrentLinkedDeque { val scopedParticipants = new ConcurrentLinkedDeque if (scope === null) { - for (p : internalStrongParticipantStructure.values) { - scopedParticipants += p - } - val struct = internalWeakParticipantStructure - if (struct !== null) { - for (p : struct.values) { - scopedParticipants += p - } - } + strongRepository.forEach[id, participant|scopedParticipants += participant] + weakRepository.forEach[id, participant|scopedParticipants += participant] } else { - for (p : internalStrongParticipantStructure.values) { - if (scope.matches(p.address)) { - scopedParticipants += p - } - } - val struct = internalWeakParticipantStructure - if (struct !== null) { - for (p : struct.values) { - if (scope.matches(p.address)) { - scopedParticipants += p - } - } - } + strongRepository.filter[id, p|scope.matches(p.address)].forEach [ id, participant | + scopedParticipants += participant + ] + weakRepository.filter[id, p|scope.matches(p.address)].forEach [ id, participant | + scopedParticipants += participant + ] } return scopedParticipants } @@ -249,12 +239,18 @@ abstract class AbstractEventSpace extends AbstractSpace implements EventSpace, S @Pure override getNumberOfStrongParticipants : int { - internalStrongParticipantStructure.size + strongRepository.size } + @Pure + def getNumberOfWeakParticipants : int { + weakRepository.size + } + + @Pure override isPseudoEmpty(id : UUID) : boolean { - val struct = internalStrongParticipantStructure + val struct = strongRepository val sz = struct.size if (sz <= 0) { return true @@ -266,9 +262,24 @@ abstract class AbstractEventSpace extends AbstractSpace implements EventSpace, S } override forEachStrongParticipant(callback : (UUID)=>void) { - for (participant : internalStrongParticipantStructure.values) { - callback.apply(participant.address.UUID) - } + strongRepository.forEach[id, participant|callback.apply(id)] // see if participant.address.UUID is better } + override forEachWeakParticipant(callback : (UUID)=>void) { + weakRepository.forEach[id, participant|callback.apply(id)] // see if participant.address.UUID is better + } + + override forEachStrongParticipant(callback : (UUID, Participant)=>void) { + strongRepository.forEach[id, participant|callback.apply(id, participant)] + } + + override forEachWeakParticipant(callback : (UUID, Participant)=>void) { + weakRepository.forEach[id, participant|callback.apply(id, participant)] + } + + override getListenerFromStrongParticipant(target : UUID) : EventListener { + var participant = this.strongRepository?.get(target) + return participant.participant + } + } diff --git a/sre/io.janusproject/io.janusproject.plugin/src/main/sarl/io/sarl/sre/spaces/LocalEventSpaces.sarl b/sre/io.janusproject/io.janusproject.plugin/src/main/sarl/io/sarl/sre/spaces/LocalEventSpaces.sarl index 074e551cc0..1848d72fec 100644 --- a/sre/io.janusproject/io.janusproject.plugin/src/main/sarl/io/sarl/sre/spaces/LocalEventSpaces.sarl +++ b/sre/io.janusproject/io.janusproject.plugin/src/main/sarl/io/sarl/sre/spaces/LocalEventSpaces.sarl @@ -47,26 +47,15 @@ import java.util.concurrent.ConcurrentHashMap */ class OpenLocalEventSpace extends AbstractEventSpace implements OpenEventSpace { - val strongRepository = new ConcurrentHashMap - volatile var weakRepository : ConcurrentHashMap - override getInternalStrongParticipantStructure : ConcurrentHashMap { + /*override getInternalStrongParticipantStructure : ConcurrentHashMap { this.strongRepository } override getInternalWeakParticipantStructure : ConcurrentHashMap { this.weakRepository - } - - override ensureInternalWeakParticipantStructure : ConcurrentHashMap { - var r = this.weakRepository - if (r === null) { - this.weakRepository = new ConcurrentHashMap - r = this.weakRepository - } - return this.weakRepository - } + }*/ def register(entity : EventListener, weakParticipant : boolean) : Address { entity.registerToSpace(weakParticipant) @@ -117,17 +106,14 @@ class RestrictedAccessLocalEventSpace extends AbstractEventSpace implements Rest this.accessPermission = accessPermission } - override getInternalStrongParticipantStructure : ConcurrentHashMap { + /*override getInternalStrongParticipantStructure : ConcurrentHashMap { this.repository } override getInternalWeakParticipantStructure : ConcurrentHashMap { null - } + }*/ - override ensureInternalWeakParticipantStructure : ConcurrentHashMap { - null - } /** * Replies the Access Control List. diff --git a/sre/io.janusproject/io.janusproject.plugin/src/main/sarl/io/sarl/sre/spaces/SpaceWithParticipants.sarl b/sre/io.janusproject/io.janusproject.plugin/src/main/sarl/io/sarl/sre/spaces/SpaceWithParticipants.sarl index c2fe191a0f..47ca0bb94e 100644 --- a/sre/io.janusproject/io.janusproject.plugin/src/main/sarl/io/sarl/sre/spaces/SpaceWithParticipants.sarl +++ b/sre/io.janusproject/io.janusproject.plugin/src/main/sarl/io/sarl/sre/spaces/SpaceWithParticipants.sarl @@ -1,30 +1,29 @@ -/* +/* * $Id$ - * + * * SARL is an general-purpose agent programming language. * More details on http://www.sarl.io - * + * * Copyright (C) 2014-2020 the original authors or authors. - * + * * Licensed 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 - * + * + * 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 io.sarl.sre.spaces import io.sarl.lang.annotation.PrivateAPI +import io.sarl.lang.core.EventListener import io.sarl.lang.core.Space import java.util.UUID -import java.util.concurrent.ConcurrentHashMap /** * Space with participants that exhibits the participants' list. @@ -39,29 +38,21 @@ import java.util.concurrent.ConcurrentHashMap @PrivateAPI interface SpaceWithParticipants extends Space { - /** Replies the internal data structure for storing the strong space's participants. - * A Weak participant will not prevent the space from begin destroyed if it is the only one staying in it, a Strong participant will prevent the space destruction. - * A space containing only Weak participants will be destroyed by the SRE Kernel - * @return the entire strong participant structure, never {@code null} + /** Apply the given procedure to each of the strong participants. + * This function ignores the weak participants. + * + * @param callback the lambda to invoke. * @since 0.11 */ - def getInternalStrongParticipantStructure : ConcurrentHashMap + def forEachStrongParticipant(callback : (UUID, Participant) => void); - /** Replies the internal data structure for storing the weak space's participants. - * A Weak participant will not prevent the space from begin destroyed if it is the only one staying in it, a Strong participant will prevent the space destruction. - * A space containing only Weak participants will be destroyed by the SRE Kernel - * @return the entire weak participant structure, or {@code null} if none. + /** Apply the given procedure to each of the weak participants. + * This function ignores the strong participants. + * + * @param callback the lambda to invoke. * @since 0.11 */ - def getInternalWeakParticipantStructure : ConcurrentHashMap - - /** Replies the internal data structure for storing the weak space's participants. - * A Weak participant will not prevent the space from begin destroyed if it is the only one staying in it, a Strong participant will prevent the space destruction. - * A space containing only Weak participants will be destroyed by the SRE Kernel - * @return the entire weak participant structure, never {@code null}. - * @since 0.11 - */ - def ensureInternalWeakParticipantStructure : ConcurrentHashMap + def forEachWeakParticipant(callback : (UUID, Participant)=>void); + def getListenerFromStrongParticipant(target : UUID):EventListener; } -