github.com/cyverse/go-irodsclient@v0.13.2/fs/fs_cache.go (about)

     1  package fs
     2  
     3  import (
     4  	"github.com/cyverse/go-irodsclient/irods/util"
     5  )
     6  
     7  // ClearCache clears all file system caches
     8  func (fs *FileSystem) ClearCache() {
     9  	fs.cache.ClearACLsCache()
    10  	fs.cache.ClearMetadataCache()
    11  	fs.cache.ClearEntryCache()
    12  	fs.cache.ClearNegativeEntryCache()
    13  	fs.cache.ClearDirCache()
    14  }
    15  
    16  // AddCacheEventHandler adds cache event handler
    17  func (fs *FileSystem) AddCacheEventHandler(handler FilesystemCacheEventHandler) string {
    18  	return fs.cacheEventHandlerMap.AddEventHandler(handler)
    19  }
    20  
    21  // RemoveCacheEventHandler removes cache event handler
    22  func (fs *FileSystem) RemoveCacheEventHandler(handlerID string) {
    23  	fs.cacheEventHandlerMap.RemoveEventHandler(handlerID)
    24  }
    25  
    26  // invalidateCacheForRemoveInternal invalidates cache for removal of the given file/dir
    27  func (fs *FileSystem) invalidateCacheForRemoveInternal(path string, recurse bool) {
    28  	var entry *Entry
    29  	if recurse {
    30  		entry = fs.cache.GetEntryCache(path)
    31  	}
    32  
    33  	fs.cache.RemoveEntryCache(path)
    34  	fs.cache.RemoveACLsCache(path)
    35  	fs.cache.RemoveMetadataCache(path)
    36  
    37  	if recurse && entry != nil {
    38  		if entry.Type == DirectoryEntry {
    39  			dirEntries := fs.cache.GetDirCache(path)
    40  			for _, dirEntry := range dirEntries {
    41  				// do it recursively
    42  				fs.invalidateCacheForRemoveInternal(dirEntry, recurse)
    43  			}
    44  		}
    45  	}
    46  
    47  	// remove dircache and dir acl cache even if it is a file or unknown, no harm.
    48  	fs.cache.RemoveDirCache(path)
    49  }
    50  
    51  // invalidateCacheForDirCreate invalidates cache for creation of the given dir
    52  func (fs *FileSystem) invalidateCacheForDirCreate(path string) {
    53  	fs.cache.RemoveNegativeEntryCache(path)
    54  
    55  	// parent dir's entry also changes
    56  	fs.cache.RemoveParentDirCache(path)
    57  	// parent dir's dir entry also changes
    58  	parentPath := util.GetIRODSPathDirname(path)
    59  	parentDirEntries := fs.cache.GetDirCache(parentPath)
    60  	if parentDirEntries != nil {
    61  		parentDirEntries = append(parentDirEntries, path)
    62  		fs.cache.AddDirCache(parentPath, parentDirEntries)
    63  	}
    64  
    65  	// send event
    66  	fs.cacheEventHandlerMap.SendDirCreateEvent(path)
    67  }
    68  
    69  // invalidateCacheForFileUpdate invalidates cache for update on the given file
    70  func (fs *FileSystem) invalidateCacheForFileUpdate(path string) {
    71  	fs.cache.RemoveNegativeEntryCache(path)
    72  	fs.cache.RemoveEntryCache(path)
    73  
    74  	// modification doesn't affect to parent dir's modified time
    75  
    76  	// send event
    77  	fs.cacheEventHandlerMap.SendFileUpdateEvent(path)
    78  }
    79  
    80  // invalidateCacheForDirRemove invalidates cache for removal of the given dir
    81  func (fs *FileSystem) invalidateCacheForDirRemove(path string, recurse bool) {
    82  	var entry *Entry
    83  	if recurse {
    84  		entry = fs.cache.GetEntryCache(path)
    85  	}
    86  
    87  	// we need to expunge all negatie entry caches under irodsDestPath
    88  	// since all sub-directories/files are also moved
    89  	fs.cache.RemoveAllNegativeEntryCacheForPath(path)
    90  
    91  	fs.cache.AddNegativeEntryCache(path)
    92  	fs.cache.RemoveEntryCache(path)
    93  	fs.cache.RemoveMetadataCache(path)
    94  
    95  	if recurse && entry != nil {
    96  		if entry.Type == DirectoryEntry {
    97  			dirEntries := fs.cache.GetDirCache(path)
    98  			for _, dirEntry := range dirEntries {
    99  				// do it recursively
   100  				fs.invalidateCacheForRemoveInternal(dirEntry, recurse)
   101  			}
   102  		}
   103  	}
   104  
   105  	fs.cache.RemoveDirCache(path)
   106  	fs.cache.RemoveACLsCache(path)
   107  
   108  	// parent dir's entry also changes
   109  	fs.cache.RemoveParentDirCache(path)
   110  	// parent dir's dir entry also changes
   111  	parentPath := util.GetIRODSPathDirname(path)
   112  	parentDirEntries := fs.cache.GetDirCache(parentPath)
   113  	if parentDirEntries != nil {
   114  		newParentDirEntries := []string{}
   115  		for _, dirEntry := range parentDirEntries {
   116  			if dirEntry != path {
   117  				newParentDirEntries = append(newParentDirEntries, dirEntry)
   118  			}
   119  		}
   120  		fs.cache.AddDirCache(parentPath, newParentDirEntries)
   121  	}
   122  
   123  	// send event
   124  	fs.cacheEventHandlerMap.SendDirRemoveEvent(path)
   125  }
   126  
   127  // invalidateCacheForDirExtract invalidates cache for bundle extraction of the given dir
   128  // this occurs when extracting bundle files
   129  func (fs *FileSystem) invalidateCacheForDirExtract(path string) {
   130  	entry := fs.cache.GetEntryCache(path)
   131  
   132  	// we need to expunge all negatie entry caches under irodsDestPath
   133  	// since it also creates sub-directories/files
   134  	fs.cache.RemoveAllNegativeEntryCacheForPath(path)
   135  
   136  	fs.cache.RemoveEntryCache(path)
   137  	fs.cache.RemoveMetadataCache(path)
   138  
   139  	if entry != nil {
   140  		if entry.Type == DirectoryEntry {
   141  			dirEntries := fs.cache.GetDirCache(path)
   142  			for _, dirEntry := range dirEntries {
   143  				// do it recursively
   144  				fs.invalidateCacheForRemoveInternal(dirEntry, true)
   145  			}
   146  		}
   147  	}
   148  
   149  	fs.cache.RemoveDirCache(path)
   150  	fs.cache.RemoveACLsCache(path)
   151  
   152  	// parent dir's entry also changes
   153  	fs.cache.RemoveParentDirCache(path)
   154  	// parent dir's dir entry also changes
   155  	parentPath := util.GetIRODSPathDirname(path)
   156  	parentDirEntries := fs.cache.GetDirCache(parentPath)
   157  	if parentDirEntries != nil {
   158  		exist := false
   159  		for _, parentDirEntry := range parentDirEntries {
   160  			if parentDirEntry == path {
   161  				exist = true
   162  				break
   163  			}
   164  		}
   165  
   166  		if !exist {
   167  			parentDirEntries = append(parentDirEntries, path)
   168  		}
   169  
   170  		fs.cache.AddDirCache(parentPath, parentDirEntries)
   171  	}
   172  
   173  	// send event
   174  	fs.cacheEventHandlerMap.SendDirCreateEvent(path)
   175  }
   176  
   177  // invalidateCacheForFileCreate invalidates cache for creation of the given file
   178  func (fs *FileSystem) invalidateCacheForFileCreate(path string) {
   179  	fs.cache.RemoveNegativeEntryCache(path)
   180  
   181  	// parent dir's entry also changes
   182  	fs.cache.RemoveParentDirCache(path)
   183  	// parent dir's dir entry also changes
   184  	parentPath := util.GetIRODSPathDirname(path)
   185  	parentDirEntries := fs.cache.GetDirCache(parentPath)
   186  	if parentDirEntries != nil {
   187  		parentDirEntries = append(parentDirEntries, path)
   188  		fs.cache.AddDirCache(parentPath, parentDirEntries)
   189  	}
   190  
   191  	// send event
   192  	fs.cacheEventHandlerMap.SendFileCreateEvent(path)
   193  }
   194  
   195  // invalidateCacheForFileRemove invalidates cache for removal of the given file
   196  func (fs *FileSystem) invalidateCacheForFileRemove(path string) {
   197  	fs.cache.AddNegativeEntryCache(path)
   198  	fs.cache.RemoveEntryCache(path)
   199  	fs.cache.RemoveACLsCache(path)
   200  	fs.cache.RemoveMetadataCache(path)
   201  
   202  	// parent dir's entry also changes
   203  	fs.cache.RemoveParentDirCache(path)
   204  	// parent dir's dir entry also changes
   205  	parentPath := util.GetIRODSPathDirname(path)
   206  	parentDirEntries := fs.cache.GetDirCache(parentPath)
   207  	if parentDirEntries != nil {
   208  		newParentDirEntries := []string{}
   209  		for _, dirEntry := range parentDirEntries {
   210  			if dirEntry != path {
   211  				newParentDirEntries = append(newParentDirEntries, dirEntry)
   212  			}
   213  		}
   214  		fs.cache.AddDirCache(parentPath, newParentDirEntries)
   215  	}
   216  
   217  	// send event
   218  	fs.cacheEventHandlerMap.SendFileRemoveEvent(path)
   219  }