Ñò
ÎÑAHc           @   sï   d  Z  d d k l Z d d k Z d d k Z d d k Z d d k Z d d k	 Z	 d d k
 Z
 d d k Z d d k l Z d „  Z e ƒ  Z d e	 i f d „  ƒ  YZ d d d	 „  ƒ  YZ d
 „  Z d „  Z d „  Z e d j o e ƒ  n d S(   s&   PickleShare - a small 'shelve' like datastore with concurrency support

Like shelve, a PickleShareDB object acts like a normal dictionary. Unlike 
shelve, many processes can access the database simultaneously. Changing a 
value in database is immediately visible to other processes accessing the 
same database.

Concurrency is possible because the values are stored in separate files. Hence
the "database" is a directory where *all* files are governed by PickleShare.

Example usage::
    
    from pickleshare import *
    db = PickleShareDB('~/testpickleshare')
    db.clear()
    print "Should be empty:",db.items()
    db['hello'] = 15
    db['aku ankka'] = [1,2,313]
    db['paths/are/ok/key'] = [1,(5,46)]
    print db.keys()
    del db['aku ankka']

This module is certainly not ZODB, but can be used for low-load 
(non-mission-critical) situations where tiny code size trumps the 
advanced features of a "real" object database.

Installation guide: easy_install pickleshare

Author: Ville Vainio <vivainio@gmail.com>
License: MIT open source license.

iÿÿÿÿ(   t   pathN(   t   Setc         C   s   d t  t |  ƒ d ƒ d S(   Ns   %02xi   iþÿÿÿ(   t   abst   hash(   t   key(    (    sV   /u/d/b/dbachman/web/work/lib/python2.3/site-packages/IPython/Extensions/pickleshare.pyt   gethashfile-   s    t   PickleShareDBc           B   s˜   e  Z d  Z d „  Z d „  Z d „  Z d „  Z e e d „ Z	 d „  Z
 d „  Z d „  Z d	 „  Z d d
 „ Z d „  Z d d „ Z d „  Z d „  Z RS(   s7    The main 'connection' object for PickleShare database c         C   sI   t  | ƒ i ƒ  i ƒ  |  _ |  i i ƒ  p |  i i ƒ  n h  |  _ d S(   s:    Return a db object that will manage the specied directoryN(   t   Patht
   expandusert   abspatht   roott   isdirt   makedirst   cache(   t   selfR
   (    (    sV   /u/d/b/dbachman/web/work/lib/python2.3/site-packages/IPython/Extensions/pickleshare.pyt   __init__4   s    c      	   C   sÄ   |  i  | } y | i ƒ  t i } Wn t j
 o t | ƒ ‚ n X| |  i j o( | |  i | d j o |  i | d Sy t i | i ƒ  ƒ } Wn t | ƒ ‚ n X| | f |  i | <| S(   s    db['key'] reading i   i    (	   R
   t   statt   ST_MTIMEt   OSErrort   KeyErrorR   t   picklet   loadt   open(   R   R   t   filt   mtimet   obj(    (    sV   /u/d/b/dbachman/web/work/lib/python2.3/site-packages/IPython/Extensions/pickleshare.pyt   __getitem__=   s    (c         C   s¡   |  i  | } | i } | o | i ƒ  o | i ƒ  n t i | | i d ƒ ƒ } y | | i f |  i | <Wn, t	 j
 o  } | i
 d j o ‚  q n Xd S(   s    db['key'] = 5 t   wi   N(   R
   t   parentR   R   R   t   dumpR   R   R   R   t   errno(   R   R   t   valueR   R   t   pickledt   e(    (    sV   /u/d/b/dbachman/web/work/lib/python2.3/site-packages/IPython/Extensions/pickleshare.pyt   __setitem__P   s    	c         C   sl   |  i  | } | i ƒ  p | i ƒ  n | t | ƒ } |  i | h  ƒ } | i h | | 6ƒ | |  | <d S(   s    hashed set N(   R
   R   R   R   t   gett   update(   R   t   hashrootR   R   t   hroott   hfilet   d(    (    sV   /u/d/b/dbachman/web/work/lib/python2.3/site-packages/IPython/Extensions/pickleshare.pyt   hset]   s    c         C   sˆ   |  i  | } | t | ƒ } |  i | t ƒ } | t j o< | o" | t j o t | ƒ ‚ n | S|  i | ƒ } n | i | | ƒ S(   s    hashed get (   R
   R   R#   t	   _sentinelR   t   hdict(   R   R%   R   t   defaultt	   fast_onlyR&   R'   R(   (    (    sV   /u/d/b/dbachman/web/work/lib/python2.3/site-packages/IPython/Extensions/pickleshare.pyt   hgeti   s    c         C   sÇ   |  i  | d ƒ } | i ƒ  t | ƒ o | d p d } | i d ƒ o | g | d  } n h  } xZ | D]R } y | i |  | ƒ Wn' t j
 o d G| Gd GH|  | =n X|  i | ƒ qm W| S(   s>    Get all data contained in hashed category 'hashroot' as dict s   /*iÿÿÿÿt    t   xxt   Corrupts!   deleted - hset is not threadsafe!(   t   keyst   sortt   lent   endswithR$   R   t   uncache(   R   R%   t   hfilest   lastt   allt   f(    (    sV   /u/d/b/dbachman/web/work/lib/python2.3/site-packages/IPython/Extensions/pickleshare.pyR+   |   s    
 c         C   sœ   |  i  | d ƒ } h  } x, | D]$ } | i |  | ƒ |  i | ƒ q  W| |  | d <x? | D]7 } |  i | } | i ƒ  d j o q] n | i ƒ  q] Wd S(   s»    Compress category 'hashroot', so hset is fast again
        
        hget will fail if fast_only is True for compressed items (that were
        hset before hcompress).
        
        s   /*s   /xxR0   N(   R2   R$   R6   R
   t   basenamet   remove(   R   R%   R7   R9   R:   t   p(    (    sV   /u/d/b/dbachman/web/work/lib/python2.3/site-packages/IPython/Extensions/pickleshare.pyt	   hcompress“   s      c         C   sH   |  i  | } |  i i | d ƒ y | i ƒ  Wn t j
 o n Xd S(   s    del db["key"] N(   R
   R   t   popt   NoneR<   R   (   R   R   R   (    (    sV   /u/d/b/dbachman/web/work/lib/python2.3/site-packages/IPython/Extensions/pickleshare.pyt   __delitem__ª   s    c         C   s"   t  |  i i | ƒ ƒ i d d ƒ S(   s%    Make a key suitable for user's eyes s   \t   /(   t   strR
   t	   relpathtot   replace(   R   R=   (    (    sV   /u/d/b/dbachman/web/work/lib/python2.3/site-packages/IPython/Extensions/pickleshare.pyt   _normalizedµ   s    c         C   s   | d j o |  i i ƒ  } n8 g  } t i |  i | ƒ D] } | t | ƒ q; ~ } g  } | D]' } | i ƒ  o | |  i | ƒ qb qb ~ S(   s,    All keys in DB, or all keys matching a globN(   R@   R
   t	   walkfilest   globR   t   isfileRF   (   R   t   globpatt   filest   _[1]R=   t   _[2](    (    sV   /u/d/b/dbachman/web/work/lib/python2.3/site-packages/IPython/Extensions/pickleshare.pyR2   ¹   s    7c         G   s<   | p h  |  _  n x! | D] } |  i  i | d ƒ q Wd S(   sÜ    Removes all, or specified items from cache
        
        Use this after reading a large amount of large objects
        to free up memory, when you won't be needing the objects
        for a while.
         
        N(   R   R?   R@   (   R   t   itemst   it(    (    sV   /u/d/b/dbachman/web/work/lib/python2.3/site-packages/IPython/Extensions/pickleshare.pyR6   Â   s
     i<   c         C   s¾   d g d d g d d g } d } d } xŒ y |  | } | SWn t  j
 o n X| | j o t  | ƒ ‚ n t i | | ƒ | | | 7} | t | ƒ d j  o | d 7} q. q. d S(   s"   Wait (poll) for a key to get a value
        
        Will wait for `maxwaittime` seconds before raising a KeyError.
        The call exits normally if the `key` field in db gets a value
        within the timeout period.
        
        Use this for synchronizing different processes or for ensuring
        that an unfortunately timed "db['key'] = newvalue" operation 
        in another process (which causes all 'get' operation to cause a 
        KeyError for the duration of pickling) won't screw up your program 
        logic. 
        gš™™™™™É?i   g      à?i   i   i    N(   R   t   timet   sleepR4   (   R   R   t   maxwaittimet   wtimest   triest   waitedt   val(    (    sV   /u/d/b/dbachman/web/work/lib/python2.3/site-packages/IPython/Extensions/pickleshare.pyt   waitgetÏ   s    
c         C   s   t  |  | ƒ S(   s,    Get a convenient link for accessing items  (   t   PickleShareLink(   R   t   folder(    (    sV   /u/d/b/dbachman/web/work/lib/python2.3/site-packages/IPython/Extensions/pickleshare.pyt   getlinkï   s    c         C   s   d |  i  S(   Ns   PickleShareDB('%s')(   R
   (   R   (    (    sV   /u/d/b/dbachman/web/work/lib/python2.3/site-packages/IPython/Extensions/pickleshare.pyt   __repr__ó   s    N(   t   __name__t
   __module__t   __doc__R   R   R"   R)   R*   t   TrueR.   R+   R>   RA   RF   R@   R2   R6   RW   RZ   R[   (    (    (    sV   /u/d/b/dbachman/web/work/lib/python2.3/site-packages/IPython/Extensions/pickleshare.pyR   2   s   											 	RX   c           B   s2   e  Z d  Z d „  Z d „  Z d „  Z d „  Z RS(   sà    A shortdand for accessing nested PickleShare data conveniently.

    Created through PickleShareDB.getlink(), example::

        lnk = db.getlink('myobjects/test')
        lnk.foo = 2
        lnk.bar = lnk.foo + 5
    
    c         C   s   |  i  i t ƒ  ƒ d  S(   N(   t   __dict__R$   t   locals(   R   t   dbt   keydir(    (    sV   /u/d/b/dbachman/web/work/lib/python2.3/site-packages/IPython/Extensions/pickleshare.pyR     s    c         C   s   |  i  d |  i  d d | S(   NRb   Rc   RB   (   R`   (   R   R   (    (    sV   /u/d/b/dbachman/web/work/lib/python2.3/site-packages/IPython/Extensions/pickleshare.pyt   __getattr__  s    c         C   s   | |  i  |  i d | <d  S(   NRB   (   Rb   Rc   (   R   R   RV   (    (    sV   /u/d/b/dbachman/web/work/lib/python2.3/site-packages/IPython/Extensions/pickleshare.pyt   __setattr__  s    c         C   sl   |  i  d } | i |  i  d d ƒ } d |  i  d d i g  } | D] } | t | ƒ i ƒ  qE ~ ƒ f S(   NRb   Rc   s   /*s   <PickleShareLink '%s': %s>t   ;(   R`   R2   t   joinR   R;   (   R   Rb   R2   RL   t   k(    (    sV   /u/d/b/dbachman/web/work/lib/python2.3/site-packages/IPython/Extensions/pickleshare.pyR[   	  s
    
(   R\   R]   R^   R   Rd   Re   R[   (    (    (    sV   /u/d/b/dbachman/web/work/lib/python2.3/site-packages/IPython/Extensions/pickleshare.pyRX   ø   s
   				c          C   s  t  d ƒ }  |  i ƒ  d G|  i ƒ  GHd |  d <d d d g |  d <d d g |  d <|  i d d d ƒ |  i d d d ƒ d G|  i d d ƒ GHd G|  i d d ƒ GHd G|  i d ƒ GH|  i ƒ  GH|  i d ƒ GHt |  ƒ GH|  i ƒ  |  i	 d ƒ } d | _
 | i
 d	 | _ | i GHd  S(   Ns   ~/testpickleshares   Should be empty:i   t   helloi   i   i9  s	   aku ankkai   i.   s   paths/nest/ok/keynameR   t   akui   t   ankkas   12 =s   313 =s
   all hasheds   paths/nest/ok/k*s   myobjects/test(   i   i.   (   R   t   clearRN   R)   R.   R+   R2   t   dictR6   RZ   t   foot   bar(   Rb   t   lnk(    (    sV   /u/d/b/dbachman/web/work/lib/python2.3/site-packages/IPython/Extensions/pickleshare.pyt   test  s&    


	c          C   sS  t  d ƒ }  d d  k } d d  k } x(t d ƒ D]} xá t d ƒ D]Ó } | d d j o8 | d j  o+ t | ƒ |  j o |  t | ƒ =qD qD n | d d j o | i d ƒ n |  i t | ƒ g  ƒ | | d	 t i ƒ  f g |  t | ƒ <|  i	 d
 | |  i
 d
 | d ƒ d ƒ qD W| G| i i ƒ  | d d j o |  i ƒ  q1 q1 Wd  S(   Ns
   ~/fsdbtestiÿÿÿÿiè  i   i    iÈ   i!   g{®Gáz”?s   proc %dR   i   i
   (   R   RP   t   syst   rangeRC   RQ   R#   t   ost   getpidR)   R.   t   stdoutt   flushR6   (   Rb   RP   Rr   t   it   j(    (    sV   /u/d/b/dbachman/web/work/lib/python2.3/site-packages/IPython/Extensions/pickleshare.pyt   stress(  s$      <*c          C   s„  d d  k  }  |  i d ƒ } t } d d  k } t | i ƒ d j  o
 | GHd  S| i d } | i d } | d j oG | p d g } n | | d ƒ } d d  k } | i | i ƒ  ƒ nÆ | d j o` | i i	 ƒ  } | | d ƒ } t
 | ƒ }	 | i ƒ  x€ | i ƒ  D] \ }
 } | | |
 <q
WnY | d	 j o, | | d ƒ } | i ƒ  | i d
 ƒ GHn  | d j o t ƒ  t ƒ  n d  S(   NiÿÿÿÿsÒ       pickleshare - manage PickleShare databases 
    
    Usage:
        
        pickleshare dump /path/to/db > dump.txt
        pickleshare load /path/to/db < dump.txt
        pickleshare test /path/to/db
    i   i   R   t   .i    R   t   testwaitt   250Rq   (   t   textwrapt   dedentR   Rr   R4   t   argvt   pprintRN   t   stdint   readt   evalRl   RW   Rq   Rz   (   R~   t   usaget   DBRr   t   cmdt   argsRb   R   t   contt   dataRh   t   v(    (    sV   /u/d/b/dbachman/web/work/lib/python2.3/site-packages/IPython/Extensions/pickleshare.pyt   main=  s>    	 
 
t   __main__(    (   R^   t   IPython.external.pathR    R   Rt   R   RP   t   cPickleR   t   UserDictt   warningsRH   t   setsR   t   setR   t   objectR*   t	   DictMixinR   RX   Rq   Rz   RŒ   R\   (    (    (    sV   /u/d/b/dbachman/web/work/lib/python2.3/site-packages/IPython/Extensions/pickleshare.pyt   <module>"   s    $		Æ			'