Пример #1
0
        /// <summary>
        /// Adds the existence state of the path if not present or returns the current cached existence state of the path
        /// </summary>
        /// <remarks>
        /// If flags are provided, those are added to potentially existing flags
        /// </remarks>
        private PathExistence GetOrAddExistence(AbsolutePath path, FileSystemViewMode mode, PathExistence existence, out bool added, bool updateParents = true, FileSystemEntryFlags flags = FileSystemEntryFlags.None)
        {
            PathExistence result       = existence;
            var           originalPath = path;

            while (path.IsValid)
            {
                var getOrAddResult = PathExistenceCache.GetOrAdd(path, FileSystemEntry.Create(mode, existence).SetFlag(flags));
                if (getOrAddResult.IsFound)
                {
                    var currentExistence = getOrAddResult.Item.Value.GetExistence(mode);
                    var currentFlags     = getOrAddResult.Item.Value.Flags;
                    if (currentExistence != null && currentFlags.HasFlag(flags))
                    {
                        if (originalPath != path)
                        {
                            // Parent entry with existence already exists, just return the result
                            added = true;
                            return(result);
                        }
                        else
                        {
                            // Entry with existence already exists, just return the value
                            added = false;
                            return(currentExistence.Value);
                        }
                    }

                    // found entry for the 'path', but it does not contain existence for the specified 'mode'
                    var updateResult = PathExistenceCache.AddOrUpdate(path, (mode, existence),
                                                                      (key, data) => FileSystemEntry.Create(data.mode, data.existence).SetFlag(flags),
                                                                      (key, data, oldValue) => oldValue.TryUpdate(data.mode, data.existence).SetFlag(flags));

                    // the same entry might be updated concurrently; check whether we lost the race, and if we did, stop further processing
                    currentExistence = updateResult.OldItem.Value.GetExistence(mode);
                    currentFlags     = updateResult.OldItem.Value.Flags;
                    if (currentExistence != null && currentFlags.HasFlag(flags))
                    {
                        if (originalPath != path)
                        {
                            // Parent entry with existence already exists, just return the result
                            added = true;
                            return(result);
                        }
                        else
                        {
                            // Entry with existence already exists, just return the value
                            added = false;
                            return(currentExistence.Value);
                        }
                    }
                }

                // Only register parents as directories if path exists AND updateParents=true
                if (existence == PathExistence.Nonexistent || !updateParents)
                {
                    break;
                }

                // Set ancestor paths existence to directory existent for existent paths
                existence = PathExistence.ExistsAsDirectory;
                path      = path.GetParent(PathTable);
            }

            added = true;
            return(result);
        }
Пример #2
0
 /// <summary>
 /// Adds the existence state of the path if not present or returns the current cached existence state of the path
 /// </summary>
 private PathExistence GetOrAddExistence(AbsolutePath path, FileSystemViewMode mode, PathExistence existence, bool updateParents = true, FileSystemEntryFlags flags = FileSystemEntryFlags.None)
 {
     return(GetOrAddExistence(path, mode, existence, out var added, updateParents, flags));
 }