示例#1
0
 public HashPack(LocalFile file, string path, uint project, string dir)
 {
     File = file;
     Path = path;
     Project = project;
     Dir = dir;
 }
示例#2
0
        public void MergeFile(LocalFile file)
        {
            // if there are any unique files in the merge that don't exist locally, add them

            file.Archived.LockReading(delegate()
            {
                foreach (StorageFile merge in file.Archived)
                {
                    // check if exists
                    bool fileExists = false;

                    Archived.LockReading(delegate()
                    {
                        foreach (StorageFile item in Archived)
                            if (Utilities.MemCompare(item.InternalHash, merge.InternalHash))
                            {
                                fileExists = true;
                                break;
                            }
                    });

                    // add file if doesnt exist
                    if (!fileExists)
                    {
                        bool added = false;
                        LinkedListNode<StorageItem> item = null;

                        Archived.LockReading(delegate()
                        {
                            for (item = Archived.First; item != null; item = item.Next)
                                if (item.Value.Date > merge.Date) // loop until item is no longer the lowest (oldest)
                                {
                                    added = true;

                                    break;
                                }
                        });

                        if (added && item != null)
                        {
                            if (item.Value == Info)
                                Archived.SafeAddAfter(item, merge); // even if newest, the file being moved is the one at top
                            else
                                Archived.SafeAddBefore(item, merge); // put file in right spot
                        }
                        else
                            Archived.SafeAddLast(merge); // oldest, at end

                    }
                }
            });
        }
示例#3
0
        public void ReadyChange(LocalFile file, StorageFile newInfo)
        {
            Modified = true;
            PeriodicSave = true;

            file.Modify(Core.TimeNow, newInfo);
        }
示例#4
0
        public void ReadyChange(LocalFile file)
        {
            Modified = true;
            PeriodicSave = true;

            file.Modify(Core.TimeNow, file.Info.Clone());
        }
示例#5
0
        public void MoveFile(string sourcePath, string destPath, List<string> errors)
        {
            // get source folder
            string name = Path.GetFileName(sourcePath);

            sourcePath = Utilities.StripOneLevel(sourcePath);

            LocalFolder sourceFolder = GetLocalFolder(sourcePath);
            LocalFolder destFolder = GetLocalFolder(destPath);

            if (sourceFolder == null || destFolder == null || sourceFolder == destFolder)
                return;

            // get source file
            LocalFile sourceFile = sourceFolder.GetFile(name);

            if (sourceFile == null)
                return;

            // if name exists with diff uid, return error
            bool exists = false;

            destFolder.Files.LockReading(delegate()
            {
                foreach (LocalFile check in destFolder.Files.Values)
                    if (check.Info.UID != sourceFile.Info.UID &&
                        String.Compare(check.Info.Name, sourceFile.Info.Name, true) == 0)
                    {
                        errors.Add("File with same name exists at " + destPath);
                        exists = true;
                    }
            });

            if (exists)
                return;

            // if uid exists in destination, merge histories with diff hashes
            WorkingChange destChange = WorkingChange.Created;
            WorkingChange sourceChange = WorkingChange.Updated;

            LocalFile mergeFile = null;

            if (destFolder.Files.SafeTryGetValue(sourceFile.Info.UID, out mergeFile))
            {
                sourceFile.MergeFile(mergeFile);
                destFolder.Files.SafeAdd(sourceFile.Info.UID, sourceFile);
                destChange = WorkingChange.Updated;
            }
            else
                destFolder.AddFile(sourceFile);

            // make note file was moved at source in destination
            LocalFile ghost = new LocalFile(sourceFile.Info.Clone()); // do before modified/new date set
            ReadyChange(sourceFile);
            sourceFile.Info.Note = "Moved from " + (sourcePath == "" ? Path.DirectorySeparatorChar.ToString() : sourcePath);

            sourceFolder.Files.SafeRemove(sourceFile.Info.UID);

            // only leave a ghost if this file has a committed history
            if (sourceFile.Archived.SafeCount > 1 || !sourceFile.Info.IsFlagged(StorageFlags.Modified))
            {
                ghost.Archived.SafeAddFirst(ghost.Info);
                sourceFolder.AddFile(ghost);
                ReadyChange(ghost);
                ghost.Info.Note = "Moved to " + (destPath == "" ? Path.DirectorySeparatorChar.ToString() : destPath);
                ghost.Info.SetFlag(StorageFlags.Archived);
            }
            else
                sourceChange = WorkingChange.Removed;

            // move actual file if unlocked on disk, create new folder if need be
            if (File.Exists(RootPath + sourcePath + Path.DirectorySeparatorChar + name))
            {
                Directory.CreateDirectory(RootPath + destPath);

                // exceptions handled by caller
                File.Move(  RootPath + sourcePath + Path.DirectorySeparatorChar + name,
                            RootPath + destPath + Path.DirectorySeparatorChar + name);
            }

            // file created at destination, updated at source
            Storages.CallFileUpdate(ProjectID, destPath, sourceFile.Info.UID,  destChange);
            Storages.CallFileUpdate(ProjectID, sourcePath, sourceFile.Info.UID, sourceChange);
        }
