mirror of
				https://bitbucket.org/s_l_teichmann/mtsatellite
				synced 2025-10-31 16:15:27 +01:00 
			
		
		
		
	Complete code of insert into span buffer. Looks complicated and needs testing.
This commit is contained in:
		
							
								
								
									
										107
									
								
								common/spans.go
									
									
									
									
									
								
							
							
						
						
									
										107
									
								
								common/spans.go
									
									
									
									
									
								
							| @@ -59,6 +59,7 @@ func (sp *SpanPool) FreeAll(s *Span) { | ||||
|  | ||||
| func (sp *SpanPool) Insert(s *Span, pos, value int32) *Span { | ||||
|  | ||||
| 	// No head -> create. | ||||
| 	if s == nil { | ||||
| 		s = sp.Alloc() | ||||
| 		s.From = pos | ||||
| @@ -71,10 +72,10 @@ func (sp *SpanPool) Insert(s *Span, pos, value int32) *Span { | ||||
| 	if pos < s.From { | ||||
| 		// Same value and directly neighbored -> extend head. | ||||
| 		if value == s.Value && pos == s.From-1 { | ||||
| 			s.From-- | ||||
| 			s.From = pos | ||||
| 			return s | ||||
| 		} | ||||
| 		// Disjunct -> create new. | ||||
| 		// Disjunct -> create new head. | ||||
| 		prev := sp.Alloc() | ||||
| 		prev.From = pos | ||||
| 		prev.To = pos | ||||
| @@ -83,7 +84,103 @@ func (sp *SpanPool) Insert(s *Span, pos, value int32) *Span { | ||||
| 		return prev | ||||
| 	} | ||||
|  | ||||
| 	// TODO: Implement the more complicated cases. | ||||
|  | ||||
| 	return nil | ||||
| 	head := s | ||||
| 	for prev := s; s != nil; s = s.Next { | ||||
| 		switch { | ||||
| 		case pos < s.From: // before span | ||||
| 			if pos == s.From-1 && value == s.Value { // directly neighbored | ||||
| 				s.From = pos | ||||
| 				// Check if a gap has to be closed. | ||||
| 				if prev.To == s.From-1 && value == prev.Value { | ||||
| 					prev.To = s.To | ||||
| 					prev.Next = s.Next | ||||
| 					sp.Free(s) | ||||
| 					return head | ||||
| 				} | ||||
| 			} | ||||
| 			// Extend prev? | ||||
| 			if prev.To == pos-1 && value == prev.Value { | ||||
| 				prev.To = pos | ||||
| 				return head | ||||
| 			} | ||||
| 			// New between prev and current. | ||||
| 			sn := sp.Alloc() | ||||
| 			sn.From = pos | ||||
| 			sn.To = pos | ||||
| 			sn.Value = value | ||||
| 			sn.Next = s | ||||
| 			prev.Next = sn | ||||
| 			return head | ||||
|  | ||||
| 		case pos > s.To: // after span | ||||
| 			if pos == s.To+1 && value == s.Value { // directly neighbored | ||||
| 				s.To = pos | ||||
| 				// Check if a gap has to be closed | ||||
| 				next := s.Next | ||||
| 				if next != nil { | ||||
| 					if next.From == s.To-1 && value == next.Value { | ||||
| 						s.To = next.To | ||||
| 						s.Next = next.Next | ||||
| 						sp.Free(next) | ||||
| 						return head | ||||
| 					} | ||||
| 					// Extend next? | ||||
| 					if pos == next.From-1 && value == next.Value { | ||||
| 						next.From = pos | ||||
| 						return head | ||||
| 					} | ||||
| 					// Before next -> New between current and next | ||||
| 					if pos < next.From { | ||||
| 						sn := sp.Alloc() | ||||
| 						sn.From = pos | ||||
| 						sn.To = pos | ||||
| 						sn.Value = value | ||||
| 						sn.Next = next | ||||
| 						s.Next = sn | ||||
| 						return head | ||||
| 					} | ||||
| 				} else { // No next -> new at tail | ||||
| 					sn := sp.Alloc() | ||||
| 					sn.From = pos | ||||
| 					sn.To = pos | ||||
| 					sn.Value = value | ||||
| 					sn.Next = nil | ||||
| 					s.Next = sn | ||||
| 					return head | ||||
| 				} | ||||
| 			} else { // Not directly connected and/or values do not match. | ||||
| 				next := s.Next | ||||
| 				if next != nil { | ||||
| 					if pos == next.From-1 && value == next.Value { | ||||
| 						next.From = pos | ||||
| 						return head | ||||
| 					} | ||||
| 					// Before next -> New between current and next | ||||
| 					if pos < next.From { | ||||
| 						sn := sp.Alloc() | ||||
| 						sn.From = pos | ||||
| 						sn.To = pos | ||||
| 						sn.Value = value | ||||
| 						sn.Next = next | ||||
| 						s.Next = sn | ||||
| 						return head | ||||
| 					} | ||||
| 				} else { // No next -> new at tail | ||||
| 					sn := sp.Alloc() | ||||
| 					sn.From = pos | ||||
| 					sn.To = pos | ||||
| 					sn.Value = value | ||||
| 					sn.Next = nil | ||||
| 					s.Next = sn | ||||
| 					return head | ||||
| 				} | ||||
| 			} | ||||
|  | ||||
| 		default: // pos in span -> do not modify. | ||||
| 			return head | ||||
| 		} | ||||
| 		prev = s | ||||
| 	} | ||||
|  | ||||
| 	return head | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user