copy-on-write for dict objects?

Michael Hudson mwh at python.net
Thu Jan 16 09:25:31 EST 2003


Matthias Oberlaender <matthias.oberlaender at REMOVE.daimlerchrysler.com> writes:

> In <7h3n0m2p77m.fsf at pc150.maths.bris.ac.uk> Michael Hudson wrote:
> > Matthias Oberlaender <matthias.oberlaender at REMOVE.daimlerchrysler.com> 
> writes:
> > 
> > > Is there an easy way in Python 2.2.1 to add a copy-on-write mechanism to 
> > > subclasses of dict, i.e. without extending/modifying the C-code 
> > > implementation?  (I guess there is none!)
> > 
> > Not sure what you mean.  But I doubt it.  You need a level of
> > indirection in there, so I don't see how you could do it directly even
> > hacking C.
> > 
> > > I don't want to resort to UserDict again, since, at least for my
> > > purposes, it's much slower than direct subclasses of dict (around
> > > 10x)
> > 
> > I know that feeling.
> > 
> Thanks for all the answers so far (from Andrew, Just and Michael)
> 
> A line of "hacking" I could think of is this:
> 
> class MyDict(dict):
> 
>   def __init__(self, d)
>     self.sharedDict = d
>     self.oldPtr = getTable(self)
>     # getTable should be some external function that returns the C pointer to
>     # the object's hashtable
>     setTable(self, getTable(self.sharedDict))
>     # setTable should be some external function that explicitly sets the C 
>     # pointer to the hashtable
>     self.mustCopy = 1
>     
>   def _onWrite(self):
>     setTable(self, self.oldPtr)
>     self.update(self.sharedDict)
>     self.sharedDict = None # give up the reference 
>     self.mustCopy = 0
>     
>   ....
> 
> You get the idea? I don't know much about the magic behind the scenes. Maybe 
> this is to naive? 

Hmm, that could work.  Is never going to from Python, though, I'd hazard.

You *could* try this (untested):

class UnSharedDict(dict):
   __slots__ = ["other"]

class SharedDict(UnSharedDict, UserDict.DictMixin):
   __slots__ = ["other"]
   def __init__(self, other):
       self.other = other
   def __getitem__(self, key):
       return self.other[key]
   def __setitem__(self, key, value):
       super(SharedDict, self).__setitem__(key, value)
       self.__class__ = UnSharedDict

   def has_key(self, key):
       return key in self.other
   def __iter__(self):
       return iter(self.other)

But you're probably going to find lot's of places that blissfully
ignore the __getitem__ method.

> Why do I want this ? 

That wasn't the bit that bothered me :)

Cheers,
M.

-- 
  I really hope there's a catastrophic bug insome future e-mail
  program where if you try and send an attachment it cancels your
  ISP account, deletes your harddrive, and pisses in your coffee
                                                         -- Adam Rixey




More information about the Python-list mailing list