Example #1
0
        private static void ScanForExistingSourceBlocksFast(LocalRestoreDatabase database, Options options, byte[] blockbuffer, System.Security.Cryptography.HashAlgorithm hasher, RestoreResults result)
        {
            // Fill BLOCKS with data from known local source files
            using (var blockmarker = database.CreateBlockMarker())
            {
                var updateCount = 0L;
            	foreach(var entry in database.GetFilesAndSourceBlocksFast())
            	{
                    var targetpath = entry.TargetPath;
                    var targetfileid = entry.TargetFileID;
                    var sourcepath = entry.SourcePath;
                    var patched = false;
                    
                	try
                	{
        				if (m_systemIO.FileExists(sourcepath))
        				{
	    					var folderpath = m_systemIO.PathGetDirectoryName(targetpath);
	    					if (!options.Dryrun && !m_systemIO.DirectoryExists(folderpath))
	    					{
	                            result.AddWarning(string.Format("Creating missing folder {0} for  file {1}", folderpath, targetpath), null);
	    						m_systemIO.DirectoryCreate(folderpath);
	    					}
        				
	                		using(var targetstream = options.Dryrun ? null : m_systemIO.FileCreate(targetpath))
	                		{
	                			try
	                			{
		                    		using(var sourcestream = m_systemIO.FileOpenRead(sourcepath))
		                    		{
		    			                foreach(var block in entry.Blocks)
		    			                {
                                            if (result.TaskControlRendevouz() == TaskControlState.Stop)
                                                return;
                                            
			    			                if (sourcestream.Length > block.Offset)
				                    		{
				                    			sourcestream.Position = block.Offset;
				                    			
		                                        var size = sourcestream.Read(blockbuffer, 0, blockbuffer.Length);
		                                        if (size == block.Size)
		                                        {
		                                            var key = Convert.ToBase64String(hasher.ComputeHash(blockbuffer, 0, size));
		                                            if (key == block.Hash)
		                                            {
                                                        patched = true;
						                            	if (!options.Dryrun)
					                            		{
					                            			targetstream.Position = block.Offset;
		                                                    targetstream.Write(blockbuffer, 0, size);
		                                                }
		                                                    
		                                                blockmarker.SetBlockRestored(targetfileid, block.Index, key, block.Size);
		                                            }
		                                        }	                    		
											}
										}
									}
	                			}
	                			catch (Exception ex)
	                			{
	                                result.AddWarning(string.Format("Failed to patch file: \"{0}\" with data from local file \"{1}\", message: {2}", targetpath, sourcepath, ex.Message), ex);
                                    if (ex is System.Threading.ThreadAbortException)
                                        throw;
	                			}
	                		}
                            
                            if (updateCount++ % 20 == 0)
                            {
                                blockmarker.UpdateProcessed(result.OperationProgressUpdater);
                                if (result.TaskControlRendevouz() == TaskControlState.Stop)
                                    return;
                            }
                            
	                	}
                        else
                        {
                            result.AddVerboseMessage("Local source file not found: {0}", sourcepath);
                        }
	 				}
                    catch (Exception ex)
                    {
                        result.AddWarning(string.Format("Failed to patch file: \"{0}\" with local data, message: {1}", targetpath, ex.Message), ex);
                        if (ex is System.Threading.ThreadAbortException)
                            throw;
                    }
                    
                    if (patched)
                        result.AddVerboseMessage("Target file is patched with some local data: {0}", targetpath);
                    else
                        result.AddVerboseMessage("Target file is not patched any local data: {0}", targetpath);
                    
                    if (patched && options.Dryrun)
                    	result.AddDryrunMessage(string.Format("Would patch file with local data: {0}", targetpath));
            	}
            	
                blockmarker.UpdateProcessed(result.OperationProgressUpdater);
            	blockmarker.Commit(result);
            }
        }