-
Notifications
You must be signed in to change notification settings - Fork 28
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
CustomFunc should allow Ptr types as well #23
Comments
One possible way to implement the feature you mentioned could be that you can consider to define a new struct to wrap the pointer and implement the logic on this new struct. Something like following. type MyPointer struct {
*ActualPointer
} Here is a workable sample for you. Hope it can help you. type T struct {
shouldClone bool
data []string
}
type Pointer struct {
*T
}
values := map[string]Pointer{
"shouldClone": {
T: &T{
shouldClone: true,
data: []string{"a", "b", "c"},
},
},
"shouldNotClone": {
T: &T{
shouldClone: false,
data: []string{"a", "b", "c"},
},
},
}
clone.SetCustomFunc(reflect.TypeOf(Pointer{}), func(allocator *clone.Allocator, old, new reflect.Value) {
p := old.Interface().(Pointer)
if p.shouldClone {
np := allocator.Clone(old).Interface().(Pointer)
// Update the cloned value to make the change very obvious.
np.data = append(np.data, "cloned")
new.Set(reflect.ValueOf(np))
} else {
new.Set(old)
}
})
cloned := clone.Clone(values).(map[string]Pointer)
fmt.Println(cloned["shouldClone"].data)
fmt.Println(cloned["shouldNotClone"].data)
// Output:
// [a b c cloned]
// [a b c] Live demo: https://go.dev/play/p/3V6VoHPRabd |
Thanks. I did consider this solution, but that would work if clone is the only thing the application does. But there are lot more stuff that goes on, and having to use a wrapper in place of a pointer (Note type alias doesn't work), at every code path using this is a pain. I would love to hear more on why you think there will be a significant performance hit for supporting custom function for pointers to struct? Are you worried, supporting custom functions to pointers to struct would impact non-users of the feature as well or would it slow down only when the feature is used? |
A quick hack. #24 I did not implement this for other cases like cloneSlowly or other variants. I would love to implement it if you are okay with this approach. Do let me know. |
If the
I'll review it later, maybe next Tue. I'm on vacation now. If it's possible, can you please tell me more about your use case with some key code? It can help me to find out the best soluttion. |
I want a way to retain the relationship between the pointer values, when cloning. From my understanding cloneSlowly function does that for a single clone operation. For me, I need a way to be able to use the same visited graph if possible across multiple invocations. |
@jayaprabhakar I got your point. I think it's OK to add some features in Allocator to provide more powerful APIs with some performance penalty for complex use cases. I'll submit a PR soon to address your need. |
Thanks a lot. For additional context on what I am trying to build - I am implementing a new model checker - the first step of it is state space exploration. To do that, every fork points where we have to choose a path between multiple options, I will deep clone the entire state-space, and evaluate each path separately one after another until no new state is found. With these, if I clone the container/parent/root object with clone.Slowly(), it won't work simply, because I need to add custom function to skip a few fields. But those individual fields must be deep cloned as well. But it doesn't have access to the same visitor graph :( So, clone.Slowly here will not be sufficient) So, I think, I would need a way to reuse the visited map in
|
Hi @huandu, did you get a chance to work on this? Or can you give some guidance on how to do it? |
@jayaprabhakar Sorry for the delay. I'm super busy these days and have no time to finish this change. I'll try to spare some time on this weekend. |
No problem, let me know if there is something I can do to make it easy for you to finish it. I am facing an issue with Cloning a specific object type. I use another library starlark extensively, and when I do clone, for one of the types alone, the clone is not working.
https://go.dev/play/p/SRQMnBef26Q In this case, value added to m2 is ignored. I couldn't figure out exactly what causes this. The code for the library is here, Is there some specific feature that is causing this issue. I can try again using Custom Fn but the issue would be with deduplication. I want to use |
CustomFunc are helpful in creating custom clone functions. However, it doesn't work well with Ptrs. Because when adding *Struct, it gets resolved to Struct and similarly when looking up from the map, only the Struct is used.
There are some cases, when custom pointers would be helpful.
For example, in my case, under certain circumstances, I want the ptrs to reuse the same reference and sometimes not.
I am working on a model checker, where the spec might say, multiple alternate paths a process can take, and we would want to explore both the paths. So, from the parent, I would create separate clone of entire variable spaces for each fork, but within each fork I would want to reuse the variable.
Marking it opaque pointer doesn't help, as I would want to actually clone in some cases. So, the ideal solution would be to make allocator.SetCustomFunc(...) to not dereference the Ptr type, and when checking ptrs, and use the custom func when present, before dereferencing the ptr
The text was updated successfully, but these errors were encountered: