temp for tree extraction

This commit is contained in:
2025-10-15 19:19:52 -04:00
commit ffa434630f
51 changed files with 9036 additions and 0 deletions

173
internal/models/oplog.go Normal file
View File

@ -0,0 +1,173 @@
package models
import (
"bytes"
"encoding/binary"
"encoding/json"
"fmt"
"io"
"time"
)
// OplogEntry represents a single entry in the action log
type OplogEntry struct {
// ID is a monotonically increasing entry ID
ID uint64
// Timestamp when the operation was performed
Timestamp time.Time
// Operation type (e.g., "save", "switch", "new", "sync")
Operation string
// Description of the operation
Description string
// StateBefore captures the state before the operation
StateBefore *RepositoryState
// StateAfter captures the state after the operation
StateAfter *RepositoryState
// Metadata contains operation-specific data
Metadata map[string]string
}
// RepositoryState captures the state of the repository at a point in time
type RepositoryState struct {
// Refs maps reference names to their SHA-1 hashes
Refs map[string]string
// CurrentWorkstream is the active workstream name
CurrentWorkstream string
// WorkingTreeHash is the hash of the current working tree snapshot
WorkingTreeHash string
// IndexHash is the hash of the staging area
IndexHash string
}
// Serialize converts an OplogEntry to binary format
func (e *OplogEntry) Serialize() ([]byte, error) {
buf := new(bytes.Buffer)
// Write entry ID (8 bytes)
if err := binary.Write(buf, binary.LittleEndian, e.ID); err != nil {
return nil, fmt.Errorf("failed to write ID: %w", err)
}
// Write timestamp (8 bytes, Unix nano)
timestamp := e.Timestamp.UnixNano()
if err := binary.Write(buf, binary.LittleEndian, timestamp); err != nil {
return nil, fmt.Errorf("failed to write timestamp: %w", err)
}
// Serialize the rest as JSON for flexibility
payload := struct {
Operation string `json:"operation"`
Description string `json:"description"`
StateBefore *RepositoryState `json:"state_before"`
StateAfter *RepositoryState `json:"state_after"`
Metadata map[string]string `json:"metadata"`
}{
Operation: e.Operation,
Description: e.Description,
StateBefore: e.StateBefore,
StateAfter: e.StateAfter,
Metadata: e.Metadata,
}
jsonData, err := json.Marshal(payload)
if err != nil {
return nil, fmt.Errorf("failed to marshal JSON: %w", err)
}
// Write JSON length (4 bytes)
jsonLen := uint32(len(jsonData))
if err := binary.Write(buf, binary.LittleEndian, jsonLen); err != nil {
return nil, fmt.Errorf("failed to write JSON length: %w", err)
}
// Write JSON data
if _, err := buf.Write(jsonData); err != nil {
return nil, fmt.Errorf("failed to write JSON data: %w", err)
}
return buf.Bytes(), nil
}
// Deserialize converts binary data back to an OplogEntry
func DeserializeOplogEntry(data []byte) (*OplogEntry, error) {
buf := bytes.NewReader(data)
entry := &OplogEntry{}
// Read entry ID (8 bytes)
if err := binary.Read(buf, binary.LittleEndian, &entry.ID); err != nil {
return nil, fmt.Errorf("failed to read ID: %w", err)
}
// Read timestamp (8 bytes)
var timestamp int64
if err := binary.Read(buf, binary.LittleEndian, &timestamp); err != nil {
return nil, fmt.Errorf("failed to read timestamp: %w", err)
}
entry.Timestamp = time.Unix(0, timestamp)
// Read JSON length (4 bytes)
var jsonLen uint32
if err := binary.Read(buf, binary.LittleEndian, &jsonLen); err != nil {
return nil, fmt.Errorf("failed to read JSON length: %w", err)
}
// Read JSON data
jsonData := make([]byte, jsonLen)
if _, err := io.ReadFull(buf, jsonData); err != nil {
return nil, fmt.Errorf("failed to read JSON data: %w", err)
}
// Unmarshal JSON
payload := struct {
Operation string `json:"operation"`
Description string `json:"description"`
StateBefore *RepositoryState `json:"state_before"`
StateAfter *RepositoryState `json:"state_after"`
Metadata map[string]string `json:"metadata"`
}{}
if err := json.Unmarshal(jsonData, &payload); err != nil {
return nil, fmt.Errorf("failed to unmarshal JSON: %w", err)
}
entry.Operation = payload.Operation
entry.Description = payload.Description
entry.StateBefore = payload.StateBefore
entry.StateAfter = payload.StateAfter
entry.Metadata = payload.Metadata
return entry, nil
}
// NewOplogEntry creates a new oplog entry
func NewOplogEntry(id uint64, operation, description string, before, after *RepositoryState) *OplogEntry {
return &OplogEntry{
ID: id,
Timestamp: time.Now(),
Operation: operation,
Description: description,
StateBefore: before,
StateAfter: after,
Metadata: make(map[string]string),
}
}
// NewRepositoryState creates a new repository state snapshot
func NewRepositoryState(refs map[string]string, currentWorkstream, workingTreeHash, indexHash string) *RepositoryState {
return &RepositoryState{
Refs: refs,
CurrentWorkstream: currentWorkstream,
WorkingTreeHash: workingTreeHash,
IndexHash: indexHash,
}
}