ó
æNXc           @  s  d  Z  d d l m Z d Z d d l m Z d d l Z d d l Z d d l Z d d l	 Z	 y d d l
 Z Wn e k
 r‹ d d l Z n Xd d l Z d d l Z d „  Z e ƒ  Z d e	 j f d „  ƒ  YZ d	 d d
 „  ƒ  YZ d „  Z e d k r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: pip install path pickleshare

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

iÿÿÿÿ(   t   print_functions   0.5(   t   pathNc         C  s   d t  t |  ƒ d ƒ d S(   Ns   %02xi   iþÿÿÿ(   t   abst   hash(   t   key(    (    sC   /data/av2000/mvv/env_mvv/lib/python2.7/site-packages/pickleshare.pyt   gethashfile4   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 „  Z d „  Z d d „ Z d „  Z d „  Z RS(   s7    The main 'connection' object for PickleShare database c         C  sG   t  | ƒ j ƒ  j ƒ  |  _ |  j j ƒ  s: |  j j ƒ  n  i  |  _ d S(   s:    Return a db object that will manage the specied directoryN(   t   Patht
   expandusert   abspatht   roott   isdirt
   makedirs_pt   cache(   t   selfR
   (    (    sC   /data/av2000/mvv/env_mvv/lib/python2.7/site-packages/pickleshare.pyt   __init__;   s    c         C  s×   |  j  | } y | j ƒ  t j } Wn t k
 rC t | ƒ ‚ n X| |  j k ry | |  j | d k ry |  j | d Sy1 | j d ƒ  } t j | j	 ƒ  ƒ } Wd QXWn t | ƒ ‚ n X| | f |  j | <| S(   s    db['key'] reading i   i    t   rbN(
   R
   t   statt   ST_MTIMEt   OSErrort   KeyErrorR   t   opent   picklet   loadst   read(   R   R   t   filt   mtimet   ft   obj(    (    sC   /data/av2000/mvv/env_mvv/lib/python2.7/site-packages/pickleshare.pyt   __getitem__D   s    &c      
   C  s°   |  j  | } | j } | r6 | j ƒ  r6 | j ƒ  n  | j d ƒ  } t j | | d d ƒWd QXy | | j f |  j | <Wn+ t	 k
 r« } | j
 t
 j k r¬ ‚  q¬ n Xd S(   s    db['key'] = 5 t   wbt   protocoli   N(   R
   t   parentR   t   makedirsR   R   t   dumpR   R   R   t   errnot   ENOENT(   R   R   t   valueR   R    R   t   e(    (    sC   /data/av2000/mvv/env_mvv/lib/python2.7/site-packages/pickleshare.pyt   __setitem__X   s    	c         C  sj   |  j  | } | j ƒ  s& | j ƒ  n  | t | ƒ } |  j | i  ƒ } | j i | | 6ƒ | |  | <d S(   s    hashed set N(   R
   R   R!   R   t   gett   update(   R   t   hashrootR   R%   t   hroott   hfilet   d(    (    sC   /data/av2000/mvv/env_mvv/lib/python2.7/site-packages/pickleshare.pyt   hseth   s    c         C  s‚   |  j  | } | t | ƒ } |  j | t ƒ } | t k rr | r` | t k r\ t | ƒ ‚ n  | S|  j | ƒ } n  | j | | ƒ S(   s    hashed get (   R
   R   R(   t	   _sentinelR   t   hdict(   R   R*   R   t   defaultt	   fast_onlyR+   R,   R-   (    (    sC   /data/av2000/mvv/env_mvv/lib/python2.7/site-packages/pickleshare.pyt   hgett   s    c         C  sÄ   |  j  | d ƒ } | j ƒ  t | ƒ r3 | d p6 d } | j d ƒ r\ | g | d  } n  i  } x[ | D]S } y | j |  | ƒ Wn( t k
 r® t d | d ƒ |  | =n X|  j | ƒ qi 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   printt   uncache(   R   R*   t   hfilest   lastt   allR   (    (    sC   /data/av2000/mvv/env_mvv/lib/python2.7/site-packages/pickleshare.pyR0   ‡   s    
c         C  sš   |  j  | d ƒ } i  } x, | D]$ } | j |  | ƒ |  j | ƒ q  W| |  | d <x= | D]5 } |  j | } | j ƒ  d k rˆ q] n  | j ƒ  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   /xxR5   N(   R7   R)   R<   R
   t   basenamet   remove(   R   R*   R=   R?   R   t   p(    (    sC   /data/av2000/mvv/env_mvv/lib/python2.7/site-packages/pickleshare.pyt	   hcompressž   s    c         C  sF   |  j  | } |  j j | d ƒ y | j ƒ  Wn t k
 rA n Xd S(   s    del db["key"] N(   R
   R   t   popt   NoneRA   R   (   R   R   R   (    (    sC   /data/av2000/mvv/env_mvv/lib/python2.7/site-packages/pickleshare.pyt   __delitem__µ   s    c         C  s"   t  |  j j | ƒ ƒ j d d ƒ S(   s%    Make a key suitable for user's eyes s   \t   /(   t   strR
   t	   relpathtot   replace(   R   RB   (    (    sC   /data/av2000/mvv/env_mvv/lib/python2.7/site-packages/pickleshare.pyt   _normalizedÀ   s    c         C  sy   | d k r |  j j ƒ  } n/ g  t j |  j | ƒ D] } t | ƒ ^ q5 } g  | D]! } | j ƒ  rT |  j | ƒ ^ qT S(   s,    All keys in DB, or all keys matching a globN(   RE   R
   t	   walkfilest   globR   t   isfileRK   (   R   t   globpatt   filesRB   (    (    sC   /data/av2000/mvv/env_mvv/lib/python2.7/site-packages/pickleshare.pyR7   Ä   s    /c         C  s   t  |  j ƒ  ƒ S(   N(   t   iterR7   (   R   (    (    sC   /data/av2000/mvv/env_mvv/lib/python2.7/site-packages/pickleshare.pyt   __iter__Í   s    c         C  s   t  |  j ƒ  ƒ S(   N(   R9   R7   (   R   (    (    sC   /data/av2000/mvv/env_mvv/lib/python2.7/site-packages/pickleshare.pyt   __len__Ð   s    c         G  s:   | s i  |  _  n  x! | D] } |  j  j | 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   RD   RE   (   R   t   itemst   it(    (    sC   /data/av2000/mvv/env_mvv/lib/python2.7/site-packages/pickleshare.pyR<   Ó   s    i<   c         C  s¸   d g d d g d d g } d } d } x† y |  | } | SWn t  k
 rS n X| | k ro t  | ƒ ‚ n  t j | | ƒ | | | 7} | t | ƒ d k  r. | 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   sleepR9   (   R   R   t   maxwaittimet   wtimest   triest   waitedt   val(    (    sC   /data/av2000/mvv/env_mvv/lib/python2.7/site-packages/pickleshare.pyt   waitgetà   s    
c         C  s   t  |  | ƒ S(   s,    Get a convenient link for accessing items  (   t   PickleShareLink(   R   t   folder(    (    sC   /data/av2000/mvv/env_mvv/lib/python2.7/site-packages/pickleshare.pyt   getlink   s    c         C  s   d |  j  S(   Ns   PickleShareDB('%s')(   R
   (   R   (    (    sC   /data/av2000/mvv/env_mvv/lib/python2.7/site-packages/pickleshare.pyt   __repr__  s    N(   t   __name__t
   __module__t   __doc__R   R   R'   R.   R/   t   TrueR3   R0   RC   RF   RK   RE   R7   RR   RS   R<   R]   R`   Ra   (    (    (    sC   /data/av2000/mvv/env_mvv/lib/python2.7/site-packages/pickleshare.pyR   9   s"   													 	R^   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   |  j  j t ƒ  ƒ d  S(   N(   t   __dict__R)   t   locals(   R   t   dbt   keydir(    (    sC   /data/av2000/mvv/env_mvv/lib/python2.7/site-packages/pickleshare.pyR     s    c         C  s   |  j  d |  j  d d | S(   NRh   Ri   RG   (   Rf   (   R   R   (    (    sC   /data/av2000/mvv/env_mvv/lib/python2.7/site-packages/pickleshare.pyt   __getattr__  s    c         C  s   | |  j  |  j d | <d  S(   NRG   (   Rh   Ri   (   R   R   R\   (    (    sC   /data/av2000/mvv/env_mvv/lib/python2.7/site-packages/pickleshare.pyt   __setattr__  s    c         C  sd   |  j  d } | j |  j  d d ƒ } d |  j  d d j g  | D] } t | ƒ j ƒ  ^ qA ƒ f S(   NRh   Ri   s   /*s   <PickleShareLink '%s': %s>t   ;(   Rf   R7   t   joinR   R@   (   R   Rh   R7   t   k(    (    sC   /data/av2000/mvv/env_mvv/lib/python2.7/site-packages/pickleshare.pyRa     s
    
(   Rb   Rc   Rd   R   Rj   Rk   Ra   (    (    (    sC   /data/av2000/mvv/env_mvv/lib/python2.7/site-packages/pickleshare.pyR^   	  s
   				c          C  s‚  d d  l  }  |  j d ƒ } t } d d  l } t | j ƒ d k  rP t | ƒ d  S| j d } | j d } | d k rº | sˆ d g } n  | | d ƒ } d d  l } | j | j ƒ  ƒ nÄ | d k r%| j	 j
 ƒ  } | | d ƒ } t | ƒ }	 | j ƒ  x€ | j ƒ  D] \ }
 } | | |
 <qWnY | d	 k ra| | d ƒ } | j ƒ  t | j d
 ƒ ƒ n | d k r~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    t   loadt   testwaitt   250t   test(   t   textwrapt   dedentR   t   sysR9   t   argvR;   t   pprintRT   t   stdinR   t   evalt   clearR]   Rs   t   stress(   Rt   t   usaget   DBRv   t   cmdt   argsRh   Rx   t   contt   dataRn   t   v(    (    sC   /data/av2000/mvv/env_mvv/lib/python2.7/site-packages/pickleshare.pyt   main!  s<    	
 

t   __main__(    (   Rd   t
   __future__R    t   __version__R   R   t   osR   RV   t   collectionst   cPickleR   t   ImportErrorRM   R#   R   t   objectR/   t   MutableMappingR   R^   R„   Rb   (    (    (    sC   /data/av2000/mvv/env_mvv/lib/python2.7/site-packages/pickleshare.pyt   <module>"   s$   $		Ð	'