示例#6
0
        void ReplaceFile(LocalFile file, StorageFile replacement, string dir, bool setModified, List<LockError> errors)
        {
            // this will lock file if it is unlocked
            bool unlocked = Storages.IsFileUnlocked(Core.UserID, ProjectID, dir, file.Info, false);

            Storages.LockFile(Core.UserID, ProjectID, dir, file.Info, false);

            if (setModified)
                ReadyChange(file, replacement);
            else
            {
                file.Info = replacement;
                file.Archived.SafeAddFirst(replacement);
            }

            if (unlocked)
                Storages.UnlockFile(Core.UserID, ProjectID, dir, file.Info, false, errors);
        }
示例#7
0
        public LocalFile AddFileInfo(StorageFile info)
        {
            LocalFile file = null;

            if (!Files.SafeTryGetValue(info.UID, out file))
            {
                file = new LocalFile(info);
                Files.SafeAdd(info.UID, file);
            }

            if(info.IntegratedID != 0)
                file.Integrated.SafeAdd(info.IntegratedID, info);
            else
                file.Archived.SafeAddLast(info);

            return file;
        }
示例#8
0
        private LocalFile CreateNewFile(string name)
        {
            StorageFile info = new StorageFile();
            LocalFile file = new LocalFile(info);

            info.UID = Utilities.StrongRandUInt64(Core.StrongRndGen);
            info.Name = name;
            info.Date = Core.TimeNow.ToUniversalTime();
            info.Revs = 5;

            file.Archived.SafeAddFirst(info);

            return file;
        }
示例#9
0
        public void AddFile(LocalFile file)
        {
            ulong uid = file.Info.UID;

            Debug.Assert(!Files.SafeContainsKey(uid));

            Files.SafeAdd(uid, file);
        }
示例#10
0
        private bool AutoIntegrate(LocalFile file, string dir, List<LockError> errors)
        {
            // If file/folder not flagged as modified
            if(file.Info.IsFlagged(StorageFlags.Modified))
                return false;

            StorageFile latestFile = file.Info;
            List<StorageFile> inheritIntegrated = new List<StorageFile>();

            ulong directHigher = (InheritIDs.Count >= 2) ? InheritIDs[1] : 0;

            // this process will find higher has integrated my file
            // and highest has integrated his file, and return latest

            // from self to highest
            foreach (ulong id in InheritIDs)
                if (file.HigherChanges.ContainsKey(id))
                    // higherChanges consists of files that are newer than local
                    foreach (StorageFile changeFile in file.HigherChanges[id])
                    {
                        if (changeFile.Date >= latestFile.Date && Storages.ItemDiff(latestFile, changeFile) == StorageActions.None)
                        {
                            latestFile = (StorageFile)file.HigherChanges[id][0]; // first element is newest file

                            if (id != directHigher)
                                break;
                        }

                        if (id == directHigher &&
                            changeFile.IntegratedID != 0 &&
                            Core.Trust.IsAdjacent(changeFile.IntegratedID, ProjectID))
                            inheritIntegrated.Add(changeFile);
                    }

            // if current file/folder is not our own (itemdiff)
            bool save = false;

            if (Storages.ItemDiff(latestFile, file.Info) != StorageActions.None)
            {
                ReplaceFile(file, latestFile, dir , false, errors);

                save = true;
            }

            // merges integration list for nodes adjacent to ourselves
            // works even if higher integrates more files, but doesn't necessarily change the file's hash
            StorageItem prevIntegrated = null;

            foreach (StorageFile inherited in inheritIntegrated)
            {
                file.Integrated.SafeTryGetValue(inherited.IntegratedID, out prevIntegrated);

                if (prevIntegrated == null || inherited.Date > prevIntegrated.Date)
                {
                    file.Integrated.SafeAdd(inherited.IntegratedID, inherited);
                    save = true;
                }
            }

            return save;
        }
示例#11
0
        public void TrackFile(string path, StorageFile track)
        {
            LocalFolder folder = GetLocalFolder(path);

            if (folder == null)
                return;

            // increase references
            OpFile commonFile = null;
            if (Storages.FileMap.SafeTryGetValue(track.HashID, out commonFile))
                commonFile.References++;

            LocalFile file = new LocalFile(track);
            file.Info.SetFlag(StorageFlags.Modified);
            file.Archived.SafeAddFirst(track);

            folder.AddFile(file);

            Modified = true;
            PeriodicSave = true;

            Storages.CallFileUpdate(ProjectID, folder.GetPath(), file.Info.UID, WorkingChange.Created);
        }
示例#12
0
        public void MarkforHash(LocalFile file, string path, uint project, string dir)
        {
            HashPack pack = new HashPack(file, path, project, dir);

            lock (HashFiles.Pending)
                if (HashFiles.Pending.Any(p => ((HashPack)p.Param2).File == file))
                    return;

            file.Info.Size = new FileInfo(path).Length; // set so we can get hash status

            HashFiles.Enqueue(() => HashFile(pack), pack);
        }