mirror of
				https://bitbucket.org/s_l_teichmann/mtsatellite
				synced 2025-10-26 13:55:35 +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 { | func (sp *SpanPool) Insert(s *Span, pos, value int32) *Span { | ||||||
|  |  | ||||||
|  | 	// No head -> create. | ||||||
| 	if s == nil { | 	if s == nil { | ||||||
| 		s = sp.Alloc() | 		s = sp.Alloc() | ||||||
| 		s.From = pos | 		s.From = pos | ||||||
| @@ -71,10 +72,10 @@ func (sp *SpanPool) Insert(s *Span, pos, value int32) *Span { | |||||||
| 	if pos < s.From { | 	if pos < s.From { | ||||||
| 		// Same value and directly neighbored -> extend head. | 		// Same value and directly neighbored -> extend head. | ||||||
| 		if value == s.Value && pos == s.From-1 { | 		if value == s.Value && pos == s.From-1 { | ||||||
| 			s.From-- | 			s.From = pos | ||||||
| 			return s | 			return s | ||||||
| 		} | 		} | ||||||
| 		// Disjunct -> create new. | 		// Disjunct -> create new head. | ||||||
| 		prev := sp.Alloc() | 		prev := sp.Alloc() | ||||||
| 		prev.From = pos | 		prev.From = pos | ||||||
| 		prev.To = pos | 		prev.To = pos | ||||||
| @@ -83,7 +84,103 @@ func (sp *SpanPool) Insert(s *Span, pos, value int32) *Span { | |||||||
| 		return prev | 		return prev | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// TODO: Implement the more complicated cases. | 	head := s | ||||||
|  | 	for prev := s; s != nil; s = s.Next { | ||||||
| 	return nil | 		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