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.
		
		
		
		
		
			
		
			
				
					
					
						
							116 lines
						
					
					
						
							2.6 KiB
						
					
					
				
			
		
		
		
			
			
			
		
		
	
	
							116 lines
						
					
					
						
							2.6 KiB
						
					
					
				| package filer | |
| 
 | |
| import ( | |
| 	"github.com/chrislusf/seaweedfs/weed/pb/filer_pb" | |
| 	"golang.org/x/exp/slices" | |
| ) | |
| 
 | |
| func readResolvedChunks(chunks []*filer_pb.FileChunk) (visibles []VisibleInterval) { | |
| 
 | |
| 	var points []*Point | |
| 	for _, chunk := range chunks { | |
| 		points = append(points, &Point{ | |
| 			x:       chunk.Offset, | |
| 			ts:      chunk.Mtime, | |
| 			chunk:   chunk, | |
| 			isStart: true, | |
| 		}) | |
| 		points = append(points, &Point{ | |
| 			x:       chunk.Offset + int64(chunk.Size), | |
| 			ts:      chunk.Mtime, | |
| 			chunk:   chunk, | |
| 			isStart: false, | |
| 		}) | |
| 	} | |
| 	slices.SortFunc(points, func(a, b *Point) bool { | |
| 		if a.x != b.x { | |
| 			return a.x < b.x | |
| 		} | |
| 		if a.ts != b.ts { | |
| 			return a.ts < b.ts | |
| 		} | |
| 		return !a.isStart | |
| 	}) | |
| 
 | |
| 	var prevX int64 | |
| 	var queue []*Point | |
| 	for _, point := range points { | |
| 		if point.isStart { | |
| 			if len(queue) > 0 { | |
| 				lastIndex := len(queue) - 1 | |
| 				lastPoint := queue[lastIndex] | |
| 				if point.x != prevX && lastPoint.ts < point.ts { | |
| 					visibles = addToVisibles(visibles, prevX, lastPoint, point) | |
| 					prevX = point.x | |
| 				} | |
| 			} | |
| 			// insert into queue | |
| 			for i := len(queue); i >= 0; i-- { | |
| 				if i == 0 || queue[i-1].ts <= point.ts { | |
| 					if i == len(queue) { | |
| 						prevX = point.x | |
| 					} | |
| 					queue = addToQueue(queue, i, point) | |
| 					break | |
| 				} | |
| 			} | |
| 		} else { | |
| 			lastIndex := len(queue) - 1 | |
| 			index := lastIndex | |
| 			var startPoint *Point | |
| 			for ; index >= 0; index-- { | |
| 				startPoint = queue[index] | |
| 				if startPoint.ts == point.ts { | |
| 					queue = removeFromQueue(queue, index) | |
| 					break | |
| 				} | |
| 			} | |
| 			if index == lastIndex && startPoint != nil { | |
| 				visibles = addToVisibles(visibles, prevX, startPoint, point) | |
| 				prevX = point.x | |
| 			} | |
| 		} | |
| 	} | |
| 
 | |
| 	return | |
| } | |
| 
 | |
| func removeFromQueue(queue []*Point, index int) []*Point { | |
| 	for i := index; i < len(queue)-1; i++ { | |
| 		queue[i] = queue[i+1] | |
| 	} | |
| 	queue = queue[:len(queue)-1] | |
| 	return queue | |
| } | |
| 
 | |
| func addToQueue(queue []*Point, index int, point *Point) []*Point { | |
| 	queue = append(queue, point) | |
| 	for i := len(queue) - 1; i > index; i-- { | |
| 		queue[i], queue[i-1] = queue[i-1], queue[i] | |
| 	} | |
| 	return queue | |
| } | |
| 
 | |
| func addToVisibles(visibles []VisibleInterval, prevX int64, startPoint *Point, point *Point) []VisibleInterval { | |
| 	if prevX < point.x { | |
| 		chunk := startPoint.chunk | |
| 		visibles = append(visibles, VisibleInterval{ | |
| 			start:        prevX, | |
| 			stop:         point.x, | |
| 			fileId:       chunk.GetFileIdString(), | |
| 			modifiedTime: chunk.Mtime, | |
| 			chunkOffset:  prevX - chunk.Offset, | |
| 			chunkSize:    chunk.Size, | |
| 			cipherKey:    chunk.CipherKey, | |
| 			isGzipped:    chunk.IsCompressed, | |
| 		}) | |
| 	} | |
| 	return visibles | |
| } | |
| 
 | |
| type Point struct { | |
| 	x       int64 | |
| 	ts      int64 | |
| 	chunk   *filer_pb.FileChunk | |
| 	isStart bool | |
| }
 |