Deep-clone source metadata during chunk materialization
This commit is contained in:
@@ -162,7 +162,10 @@ func MaterializeChunkPlan(doc *SourceDocument, plan ChunkPlan) ([]Chunk, error)
|
||||
for index, chunkRange := range plan.Ranges {
|
||||
start, _ := UnitIndex(doc, chunkRange.StartUnitID)
|
||||
end, _ := UnitIndex(doc, chunkRange.EndUnitID)
|
||||
units := cloneSourceUnits(doc.Units[start : end+1])
|
||||
units, err := cloneSourceUnits(doc.Units[start : end+1])
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("clone chunk plan range[%d] units: %w", index, err)
|
||||
}
|
||||
content, err := json.Marshal(struct {
|
||||
Units []SourceUnit `json:"units"`
|
||||
}{Units: units})
|
||||
@@ -189,52 +192,18 @@ func MaterializeChunkPlan(doc *SourceDocument, plan ChunkPlan) ([]Chunk, error)
|
||||
return chunks, nil
|
||||
}
|
||||
|
||||
func cloneSourceUnits(units []SourceUnit) []SourceUnit {
|
||||
func cloneSourceUnits(units []SourceUnit) ([]SourceUnit, error) {
|
||||
if len(units) == 0 {
|
||||
return nil
|
||||
return nil, nil
|
||||
}
|
||||
cloned := make([]SourceUnit, len(units))
|
||||
for i, unit := range units {
|
||||
cloned[i] = unit
|
||||
cloned[i].Metadata = cloneJSONMap(unit.Metadata)
|
||||
}
|
||||
return cloned
|
||||
}
|
||||
|
||||
func cloneJSONMap(values map[string]any) map[string]any {
|
||||
if len(values) == 0 {
|
||||
return nil
|
||||
}
|
||||
cloned := make(map[string]any, len(values))
|
||||
for key, value := range values {
|
||||
cloned[key] = cloneJSONValue(value)
|
||||
}
|
||||
return cloned
|
||||
}
|
||||
|
||||
func cloneJSONValue(value any) any {
|
||||
switch typed := value.(type) {
|
||||
case map[string]any:
|
||||
return cloneJSONMap(typed)
|
||||
case []any:
|
||||
cloned := make([]any, len(typed))
|
||||
for i := range typed {
|
||||
cloned[i] = cloneJSONValue(typed[i])
|
||||
metadata, err := CloneMetadata(unit.Metadata)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("source unit[%d] metadata: %w", i, err)
|
||||
}
|
||||
return cloned
|
||||
case json.RawMessage:
|
||||
return append(json.RawMessage(nil), typed...)
|
||||
case []byte:
|
||||
return append([]byte(nil), typed...)
|
||||
case []string:
|
||||
return append([]string(nil), typed...)
|
||||
case map[string]string:
|
||||
cloned := make(map[string]string, len(typed))
|
||||
for key, item := range typed {
|
||||
cloned[key] = item
|
||||
}
|
||||
return cloned
|
||||
default:
|
||||
return value
|
||||
cloned[i].Metadata = metadata
|
||||
}
|
||||
return cloned, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user