You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							98 lines
						
					
					
						
							2.0 KiB
						
					
					
				
			
		
		
		
			
			
			
		
		
	
	
							98 lines
						
					
					
						
							2.0 KiB
						
					
					
				
								package erasure_coding
							 | 
						|
								
							 | 
						|
								import (
							 | 
						|
									"fmt"
							 | 
						|
									"io"
							 | 
						|
									"os"
							 | 
						|
								
							 | 
						|
									"github.com/seaweedfs/seaweedfs/weed/storage/types"
							 | 
						|
									"github.com/seaweedfs/seaweedfs/weed/util"
							 | 
						|
								)
							 | 
						|
								
							 | 
						|
								var (
							 | 
						|
									MarkNeedleDeleted = func(file *os.File, offset int64) error {
							 | 
						|
										b := make([]byte, types.SizeSize)
							 | 
						|
										types.SizeToBytes(b, types.TombstoneFileSize)
							 | 
						|
										n, err := file.WriteAt(b, offset+types.NeedleIdSize+types.OffsetSize)
							 | 
						|
										if err != nil {
							 | 
						|
											return fmt.Errorf("sorted needle write error: %w", err)
							 | 
						|
										}
							 | 
						|
										if n != types.SizeSize {
							 | 
						|
											return fmt.Errorf("sorted needle written %d bytes, expecting %d", n, types.SizeSize)
							 | 
						|
										}
							 | 
						|
										return nil
							 | 
						|
									}
							 | 
						|
								)
							 | 
						|
								
							 | 
						|
								func (ev *EcVolume) DeleteNeedleFromEcx(needleId types.NeedleId) (err error) {
							 | 
						|
								
							 | 
						|
									_, _, err = SearchNeedleFromSortedIndex(ev.ecxFile, ev.ecxFileSize, needleId, MarkNeedleDeleted)
							 | 
						|
								
							 | 
						|
									if err != nil {
							 | 
						|
										if err == NotFoundError {
							 | 
						|
											return nil
							 | 
						|
										}
							 | 
						|
										return err
							 | 
						|
									}
							 | 
						|
								
							 | 
						|
									b := make([]byte, types.NeedleIdSize)
							 | 
						|
									types.NeedleIdToBytes(b, needleId)
							 | 
						|
								
							 | 
						|
									ev.ecjFileAccessLock.Lock()
							 | 
						|
								
							 | 
						|
									ev.ecjFile.Seek(0, io.SeekEnd)
							 | 
						|
									ev.ecjFile.Write(b)
							 | 
						|
								
							 | 
						|
									ev.ecjFileAccessLock.Unlock()
							 | 
						|
								
							 | 
						|
									return
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								func RebuildEcxFile(baseFileName string) error {
							 | 
						|
								
							 | 
						|
									if !util.FileExists(baseFileName + ".ecj") {
							 | 
						|
										return nil
							 | 
						|
									}
							 | 
						|
								
							 | 
						|
									ecxFile, err := os.OpenFile(baseFileName+".ecx", os.O_RDWR, 0644)
							 | 
						|
									if err != nil {
							 | 
						|
										return fmt.Errorf("rebuild: failed to open ecx file: %w", err)
							 | 
						|
									}
							 | 
						|
									defer ecxFile.Close()
							 | 
						|
								
							 | 
						|
									fstat, err := ecxFile.Stat()
							 | 
						|
									if err != nil {
							 | 
						|
										return err
							 | 
						|
									}
							 | 
						|
								
							 | 
						|
									ecxFileSize := fstat.Size()
							 | 
						|
								
							 | 
						|
									ecjFile, err := os.OpenFile(baseFileName+".ecj", os.O_RDWR, 0644)
							 | 
						|
									if err != nil {
							 | 
						|
										return fmt.Errorf("rebuild: failed to open ecj file: %w", err)
							 | 
						|
									}
							 | 
						|
								
							 | 
						|
									buf := make([]byte, types.NeedleIdSize)
							 | 
						|
									for {
							 | 
						|
										n, _ := ecjFile.Read(buf)
							 | 
						|
										if n != types.NeedleIdSize {
							 | 
						|
											break
							 | 
						|
										}
							 | 
						|
								
							 | 
						|
										needleId := types.BytesToNeedleId(buf)
							 | 
						|
								
							 | 
						|
										_, _, err = SearchNeedleFromSortedIndex(ecxFile, ecxFileSize, needleId, MarkNeedleDeleted)
							 | 
						|
								
							 | 
						|
										if err != nil && err != NotFoundError {
							 | 
						|
											ecxFile.Close()
							 | 
						|
											return err
							 | 
						|
										}
							 | 
						|
								
							 | 
						|
									}
							 | 
						|
								
							 | 
						|
									ecxFile.Close()
							 | 
						|
								
							 | 
						|
									os.Remove(baseFileName + ".ecj")
							 | 
						|
								
							 | 
						|
									return nil
							 | 
						|
								}
							 |