Nilling for GC

P

Paganoni

Hi, I've read that
http://whytheluckystiff.net/articles/theFullyUpturnedBin.html.
I have a background script that runs continuously and threads some tasks
on demand. I keep track of the launched tasks but, by keeping those
tracks, I certainly prevent tasks classes instances and threads
instances to be discarded by the garbage collector.

Data are stored like that :

@workers[:eek:ne_category] = []
@workers[:eek:ne_category] << {:started_at => Time.now, :thread => th}

So, I'm trying to setup a cleaner that would nil old references but I'm
lost in maps :

@semaphore.synchronize do
@workers.map{|k,v| v.map{|worker| (Time.now - worker[:started_at] > 5
&& worker[:thread].status == false) ? (cleaned +=1; nil) : worker}}
end

When condition is true, cleaned is incremented but the nil does not
replace @workers entry.

So, I did another test :
hs = {}
hs[:toto] = []
hs[:toto] << {:kk => 28, :so => 'yes'}
hs[:toto] << {:kk => 30}
hs[:tata] = []
hs[:tata] << {:kk => 2}

hs = hs.map{|k,v| v.map {|a| a[:kk] > 28 ? nil : a} }
pp hs displays
[[{:kk=>28, :so=>"yes"}, nil], [{:kk=>2}]]

This one works right, for each hs entry, array is nilled if :kk value is

Obviously there is a mistake somewhere in the first code source but I
don't find it.

Any help appreciated, thank you
 
R

Rick DeNatale

[Note: parts of this message were removed to make it a legal post.]

Hi, I've read that
http://whytheluckystiff.net/articles/theFullyUpturnedBin.html.
I have a background script that runs continuously and threads some tasks
on demand. I keep track of the launched tasks but, by keeping those
tracks, I certainly prevent tasks classes instances and threads
instances to be discarded by the garbage collector.

Data are stored like that :

@workers[:eek:ne_category] = []
@workers[:eek:ne_category] << {:started_at => Time.now, :thread => th}

So, I'm trying to setup a cleaner that would nil old references but I'm
lost in maps :

@semaphore.synchronize do
@workers.map{|k,v| v.map{|worker| (Time.now - worker[:started_at] > 5
&& worker[:thread].status == false) ? (cleaned +=1; nil) : worker}}
end

When condition is true, cleaned is incremented but the nil does not
replace @workers entry.

So, I did another test :
hs = {}
hs[:toto] = []
hs[:toto] << {:kk => 28, :so => 'yes'}
hs[:toto] << {:kk => 30}
hs[:tata] = []
hs[:tata] << {:kk => 2}

hs = hs.map{|k,v| v.map {|a| a[:kk] > 28 ? nil : a} }
pp hs displays
[[{:kk=>28, :so=>"yes"}, nil], [{:kk=>2}]]

This one works right, for each hs entry, array is nilled if :kk value is

Obviously there is a mistake somewhere in the first code source but I don't
find it.

Any help appreciated, thank you

