Consider some OOP language (doesn't really matter which one is it) and suppose the language creator would like to add a deep clone() method for every class. Also, it is given that the heap is implemented as a tree.
How should the language creator implement it?
So basically we can (automatically, at compilation time) implement a clone() method and adding it to the proper functions virtual table.
It will malloc() the proper size which is known in run-time and copy from source to destination. Finally, it will return the pointer to the malloced memory.
If a field is a pointer to some object, we shall activate it's clone() and put the result as value at that field.
What problem would arise if the heap was not "tree-based"?
So I really don't know what the answer is. I mean, why is it relevant how the heap was implemented? I'd be glad for help here.
Thanks.
The algorithm you describe works fine as soon as the object structure is acyclic, i.e. forms a tree. Then indeed, it's OK to make a shallow clone of an object and then to proceed with updating fields that refer to other objects using the same technique.
However, if there are cycles (i.e. the object structure does not form a tree), the algorithm will run forever. In the simplest case the initial object o references itself: o -> o. When a shallow clone c1 is created, the new object still references the old one: c1 -> o. Also, the old object is unchanged, i.e. we have c1 -> o -> o. According to the algorithm a clone of the object referenced from the clone should be created. Because this is a new object, it is different from c1. So, the picture becomes c1 -> c2 -> o. This is already wrong, because what a deep clone should create is c1 -> c1. The bad news is that c2 is now also a subject for processing. So, we get c1 -> c2 -> c3 -> o, etc. The algorithm loop forever (until there is no more memory to create new objects).
To make the algorithm working, it should track what old objects have been processed and what new objects have been created for them. Then instead of blindly making new clones of referenced objects it should check whether an old object has been cloned already and, if yes, use this clone rather than create a new one.
Related
HPX supports Active Global Address Space.Over a long period of time, I can't able to figure out what "AGAS" really is ? By doing some research with HPX-5 supported memory models. What I can able to see is in "AGAS: memory can be moved to other localities in order to balance the system" but in "PGAS" it is not able to do so. But in hpx we still create remote objects (components) with the parameter where to create it(Global identifiers of localities). But using HPX in desktop really hides this feature and also running HPX in rostam I can't able to differentiate it with "PGAS" memory system. Could you please help me to understand this black magic feature of HPX ?
You can think of AGAS as being a distributed key/value 'in memory' database.
When you create an object locally, you get a pointer of the standard variety that is referable using *this or this-> to get access to the internals.
However, you cannot pass a this pointer from one node to another and use it arbitrarily.
When you create an hpx:: component or register an object that you created with AGAS, it essentially stores the this pointer in the database and gives you an hpx::id_type as a handle (key). This id can be used in function calls on local or remote nodes as a way of referencing the object.
If you move the object from one node to another (using an agas function), then AGAS will update it's internal value to reflect the fact that the this pointer has changed value (it will internally have its destructor called locally and invoke a move of contents into a new one constructed elsewhere) and is located on another node, but the key - the id_type that you have for that object is still valid - note that this is only true if AGAS is doing the relocation - if you just create a copy elsewhere and delete a local object, it's not the same.
On a PGAS system, generally speaking, all the nodes share a block of memory with each other, and each node can 'access' memory/data/objects on the other node, by indexing into this shared memory area. So in PGAS, the addresses of items on other nodes are 'fixed' in the sense that data on node 1 is at shared_region + offset*1, data on node 2 is at + offset*2 and so on. This is a slight simplification, but you get the idea.
In HPX, objects are free to float about and you can reference them via the id_types and let AGAS handle the 'real' address lookups. That is why the 'Active' is in AGAS, as opposed to PGAS.
In this way data items (components) can be relocated from one place to another, but the handles that refer to them can be immutable.
In this sense the 'Address Space' part of AGAS is saying that hpx::id_type's can be thought of as addresses that span all the nodes in the job.
Firstly, i am sorry if the title does not properly describe my problem, but i could not think of a better one. =/
I am trying to make a game where all entities that I need to draw on the screen are children of an Actor class.
The actor class has a virtual function called "virtual void drawMe()" that is overridden by the children to specify how it should be drawn.
Ergo, at the end of the game loop, I want to draw all actors. I created a "vector allActors" to help me with this and every time I create a new actor I do this: "allActors.push_back( &newActor )". So far so good (I think).
To draw them at the end of the loop I iterate through all elements in allActors and call "allActors[i]->drawMe()" for each one.
But I discovered that this method will not work for actors that I created locally, like the bullets created when the character shoots (they are created inside an if statement).
I think it is because while I save the address of the bullets in the allActors vector, the actors themselves are destroyed after the if statement ends, so it's an address to nothing.
example:
if ( characterShot == true)
{
Bullet newBullet;
allActors.push_back( &newBullet );
characterShot = false;
}
I have no idea of how to do this in a way that it works, because I can only create the bullet actors IF the character shoots!
Please help me figure out a better and more functional way to do what I want.
Thank you in advance!
Allocate the object dynamically:
allActors.push_back(new Bullet);
Note that the lifetime management will be a genuine nightmare; you should make the container elements some sort of smart pointer (ideally std::unique_ptr<Bullet> or some suitable base class).
You're right in your assumption that you're pushing an address to a local object that then goes out of scope. Doing this should cause your application to be quite unstable.
Allocate the object on the heap instead, using a smart pointer that keeps track of the lifetime of the object for you:
allActors.push_back(tr1::shared_ptr<Bullet>(new Bullet));
This gives you another problem: You have to remove the bullet from the allActors array once it hits the target.
I am looking for some guidance as to what is going on when using proto-buf net with obfuscation (Dotfuscator). One half of the project is a DLL and the other is an EXE elsewhere and using proto-buf NET they exchange data flawlessly. Until I obfuscate the DLL.
At that point P-BN fails without raising an exception, returning variously a 0 length byte array or a foreshortened one depending on what I have fiddled with. The class is fairly simple (VB):
<ProtoContract(Name:="DMailer")> _
Friend Class DMailer
Private _Lic As Cert
Private _Sys As Sys
Private _LList As List(Of LItem)
..
..
End Class
There are 3 props all decorated with ProtoMember to get/set the constituent class objects. Snipped for brevity.
Again, it works GREAT until I obfuscate the DLL. Then, Dotfuscator renames each of these to null, apparently since they are all Friend, and that seems to choke proto-buff. If I exempt the class from renaming (just the class name, not props/members), it seems to work again. It makes sense that P-BN would only be able to act on objects with a proper name, though when asked to serialize a null named object, it seems like an exception might be in order.
On the other hand, much of the charm of PB-N is supposed to be serialization independent of .NET names working from attributes - at least as I understand it. Yet in this case it only seems to work with classes with names. I tried using the Name qualifier or argument as shown above, to no avail - it apparently doesnt do what I thought it might.
So, I am curious if:
a) ...I have basically surmised the problem correctly
b) ...There is some other attribute or flag that might facilitate serializing
a null named object
c) ...if there are any other insights that would help.
If I exempt all 3 or 4 classes from Dotfuscator renaming (LList is not actually implemented yet, leaving DMailer, Cert and Sys), the DLL seems to work again - at least the output is the correct size. I can live with that, though obscured names would be better: Dotfuscator (CE) either exempts them or sets the names to Null - I cant seem to find a way to force them to be renamed.
Rather than exempt 3 or 4 classes from renaming, one alternative I am considering is to simply store the Serializer output for Cert and Sys as byte arrays or Base64 strings in DMailer instead of classes. Then have the receiver Deserialize each object individually. It is kind of nice to be able to unpack just one thing and have your toys right there as if by magic though.
(many)TIA
Interesting. I confess I have never tried this scenario, but if you can walk me through your process (or better: maybe provide a basic repro example with "run this, then this, then this: boom") I'll happily investigate.
Note: the Name on ProtoContract is mainly intended for GetProto() usage; it is not needed by the core serializer, and can be omitted to reduce your exposure. Also, protobuf-net isn't interested in fields unless those fields are decorated with the attributes, so that shouldn't be an issue.
However! there's probably a workaround here that should work now; you can pre-generate a static serialization dll; for example in a separate console exe (just as a tool; I really need to wrap this in a standalone utility!)
So if you create a console exe that references your unobfuscated library and protobuf-net.dll:
var model = RuntimeTypeModel.Create();
model.Add(typeof(DMailer), true); // true means "use the attributes etc"
// and other types needed, etc
model.Compile("MailSerializer", "MailSerializer.dll");
this should write MailSerializer.dll, which you can then reference from your main code (in addition to protobuf-net), and use:
var ser = new MailSerializer(); // our pre-genereated serializer
ser.Serialize(...); // etc
Then include MailSerializer.dll in your obfuscation payload.
(this is all v2 specific, btw)
If this doesn't work, I'll need to investigate the main issue, but I'm not an obfuscation expert so could do with your repro steps.
Since there were a few upticks of interest, here is what looks like will work:
a) No form of reflection will be able to get the list of properties for an obfuscated type.
I tried walking thru all the types to find the ones with ProtoContract on it, I could find them
but the property names are all changed to a,m, b, j, g.
I also tried Me.GetType.GetProperties with the same result.
You could implement a map from the output to indicate that Employee.FirstName is now a0.j, but distributing this defeats the purpose of obfuscation.
b) What does work to a degree is to exempt the class NAME from obfuscation. Since PB-N looks for the ProtoMember attributes to get the data, you CAN obfuscate the Property/Member names, just not the CLASS/type name. If the name is something like FederalReserveLogIn, your class/type has a bullseye on it.
I have had initial success doing the following:
1) Build a simple class to store a Property Token and value. Store everything as string using ConvertFromInvariantString. Taking a tip from PBN, I used an integer for the token:
<ProtoMember(propIndex.Foo)>
Property Foo As String
An enum helps tie everything together later. Store these in a Dictionary(Of T, NameValuePair)
2) add some accessors. these can perform the type conversions for you:
Public Sub Add(ByVal Key As T, ByVal value As Object)
If _col.ContainsKey(Key) Then
_col.Remove(Key)
End If
_col.Add(Key, New TValue(value))
End Sub
Public Function GetTItem(Of TT)(key As T) As TT
If _col.ContainsKey(key) Then
Return CType(_col(key).TValue, TT)
Else
Return Nothing
End If
End Function
T is whatever key type you wish to use. Integer results in the smallest output and still allows the subscribing code to use an Enum. But it could be String.
TT is the original type:
myFoo = props.GetTItem(Of Long)(propsEnum.Foo)
3) Expose the innerlist (dictionary) to PBN and bingo, all done.
Its also very easy to add converters for Point, Rectangle, Font, Size, Color and even bitmap.
HTH
I've got a Registry class and there are a few Registry values that I want to access from within that Registry class. (There is a bit of a calculation with these values so I thought I'd just put all that code right in the Registry Class itself).
So we might have something within our RegistryRoutine.cls like:
Function GetMyValue() as integer
Dim R as new RegistryRoutine
<calculations>
GetMyValue=R.GetRegisetryValue (HKEY, key, value, etc.)
End Function
No, in general you won't see any problems (like member variables being overwritten or anything weird like that).
Where you could run into issues is if you have explicity shared variables that are being written to multiple times. But that's dangerous no matter what you do.
Do watch out for recursive cases - e.g., GetMyValue() should not call R.GetMyValue(), nor should GetRegistryValue() call GetMyValue().
It's rare that you actually want to do this, however.
Since you're not passing any arguments into GetMyValue(), we can assume that the current instance already has all the information it needs.
Since you're only returning an integer, not a RegistryRoutine instance, the client has no need for a new instance.
So, why not just call GetRegistryValue (without the R.)?
It's quite common for classes to work with instances of themselves. Consider, for example, how a tree structure works. Either a Node class has to keep track of its children, or has to keep track of its parent (or both). All the nodes are the same class.
Below is a code snippet that is creating object.
Form userexit_save_document_prepare.
data: /bks/exitmanager type ref to /bks/exit_manager.
create object /bks/exitmanager
exporting main_prog = 'SAPMV45A'
exit_form = 'USEREXIT_SAVE_DOCUMENT_PREPARE'.
include /bks/exitman.
ENDFORM.
I got this from the documentation
For performance reasons, the parameters "main_prog" and "exit_form" should be filled, in the case of userexits, which are performed very often like "user_field_modification" in "SAPMV45A" which is called for every single screen-field.
1) What happened exactly behind when create object /bks/exitmanager is called? memory allocated for the object etc?
2) Why for performance reasons the exporting parameters of create object needs to be filled?
I'm not 100% sure, but here is my best guess:
an object called /bks/exitmanager is constructed (which is an oject of the class /bks/exit_manager or more specific a reference/"pointer" to an object of this class) .. the required memory allocated etc., but also the "constructor" code is called (probably sets some instance variables as passed to the call).
If you're explicitly passing these parameters, they don't have to be "calculated" at run-time (e.g. by looking at the call stack). This should save some time, especially if it would have to be done quite often (as described in the documentation).
It would help to see what /bks/exit_manager actually is, and a brief explanation of what you are trying to accomplish.
Expanding on what IronGoofy wrote:
data: /bks/exitmanager type ref to /bks/exit_manager
This creates a reference pointer in the ABAP memory of your program, much like a field symbol. Also it must be already delared. If it is in the include, you need to move the include.
create object /bks/exitmanager
exporting main_prog = 'SAPMV45A'
exit_form = 'USEREXIT_SAVE_DOCUMENT_PREPARE'.
This creates an object instance based on the declared class, and assigns it to the referance pointer. It does this by calling the constructor method first.
Only by examing /bks/exit_manager will you find out exactly what you need to export.
It's impossible to tell what's going on and why the parameters should be passed without taking a look at the constructor of /BKS/EXIT_MANAGER. It's a common pattern though to keep a buffer of settings (think of a static hashed table with the key being the parameters and the value holding whatever is complicated and time-consuming to fetch). In this case, I would have expected a protected constructor that cannot be accessed directly, but only using a static factory method that uses a hashed table to keep the references of the exit handler itself - optimally using weak references...