Removing key from map using reflection changes key? Is this a bug? - go

I am trying to remove the same key from two maps using reflection. However, removing it from the first map is causing a change to the key value. Is this WAI or a bug.
Code at (http://play.golang.org/p/MIkFP_Zrxb):
func main() {
m1 := map[string]bool{"a": true, "b": true}
m2 := map[string]bool{"a": true, "b": true}
fmt.Println(m1)
v1 := reflect.ValueOf(m1)
k := v1.MapKeys()[0]
fmt.Println("KEY BEFORE", k)
v1.SetMapIndex(k, reflect.Value{}) // COMMENT THIS OUT
fmt.Println("m1:", m1)
fmt.Println("KEY AFTER", k)
v2 := reflect.ValueOf(m2)
v2.SetMapIndex(k, reflect.Value{})
fmt.Println("KEY AFTER SECOND CALL", k)
fmt.Println("m2:", m2)
}
produces this output:
map[a:true b:true]
KEY BEFORE a
m1: map[b:true]
KEY AFTER
KEY AFTER SECOND CALL
m2: map[a:true b:true]
Notice that the "a" value is not removed from m2. Commenting out the indicated line causes the call to v2.SetMapIndex to work.
Also notice that the value of "k" changes after the call to SetMapIndex. That appears to be the reason that SetMapIndex isn't working. Can anyone offer an explanation? Is this a bug? Any suggested workaround?
Thanks.

I think it's a bug? The documentation for reflect.SetMapIndex states that "If val is the zero Value, SetMapIndex deletes the key from the map." So it seems that what's happening is the key is getting deleted by the map out from under the reflection type? It's worth noting that even after the deletion, k is still a string:
fmt.Println(k.Kind())
fmt.Println(k.Len())
Output:
string
0

I filed a bug: https://code.google.com/p/go/issues/detail?id=7896
It's fixed in the tip, but hasn't propagated out to the stable release.
The workaround for this is to structure the code so that the map which is the source of the key is the last map from which it's deleted. (I.e., reversing the calls to SetMapIndex() in the original post will behave as expected.

The call to SetMapIndex will touch the complete key/value pair during the remove operation.
From a conceptual point of view this makes sense to me. When deleting a key/value pair from a map there shouldn't be a guarantee that the key stays intact.
Not sure what you are trying to achieve but might use k2 := v2.MapKeys()[0] to delete from map v2. But as suggested don't use reflections for things like this. It is far better to use e.g. the built in delete function.
You also might want to look at the sources to understand the raw details:
http://golang.org/src/pkg/reflect/value.go
http://golang.org/src/pkg/runtime/hashmap.c
Some details on map internals

Related

Get index of an SKPoint in an SKPath

I'm not seeing an IndexOf or FindIndex method for SKPath.Points. I need to be able to get neighbouring points on both sides of a specified point. Path.Iterator only has .Next, so I am looking for using the index of the SKPoint instead.
With IndexOf or FindIndex seemingly missing, I am thinking of inheriting and maintaining a 2nd dataset in the background for getting the index.
Am I missing something obvious? How are others getting the index, so far?
This post helped. Calling IndexOf directly on Array works. Just need to make sure your SKPoint X and Y are unique from other SKPoints stored in the SKPath.Points. It is doing the check based on the SKPoint's position, so if you have multiple SKPoints at (0, 0), for example, it will return the first one at that position.
Luckily, I should never be in the situation for my use case.

GO language how to change value of object inside of pointer of map

How can I do it?
I have the list of objects, I want list all and change the name of object.
I have the list and I'm doing a while end send to another function, there I change the name, but the name doesn't save.
Any idea how can I do it?
https://play.golang.org/p/el3FtwC-3U
And if there is any book that I can read to learn more, please.
Thank for helping me =D
In the range loop:
for _, track := range tracks {
// send track to channel to change the name
Working(&track, &c)
}
the track variable is actually a copy of the value contained in the map, because the assignement here works on the Track value type, and in Go, values are copied when assigned.
What you should do instead is use the key of your map and assign the values from within the loop.
for key := range tracks {
t := tracks[key]
// send track to channel to change the name
Working(&t, &c)
tracks[key] = t
}
See https://play.golang.org/p/9naDP3SfNh
I didn't found how to get pointer to value in map so I think you have to use map[string]*Track instead and then work with pointers to Track structure in your Working function.
See https://play.golang.org/p/2XJTcKn1md
If you are trying modify tracks in parallel you are may be looking for something like this https://play.golang.org/p/1GhST34wId
Note missing buffer in chanel and go Working in for range tracks.

Accessing struct fields inside a map value (without copying)

Assuming the following
type User struct {
name string
}
users := make(map[int]User)
users[5] = User{"Steve"}
Why isn't it possible to access the struct instance now stored in the map?
users[5].name = "Mark"
Can anyone shed some light into how to access the map-stored struct, or the logic behind why it's not possible?
Notes
I know that you can achieve this by making a copy of the struct, changing the copy, and copying back into the map -- but that's a costly copy operation.
I also know this can be done by storing struct pointers in my map, but I don't want to do that either.
The fundamental problem is that you can't take the address of an item within a map. You might think the compiler would re-arrange users[5].name = "Mark" into this
(&users[5]).name = "Mark"
But that doesn't compile, giving this error
cannot take the address of users[5]
This gives the maps the freedom to re-order things at will to use memory efficiently.
The only way to change something explicitly in a map is to assign value to it, i.e.
t := users[5]
t.name = "Mark"
users[5] = t
So I think you either have to live with the copy above or live with storing pointers in your map. Storing pointers have the disadvantage of using more memory and more memory allocations, which may outweigh the copying way above - only you and your application can tell that.
A third alternative is to use a slice - your original syntax works perfectly if you change users := make(map[int]User) to users := make([]User, 10)
Maps are typically sparsely filled hash tables which are reallocated when they exceed the threshold. Re-allocation would create issues when someone is holding the pointers to the values
If you are keen on not creating the copy of the object, you can store the pointer to the object itself as the value
When we are referring the map, the value returned is returned "returned by value", if i may borrow the terminology used in function parameters, editing the returned structure does not have any impact on the contents of the map

Should I get a habit of removing unused variables in R?

Currently I'm working with relatively large data files, and my computer is not a super computer. I'm creating many subsets of these data sets temporarily and don't remove them from workspace. Obviously those are making a clutter of many variables. But, is there any effect of having many unused variables on performance of R? (i.e. does memory of computer fill at some point?)
When writing code should I start a habit of removing unused variables? Does it worth it?
x <- rnorm(1e8)
y <- mean(x)
# After this point I will not use x anymore, but I will use y
# Should I add following line to my code? or
# Maybe there will not be any performance lag if I skip the following line:
rm(x)
I don't want to add another line to my code. Instead of my code to seem cluttered I prefer my workspace to be cluttered (if there will be no performance improvement).
Yes, having unused objects will affect your performance, since R stores all its objects in memry. Obviously small objects will have negligible impact, and you mostly need to remove only the really big ones (data frames with millions of rows, etc) but having an uncluttered workspace won't hurt anything.
The only risk is removing something that you need later. Even when using a repo, as suggested, breaking stuff accidentally is something you want to avoid.
One way to get around these issues is to make extensive use of local. When you do a computation that scatters around lots of temporary objects, you can wrap it inside a local call, which will effectively dispose of those objects for you afterward. No more having to clean up lots of i, j, x, temp.var, and whatnot.
local({
x <- something
for(i in seq_along(obj))
temp <- some_unvectorised function(obj[[i]], x)
for(j in 1:temp)
temp2 <- some_other_unvectorised_function(temp, j)
# x, i, j, temp, temp2 only exist for the duration of local(...)
})
Adding to the above suggestions, for assisting beginners like me, I would like to list steps to check on R memory:
List the objects that are unused using ls().
Check the objects of interest using object.size("Object_name")
Remove unused/unnecessary objects using rm("Object_name")
Use gc()
Check memory cleared using memory.size()
In case, you are using a new session, use rm(list=ls()) followed by gc().
If one feels that the habit of removing unused variables, can be dangerous, it is always a good practice to save the objects into R images occasionally.
I think it's a good programming practice to remove unused code, regardless of language.
It's also a good practice to use a version control system like Subversion or Git to track your change history. If you do that you can remove code without fear, because it's always possible to roll back to earlier versions if you need to.
That's fundamental to professional coding.
Show distribution of the largest objects and return their names, based on #Peter Raynham:
memory.biggest.objects <- function(n=10) { # Show distribution of the largest objects and return their names
Sizes.of.objects.in.mem <- sapply( ls( envir = .GlobalEnv), FUN = function(name) { object.size(get(name)) } );
topX= sort(Sizes.of.objects.in.mem,decreasing=T)[1:n]
Memorty.usage.stat =c(topX, 'Other' = sum(sort(Sizes.of.objects.in.mem,decreasing=T)[-(1:n)]))
pie(Memorty.usage.stat, cex=.5, sub=make.names(date()))
# wpie(Memorty.usage.stat, cex=.5 )
# Use wpie if you have MarkdownReports, from https://github.com/vertesy/MarkdownReports
print(topX)
print("rm(list=c( 'objectA', 'objectB'))")
# inline_vec.char(names(topX))
# Use inline_vec.char if you have DataInCode, from https://github.com/vertesy/DataInCode
}

How to generate new unique name for context?

What is the best way to generate a name for some temporary context which is guaranteed to be unique (context with this name must not exist in the system)?
The following expression will generate a context name that is guaranteed not to conflict with any loaded context:
First#Contexts[] //.
c_ /; MemberQ[Contexts[], c] :>
"Context"~~ToString[RandomInteger[1000000]]~~"`"
It makes no attempt to account for contexts that are not yet loaded. As written, this expression could be used up to 1,000,000 times before running out of names. Adjust the fixed string ("Context") and name count (1000000) to suit your taste.
Update
As #Leonid points out in a comment, empty contexts will not be listed in Contexts[]. Therefore, it is strictly speaking possible that this expression could return the name of an existing empty context.
UUIDs
For all practical purposes, generating a name from a number randomly selected from a large enough range would work, e.g.
"Context"~~ToString[RandomInteger[2^128]]~~"`"
In a similar vein, one could use a UUID. UUIDs are routinely used as identifiers that are phenomenally likely to be unique across all network nodes as well:
Needs["JLink`"]
LoadJavaClass["java.util.UUID"]
"Context"~~
StringReplace[JavaBlock#java`util`UUID`randomUUID[]#toString[], "-" -> ""]~~
"`"
I can suggest a function I used here:
Clear[unique];
unique[sym_] :=
ToExpression[
ToString[Unique[sym]] <>
StringReplace[StringJoin[ToString /# Date[]], "." :> ""]];
You can replace the ToExpression by StringJoin[...,"`"] to tailor it to your needs.
Another option would be to look at all starting contexts (before the first backquote), find their string length and then generate a string (maybe random, but that isn't necessary) that is at least one character longer than the others. This is guaranteed to be unique, and there isn't even a theoretical possibility of a collision as in some of the other solutions.
sl = (StringSplit[#, "`"][[1]] & /# Contexts[] // StringLength // Max )
Out[349]= 30
In[353]:= "c" ~~ ToString[10^sl] ~~ "`"
Out[353]= "c1000000000000000000000000000000`"
A disadvantage of this method would be that the context names get longer after each repeated application of this method. ;-) If that's a problem we could create a unique name based on the set of longest context names using Cantor's diagonal procedure.
Is Unique perhaps what you're looking for?
This is really an example illustrating Alexey's response to Sjoerd's answer/question. From a fresh kernel on my machine, the following code
Begin["myContext3`"];
Unique["myContext"]
Yields "myContext3". Thus, clearly, Unique (the first thing I thought of) does not work.
Incidentally, I would have just added a comment to Sjoerd's response, but I don't know how to include the accent symbol used to denote a context inline. Does anyone here know how to do this?

Resources