swarm-support
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Swarm-Support] How to prevent sending a message to a droppedobject?


From: martijn cox
Subject: Re: [Swarm-Support] How to prevent sending a message to a droppedobject?
Date: Tue, 9 Aug 2005 16:39:28 +0200

Well, since this whole discussion is about the procedure to remove agents in
the reaper queue, I'm fairly sure I'll never encounter a deleted agent in
the list. I've taken both your advices to heart though.
Now onto the next problem, which is still on-topic:

I don't know how or why, but once I remove the action from the Schedule like
Paul told me, everything seems to work out fine, untill some other action is
scheduled over the timeslot where the action I deleted resided. Then I
receive an RaiseEvent, telling me:

*** event raised for error: InvalidOperation
*** function: _update_mergeSchedules(), file:
/tmp/swarm-2.1.154/src/activity/Schedule.m, line: 298
> MergeSchedule is invalid. There is no
> mergeAction for schedule where action
> should be inserted!
*** execution terminating due to error
/tmp/swarm-2.1.154/src/defobj/Symbol.m:187 -[Error(c) _raiseEvent:]
Aborted (core dumped)

This is how I remove the action (in -wipe):
[lifeMutationSchedule remove: [agent getBirthAction]];

Any guesses on what I've done wrong?

----- Original Message ----- 
From: "Ken Cline" <address@hidden>
To: "Swarm Support" <address@hidden>
Sent: Thursday, August 04, 2005 9:05 PM
Subject: Re: [Swarm-Support] How to prevent sending a message to a
droppedobject?


> I definitely second what Paul has said.  It is problematic to iterate
> thru a list with an index and then remove directly from the underlying
> list.  It may work for you because you are going tip-to-tail, but it's
> not recommended.[1]
>
> Btw, if there is a chance that there's a nil member in the list, then
> you should test for that in the 'if' statement that gets the birth
> action, e.g. if ( agent && [agent getBirthAction] ) { ... }
>
> Also, if 'getBirthAction' has any computational cost, eg it searches
> a list of actions, _and_ if you are trying to squeeze out extra
> performance, then you may wish to store the action in a local variable
> instead of calling the getter twice.
>
> Finally, another design option would be to have each agent's drop
> method handle removing its birth actions.  The advantage is that
> then you don't need the loop, simply call [agentList deleteAll].
> Note, there's still a loop involved, it's just internal to the
> deleteAll method.  A disadvantage to this design is that agents
> now need pointers to either the model swarm or the schedule object.
> This may be stylistically undesirable as well as increasing the memory
> footprint of every agent slightly.  If you do override 'drop', you
> MUST be sure to call the parent class's implementation at the end of
> your implementation, otherwise the memory will never be reclaimed.
>
> Ken
> __________
> [1] You are also taking a performance hit, as Paul said, because the
>     [List remove: aMember] (inherited from Collection, I think)
>     operation likely has to search the list for the member you've
>     asked to be removed.  So (a) the list has create an internal index
>     to go find this member and (b) if your list has duplicates, it
>     might find the wrong copy of your member.  On the other hand,
>     the [Index remove] operation involves almost no work; it just has
>     to reassign a few pointers and poof, member removed.
>
>     Note, it is probably possible to create a List data structure
>     that protected its Index objects from concurrent modification,
>     ie modification via other indexes or directly to the list.  But
>     there would be a significant computational cost to pay and every-
>     one would have pay it.
>
> --- Paul Johnson <address@hidden> wrote:
>
> > martijn cox wrote:
> > > Well, that would indeed work, but the thing is: I don't have the
pointer to
> > > the object available. All I can do is loop over a List of agents like
so:
> > >
> > >  while( (agent = [index next]) != nil )
> > >     {
> > >       if ([agent getBirthAction])
> > >        [lifeMutationSchedule remove: [agent getBirthAction]];
> > >       [_agentList remove: agent];
> > >       [agent drop];
> > >       agent = nil; // ***
> > >     }
> > >
> >
> > remove returns a pointer to the removed object. But I don't think you
> > should remove items this way.
> >
> > FIrst, don't use the while construct, use for.  If your while finds a
> > nil in your list, the iterating will stop prematurely. Second, you are
> > wrecking  the index by removing a member while iterating.  That's bad.
> >
> > I can give you a much better algorithm for doiing this that fixes all of
> > these problems.  Then it will be much cleaner & faster to remove with
> > the index.
> >
> > id agent, index;
> >
> > index = [agentList begin: [self getZone]];
> >
> > for(agent = [index next]; [index getLoc]==Member; agent = [index next])
> > {
> >
> >     if ([agent getBirthAction])
> >          {
> >             id theAgent;
> >             [lifeMutationSchedule remove: [agent getBirthAction]];
> >    theAgent = [index remove];
> >             [theAgent drop];
> >    theAgent = nil;
> >           }
> > }
> >
> > Actions on indexes to remove items are
> > 1. safe to the index and
> > 2. Much Much faster than searching through a collection to find
> > something and remove it.
> >
> >
> >
> > -- 
> > Paul E. Johnson                       email: address@hidden
> > Dept. of Political Science            http://lark.cc.ku.edu/~pauljohn
> > 1541 Lilac Lane, Rm 504
> > University of Kansas                  Office: (785) 864-9086
> > Lawrence, Kansas 66044-3177           FAX: (785) 864-5700
> > _______________________________________________
> > Support mailing list
> > address@hidden
> > http://www.swarm.org/mailman/listinfo/support
> >
>
>
>
>
> _________________________________________________________
>  Ken Cline                             W: (443) 287-2636
>  address@hidden
>
>


reply via email to

[Prev in Thread] Current Thread [Next in Thread]