@workers.map{|k,v| v.map{|worker| (Time.now - worker[:started_at] > 5 #
...

vs.

hs = hs.map{|k,v| v.map {|a| a[:kk] > 28 ? nil : a} }

In the first case you create a new array from the nested map calls and then
THROW IT AWAY, @workers still refers to the old array.

In the second you compute a new array and assign it to hs.

--
Rick DeNatale

Blog: http://talklikeaduck.denhaven2.com/
Twitter: http://twitter.com/RickDeNatale
WWR: http://www.workingwithrails.com/person/9021-rick-denatale
LinkedIn: http://www.linkedin.com/in/rickdenatale
 
E

Eleanor McHugh

Hi, I've read that
http://whytheluckystiff.net/articles/theFullyUpturnedBin.html.
I have a background script that runs continuously and threads some
tasks
on demand. I keep track of the launched tasks but, by keeping those
tracks, I certainly prevent tasks classes instances and threads
instances to be discarded by the garbage collector.

Data are stored like that :

@workers[:eek:ne_category] = []
@workers[:eek:ne_category] << {:started_at => Time.now, :thread => th}

So, I'm trying to setup a cleaner that would nil old references but
I'm
lost in maps :

@semaphore.synchronize do
@workers.map{|k,v| v.map{|worker| (Time.now - worker[:started_at] > 5
&& worker[:thread].status == false) ? (cleaned +=1; nil) : worker}}
end

You could write something like:

def thread_dead? worker
(Time.now - worker[:started_at] > 5) && (worker[:thread].status ==
false)
end

@semaphore.synchronize do
hs.delete_if do |k, v|
v.map! { |worker| thread_dead?(worker) ? (cleaned += 1; nil) :
worker }.compact!
v.empty?
end
end


Ellie

Eleanor McHugh
Games With Brains
http://slides.games-with-brains.net
 
P

Paganoni

le 02/04/2009 09:57, Rick DeNatale nous a dit:
In the first case you create a new array from the nested map calls and then
THROW IT AWAY, @workers still refers to the old array.

In the second you compute a new array and assign it to hs.

But can I miss this sort of things for hours ???

Thanks !
 
P

Paganoni

le 02/04/2009 10:27, Eleanor McHugh nous a dit:
You could write something like:

def thread_dead? worker
(Time.now - worker[:started_at] > 5) && (worker[:thread].status ==
false)
end

@semaphore.synchronize do
hs.delete_if do |k, v|
v.map! { |worker| thread_dead?(worker) ? (cleaned += 1; nil) :
worker }.compact!
v.empty?
end
end

Your delete_if solution is quite elegant because self explanatory !

Thanks
 
E

Eleanor McHugh

le 02/04/2009 10:27, Eleanor McHugh nous a dit:
You could write something like:
def thread_dead? worker
(Time.now - worker[:started_at] > 5) && (worker[:thread].status
== false)
end
@semaphore.synchronize do
hs.delete_if do |k, v|
v.map! { |worker| thread_dead?(worker) ? (cleaned += 1; nil) :
worker }.compact!
v.empty?
end
end

Your delete_if solution is quite elegant because self explanatory !

Thank you :)

The delete_if could also be written as a one-liner, but it looks uglier:

hs.delete_if { |k, v| (v.map! { |worker| thread_dead?(worker) ?
(cleaned += 1; nil) : worker }.compact! || v).empty? }

It always bugs me that compact! returns nil if no changes occur,
rather than the enum as I seem to use this particular idiom a lot *sigh*


Ellie

Eleanor McHugh
Games With Brains
http://slides.games-with-brains.net
 
M

Michael Malone

It always bugs me that compact! returns nil if no changes occur,
rather than the enum as I seem to use this particular idiom a lot *sigh*


Ellie

Eleanor McHugh
Games With Brains
http://slides.games-with-brains.net
Yes, I find it equally annoying that strip! has the same bahviour

=======================================================================
This email, including any attachments, is only for the intended
addressee. It is subject to copyright, is confidential and may be
the subject of legal or other privilege, none of which is waived or
lost by reason of this transmission.
If the receiver is not the intended addressee, please accept our
apologies, notify us by return, delete all copies and perform no
other act on the email.
Unfortunately, we cannot warrant that the email has not been
altered or corrupted during transmission.
=======================================================================
 
M

Martin DeMello

It always bugs me that compact! returns nil if no changes occur, rather than
the enum as I seem to use this particular idiom a lot *sigh*

yeah, it seems like a very c-like thing to do :( i'd rather have it
set a (pseudo-)global variable the way regexp matches do.

martin
 
D

David Masover

hs.delete_if { |k, v| (v.map! { |worker| thread_dead?(worker) ?
(cleaned += 1; nil) : worker }.compact! || v).empty? }

It always bugs me that compact! returns nil if no changes occur,
rather than the enum as I seem to use this particular idiom a lot *sigh*

It could also be written like this, if I understand it:

hs.delete_if { |k, v| (v.map! { |worker| thread_dead?(worker) ? (cleaned += 1;
nil) : worker }.tap(&:compact!).empty? }

I don't feel strongly about compact! -- after all, it may be useful to know
whether it found anything. But this is exactly what tap is for, right?

For those on 1.8.6:

class Object
def tap
yield self
self
end
end
 
E

Eleanor McHugh

It could also be written like this, if I understand it:

hs.delete_if { |k, v| (v.map! { |worker| thread_dead?(worker) ?
(cleaned += 1;
nil) : worker }.tap(&:compact!).empty? }

I don't feel strongly about compact! -- after all, it may be useful
to know
whether it found anything. But this is exactly what tap is for, right?

I've only just started moving over to 1.9 so I've not used tap(), I'll
bear it in mind for the future. To be honest though I can't recall a
single occasion where I've used compact!() that I didn't find the nil
result inconvenient and have even been known to redefine it to work
the way I prefer when it's been frequently used in a program :)


Ellie

Eleanor McHugh
Games With Brains
http://slides.games-with-brains.net
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,774
Messages
2,569,599
Members
45,169
Latest member
ArturoOlne
Top