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 | |
| }
 |