From: Sven Suska Date: 2007-05-19T05:34:36+09:00 Subject: Re: "Crystallizing" Objects Hello Robert, thank you for your mail, however, I'm afraid that I haven't been able to grasp what you were up to. Robert Klemme schrieb: > On 17.05.2007 11:55, Sven Suska wrote: > >> Now, I think it should be possible >> to freeze the "already existing" data of an object >> and at the same time leave it open for "further growth". >> Especially, I have Hashes and Arrays in mind: > > Do you envision this added state to be shared by threads or thread local? This state is a property of the object, and thus shared by all threads using this object. >> So, I think it would be beneficial to introduce a third state of objects >> between frozen and normal, like "growing" or "crystallizing" or >> "monotonous" or "incrementally_freezing" or "partially_frozen" ... > > > I do not believe that it would be beneficial and here's why: I have read your explanation (several times) and I just cannot see your point. How does it fit to my use case in my post <464C4426.9080700@suska.org> of May-17, 12:01 GMT: > If "users" were in this "partially_frozen" state, then we could write: > begin > users[new_nickname] = user_data > rescue CantChangeExistingDataError > raise "Nickname already exists" > end Robert Klemme wrote: > on an abstract level the state of the object still changes, > so you need proper synchronization mechanisms in place. ?? What do you mean? The synchronization mechanism is the thing that I am addressing: atomic "check&set" -- such that manual locking is no longer needed. > Now, if you can *identify* the subset of the state that does not change, > you can put it into another instance (probably of another class). OK, let's suppose, we would have several worker threads that would all be allowed to add data to the "users"-Hash. And assuming that the "users"-Hash were initially empty, what would be the subset that does not change, just {} ? > Now you have a clean separation of constant state and mutable state - > even better: you do not have *any* locking issues at all if you use > the mutable instance only in one thread and share the constant only. OK, if I read you correctly, then you would propose to have an object that internally keeps this Hash ("users") and externally presents a thread-safe method check_add_user(name, data). But then you would have to do the locking inside this method, or have I overlooked anything? > Implementation complexity (of the interpreter) and efficiency wise > this is much better than having a single instance with split state > where read write synchronization has to take place. Really? I cannot really tell, but I suggested this idea because I believe that this "partially frozen" state can be implemented without considerable loss of performance. > You will have to define the constant and mutable part > for any class individually anyway ?? What do you mean by that? > so you can as well > build concrete collaborating classes in Ruby that will handle this. > > Concrete: if you want Arrays with common immutable prefixes, > just create a class SharedImmutablePrefixArray (possibly using > Delegator or such) > that refers a shared constant Array and a local mutable Array > and implements methods like #[], #[]=, #each, #size etc. accordingly. But I do not want a local mutable Array, I want the mutable part shared across threads, too!! Or do you mean that to say that SharedImmutablePrefixArray refers a mutable Array for each thread?? (And then the #each method summarizes over the immutable array and all the mutable arrays?) > You could even create this class in a way that the mutable state > is stored via Thread#[] (i.e. thread local storage) > so a single instance can actually be shared by multiple threads. OK. So this is the way you plan to share the mutable part across threads. Do you mean that one thread is special and carries the mutable part for all threads? Then why don't you just use a global variable? Or do you mean that each thread can have its own mutable part? Then how are you going to organize this emerging chaos? ( :-) ) Sorry, I just don't get you here. > Other advantages of this approach: it is *explicit*, i.e. in code you > create an instance of SharedImmutablePrefixArray per thread > and it becomes apparent what's going on. Again, I don't understand. If the object is shared, one object for all the relevant threads would be enough, what can be the use of one object per thread? So long Sven