Ejemplo n.º 1
0
 def __compactify_remove_index_async( cls, volume_id, parent_id, dead_file_id, dead_dir_index ):
    """
    Remove a freed index slot's node data.
    """
    idx_key_name = MSEntryDirEntIndex.make_key_name( volume_id, parent_id, dead_dir_index )
    ent_key_name = MSEntryEntDirIndex.make_key_name( volume_id, dead_file_id )
    
    idx_key = storagetypes.make_key( MSEntryDirEntIndex, idx_key_name )
    ent_key = storagetypes.make_key( MSEntryEntDirIndex, ent_key_name )
    
    @storagetypes.concurrent
    def delete_index_if_unallocated():
       
       idx_node = yield idx_key.get_async( use_cache=False, use_memcache=False )
       
       if idx_node is None:
           # already gone
           storagetypes.concurrent_return( 0 )
       
       if not idx_node.alloced:
          
          yield idx_key.delete_async()
       
       storagetypes.concurrent_return( 0 )
    
    yield ent_key.delete_async(), storagetypes.transaction_async( delete_index_if_unallocated )
    
    storagetypes.memcache.delete_multi( [idx_key_name, ent_key_name] )
Ejemplo n.º 2
0
 def __update_or_alloc_async( cls, volume_id, parent_id, file_id, dir_index, generation, alloced ):
    """
    Update or allocate the index node pair and/or set the directory index node's allocation status, asynchronously.
    If the directory index node does not exist, it and its entry index node will be created and the allocation status set accordingly.
    If the directory index node exists, but has a different allocation status, then the allocation status will be set accordingly.
    
    If we succeed in allocating a new index node, incremenet the number of children in the parent directory.
    
    Return True on success.
    Return False if the index node existed, but the file_id did not match its record or the allocation status did not change.
    """
    
    index_key_name = MSEntryDirEntIndex.make_key_name( volume_id, parent_id, dir_index )
    
    nonce = random.randint( -2**63, 2**63 - 1 )
    result = True
    idx = yield MSEntryDirEntIndex.get_or_insert_async( index_key_name, volume_id=volume_id, parent_id=parent_id, file_id=file_id, dir_index=dir_index, generation=generation, alloced=alloced, nonce=nonce )
    
    if idx.nonce == nonce:
       # created.
       if alloced:
          logging.info("Directory /%s/%s: allocated index slot for /%s/%s at %s" % (volume_id, parent_id, volume_id, file_id, dir_index))
       else:
          logging.info("Directory /%s/%s: freed index slot at %s" % (volume_id, parent_id, dir_index))
       
       # need to create an entry index node as well.
       entry_key_name = MSEntryEntDirIndex.make_key_name( volume_id, file_id )
       entry_key = storagetypes.make_key( MSEntryEntDirIndex, entry_key_name )
       entry_idx = MSEntryEntDirIndex( key=entry_key, volume_id=volume_id, parent_id=parent_id, file_id=file_id, dir_index=dir_index, generation=generation, alloced=alloced, nonce=nonce )
       
       yield entry_idx.put_async()
       
    else:
       
       # already exists.  changing allocation status?
       if idx.alloced != alloced:
          # allocation status needs to be changed
          # want to change allocation status
          rc = yield storagetypes.transaction_async( lambda: cls.__update_index_node_async( volume_id, parent_id, file_id, dir_index, alloced, generation=generation ), xg=True )
          
          if rc == 0:
             result = True 
             
          else:
             logging.error("__update_index_node_async(/%s/%s file_id=%s dir_index=%s alloced=%s) rc = %s" % (volume_id, parent_id, file_id, dir_index, alloced, rc ))
             result = False
       
       else:
          
          if alloced and idx.file_id != file_id:
             # collision on insertion
             logging.error("Directory /%s/%s: collision inserting /%s/%s at %s (occupied by /%s/%s)" % (volume_id, parent_id, volume_id, file_id, dir_index, volume_id, idx.file_id))
             result = False
             
          else:
             # created/set correctly
             result = True
    
    storagetypes.concurrent_return( result )
Ejemplo n.º 3
0
      def swap( free_file_id ):
         
         rc, alloced_idx, free_idx_file_id = yield storagetypes.transaction_async( lambda: do_swap( free_file_id ), xg=True )

         if rc < 0:
            storagetypes.concurrent_return( rc )
         
         old_dir_index = None
         
         if free_file_id is None:
            free_file_id = free_idx_file_id 
            
         if free_file_id is not None:
            # blow away the newly-freed index node
            old_entry_idx_key_name = MSEntryEntDirIndex.make_key_name( volume_id, free_file_id )
            old_entry_idx_key = storagetypes.make_key( MSEntryEntDirIndex, old_entry_idx_key_name )
            
            yield old_entry_idx_key.delete_async()
            
            storagetypes.memcache.delete( old_entry_idx_key_name )
         
            old_dir_index = alloced_idx.dir_index
         
         storagetypes.concurrent_return( old_dir_index )