Documentation
¶
Overview ¶
Package io defines the I/O pipeline framework for Pulse: Reader/Writer interfaces, schema inference, and job types (ImportJob, ExportJob, ConvertJob).
Format-specific adapters live in sub-packages (csv, tsv).
Index ¶
- Constants
- func CompareOverlayLayer(got, want *types.OverlayLayer) error
- func CompareOverlayLayers(got, want []*types.OverlayLayer) error
- func CompareOverlayPayload(got, want types.OverlayPayload) error
- func CompareOverlayRef(got, want types.OverlayRef) error
- func CompareOverlaySummary(got, want *types.OverlaySummary) error
- func DiscardWriter(w Writer) error
- func ErrStopIteration() error
- func IsNullCell(v any, explicit bool) bool
- func MaxSetElements() int
- func ResolveTransferLevel(level int) (int, error)
- func SetTypeFor(elements int) (encoding.FieldType, bool)
- func WidestSetType() encoding.FieldType
- type CohortSource
- type CohortValidator
- type CohortWriter
- type ConvertJob
- type ConvertReport
- type ConvertSource
- type DedupJob
- type DedupReport
- type DiscardableWriter
- type ExportJob
- type ExportReport
- type GroupCandidate
- type GroupDecl
- type GroupDetection
- type GroupReport
- type ImportJob
- type ImportProjection
- type ImportReport
- type InferOptions
- type InferenceResult
- type InferenceWarning
- type LabelResolver
- type LabelWarning
- type NullAwareReader
- type NullAwareWriter
- type OverlayAwareWriter
- type OverlayWarningEmitter
- type PredictReport
- type Reader
- type ResetReader
- type RowError
- type SchemaAwareReader
- type SchemaAwareWriter
- type SidecarEmitter
- type SourceAwareWriter
- type SourceWarningEmitter
- type TargetWarningEmitter
- type TransferExportJob
- type TransferImportJob
- type TransferReport
- type Writer
Constants ¶
const ( // CandidateVerdictUnmeasured: the candidate outgrew its share of // the detection memory budget before the pass ended; no figures. CandidateVerdictUnmeasured = "unmeasured" // CandidateReasonMemoryBound is the Reason on an unmeasured // candidate. CandidateReasonMemoryBound = "detection_memory_bound" )
Candidate verdicts beyond the gate's own (encoding.GroupVerdict*).
const ( MinTransferLevel = 1 MaxTransferLevel = 22 )
MinTransferLevel and MaxTransferLevel bound the accepted zstd levels. The encoder maps them onto its four speed classes (zstd.EncoderLevelFromZstd): 1-2 fastest, 3-5 default, 6-9 better, 10-22 best.
const ( TransferLayoutSingleFile = "single_file" TransferLayoutShardArchive = "shard_archive" )
Transfer layout names reported on TransferReport.Layout.
const DefaultSetDelimiter = iocore.DefaultSetDelimiter
DefaultSetDelimiter is iocore.DefaultSetDelimiter.
const DefaultTransferLevel = 3
DefaultTransferLevel is the zstd level used when a job leaves Level at zero. Level 3 is zstd's own default and was the level measured during planning.
const EmptySetCell = iocore.EmptySetCell
EmptySetCell is iocore.EmptySetCell.
const TransferCodec = "zstd"
TransferCodec is the one codec the transfer artifact uses.
const TransferExtension = ".zst"
TransferExtension is the conventional suffix appended to a cohort's file name for its transfer artifact.
Variables ¶
This section is empty.
Functions ¶
func CompareOverlayLayer ¶
func CompareOverlayLayer(got, want *types.OverlayLayer) error
CompareOverlayLayer returns nil when the two layers match across all renderer-facing slots (name, kind, scope, ref, payload, summary). Per-shape payload comparison dispatches through CompareOverlayPayload.
func CompareOverlayLayers ¶
func CompareOverlayLayers(got, want []*types.OverlayLayer) error
CompareOverlayLayers returns nil when `got` matches `want` slot-for- slot. Mismatch returns an error describing the first divergence — length, slot index, name / kind / scope, shape, or per-shape payload. Designed for use inside table-driven test bodies; callers wrap the error in t.Errorf for the failure message.
Exported so the per-format integration tests under internal/io/exportoverlay/ share one comparison surface across Arrow / Parquet / Excel / NDJSON round-trips.
func CompareOverlayPayload ¶
func CompareOverlayPayload(got, want types.OverlayPayload) error
CompareOverlayPayload dispatches by shape and compares the populated arm. Absent arms (the non-matching shape's sub-payload nil) are untouched — the OverlayPayload union always populates exactly one arm per the Shape discriminator.
func CompareOverlayRef ¶
func CompareOverlayRef(got, want types.OverlayRef) error
CompareOverlayRef returns nil when the two refs share the same discriminator state. The structural comparison covers the Margin / Population / Stage / Slot arms — extending this helper when new ref arms land follows the additive-only rule (new arms compare nil-vs- nil before recursing into the new fields).
func CompareOverlaySummary ¶
func CompareOverlaySummary(got, want *types.OverlaySummary) error
CompareOverlaySummary returns nil when both summaries match across every populated field. nil-vs-nil counts as match; nil-vs-non-nil is a mismatch.
func ErrStopIteration ¶
func ErrStopIteration() error
ErrStopIteration returns the stop iteration sentinel for use by readers.
func ResolveTransferLevel ¶
ResolveTransferLevel validates level and applies the default.
func SetTypeFor ¶
SetTypeFor is iocore.SetTypeFor.
Types ¶
type CohortSource ¶
type CohortSource = iocore.CohortSource
The tabular I/O contracts live in the iocore leaf so the format adapters can implement them without importing this package (whose jobs the adapters' own tests drive). Every name is an alias: the types are identical, so an optional-interface assertion against either spelling resolves the same way.
type CohortValidator ¶
type CohortValidator = iocore.CohortValidator
The tabular I/O contracts live in the iocore leaf so the format adapters can implement them without importing this package (whose jobs the adapters' own tests drive). Every name is an alias: the types are identical, so an optional-interface assertion against either spelling resolves the same way.
type CohortWriter ¶
type CohortWriter = iocore.CohortWriter
The tabular I/O contracts live in the iocore leaf so the format adapters can implement them without importing this package (whose jobs the adapters' own tests drive). Every name is an alias: the types are identical, so an optional-interface assertion against either spelling resolves the same way.
type ConvertJob ¶
type ConvertJob struct {
Source Reader
Target Writer
Schema *encoding.Schema
KeepPulseAt string // optional: also write intermediate .pulse
SampleRows int
FS afero.Fs
// Includes restricts the export half to the named schema fields,
// in schema order. Nil / empty means write every field. The
// intermediate .pulse file (when KeepPulseAt is set) always
// carries the full schema — projection is an output-time overlay,
// not an on-disk schema change. See ExportJob.Includes.
Includes []string
// Labels apply to the export phase only — the import side reads
// raw source bytes and has no use for label translation. See
// ExportJob.Labels.
Labels []*types.LabelBinding
// LabelResolver carries the runtime resolver. See
// ExportJob.LabelResolver.
LabelResolver LabelResolver
// IncludeOverlays controls whether the export half embeds
// Response.Overlays in the format-native sidecar. Identical
// tri-state semantics to ExportJob.IncludeOverlays — nil defaults
// to emit, *true forces emit, *false drops overlays. The
// intermediate .pulse file (when KeepPulseAt is set) is byte-
// identical regardless of this flag because overlays are an
// export-side concern only; the .pulse byte format never carries
// overlay payloads. See ExportJob.IncludeOverlays for the per-
// format wire shape.
IncludeOverlays *bool
// Overlays carries the Response.Overlays layers the convert should
// embed in the target adapter. Identical semantics to
// ExportJob.Overlays — the export half of the convert dispatches the
// slice via SetOverlays on writers satisfying OverlayAwareWriter
// when IncludeOverlays does not explicitly opt out. The intermediate
// .pulse file (when KeepPulseAt is set) never carries overlay
// payloads.
Overlays []*types.OverlayLayer
}
ConvertJob chains import and export with no intermediate file on disk (unless KeepPulseAt is set).
func NewConvertJob ¶
func NewConvertJob(source Reader, target Writer) *ConvertJob
NewConvertJob creates a ConvertJob with default settings.
func (*ConvertJob) Hash ¶
func (j *ConvertJob) Hash() string
Hash returns the canonical content hash of the ConvertJob. Same rules as ExportJob.Hash — IncludeOverlays participates so cache keys differ between overlay-bearing and overlay-stripped converts.
The hash is namespaced under "convert_job" to keep ConvertJob hashes disjoint from ExportJob hashes.
func (*ConvertJob) Predict ¶
func (j *ConvertJob) Predict(ctx context.Context) (*PredictReport, error)
Predict validates the conversion without writing.
func (*ConvertJob) Run ¶
func (j *ConvertJob) Run(ctx context.Context) (*ConvertReport, error)
Run executes the convert job, streaming from source to target. If KeepPulseAt is set, also writes an intermediate .pulse file.
Total failure is an ERROR, not a zero-row report, exactly as on ImportJob.Run and ExportJob.Run. If the pass reads at least one row and converts none of them, Run returns a nil report and a coded error — PULSE_EXPORT_ROW_ERROR, since every RowError convert can record comes from Target.WriteRow, or the first row error's own code when it carries one — with rows_read, rows_failed, first_row and first_error in details, and no KeepPulseAt intermediate is written. Partial conversion is unchanged: some rows out, some on ConvertReport.RowErrors, nil error. A source with no data rows converts to an empty target and is a success. See totalRowFailure.
A categorical dictionary that OVERFLOWS its rung is the other refusal — for a DECLARED schema (an explicit ConvertJob.Schema or a SchemaAwareReader source's). It is a capacity violation rather than a row condition — past the limit every further unseen category is lost for the rest of the file — so Run stops at the offending cell with PULSE_IMPORT_CATEGORICAL_OVERFLOW (row / column / type / max_entries / value in details), before any KeepPulseAt intermediate is written. ImportJob fails the same condition under the same code.
An INFERRED schema is promoted instead, by the import's own rule (convertOrWiden, import_widen.go): a categorical past its rung, an integer past its width and an f32 past its range move to the narrowest type that holds the value, ConvertReport.Schema carries the final types, ConvertReport.WidthWarnings one PULSE_IMPORT_WIDTH_PROMOTED per field, and a KeepPulseAt intermediate is imported at those types — the cohort a plain import of the source writes. Only a categorical past categorical_u32 still refuses. Convert passes cell TEXT through, so a promotion never changes what the target receives.
type ConvertReport ¶
type ConvertReport struct {
RowsConverted int
Schema *encoding.Schema
RowErrors []RowError
LabelWarnings []LabelWarning
OverlayWarnings []*errors.CodedError
// SourceWarnings carries the source Reader's non-fatal diagnostics
// — see ImportReport.SourceWarnings. Distinct from OverlayWarnings,
// which come from the TARGET Writer.
SourceWarnings []*errors.CodedError
// TargetWarnings carries the target Writer's non-fatal diagnostics
// — see ExportReport.TargetWarnings.
TargetWarnings []*errors.CodedError
// WidthWarnings carries one PULSE_IMPORT_WIDTH_PROMOTED warning per
// field of an INFERRED schema the row pass promoted past its
// sample-inferred width (see ImportReport.WidthWarnings); Schema
// carries the promoted types. Nil for a declared schema, and when
// nothing outgrew its width.
WidthWarnings []*errors.CodedError `json:"WidthWarnings,omitempty"`
}
ConvertReport summarizes the result of a convert operation.
RowErrors is a PARTIAL-failure channel, exactly as on ImportReport and ExportReport: when a non-empty source yields zero converted rows, ConvertJob.Run returns a coded error and no report.
OverlayWarnings carries the warn-and-skip codes the target Writer surfaced through OverlayWarningEmitter — see ExportReport.OverlayWarnings.
type ConvertSource ¶
type ConvertSource = iocore.ConvertSource
The tabular I/O contracts live in the iocore leaf so the format adapters can implement them without importing this package (whose jobs the adapters' own tests drive). Every name is an alias: the types are identical, so an optional-interface assertion against either spelling resolves the same way.
type DedupJob ¶
type DedupJob struct {
// FS is the filesystem both Source and Target live on. Required.
FS afero.Fs
// Source is the cohort to convert. Any supported format version.
Source string
// Target is where the converted cohort is written. Empty (or equal
// to Source) rewrites Source IN PLACE. A different path must not
// exist yet: the job never overwrites a file it was not asked to
// convert.
Target string
// Groups declares the parent groups, exactly as ImportJob.Groups.
Groups []GroupDecl
// ElideConstants stores every field holding one value on every
// record once, as ImportJob.ElideConstants. Declared members are
// never elided.
ElideConstants bool
// DedupRatioFloor and StrictDedup are the viability gate's policy,
// as on ImportJob.
DedupRatioFloor float64
StrictDedup bool
// SuggestGroups runs candidate detection over the source (before any
// rewrite) and returns it on DedupReport.GroupCandidates. With no
// Groups and no ElideConstants the job is detection-only and writes
// nothing.
SuggestGroups bool
}
DedupJob converts an existing single-file cohort to a grouped cohort. Shard archives are not this job's input — the caller (pulse.Dedup) refuses them with a coded error before a byte is read.
type DedupReport ¶
type DedupReport struct {
// Source and Target are the paths read and written; InPlace is true
// when they are the same file.
Source string `json:"source"`
Target string `json:"target"`
InPlace bool `json:"in_place"`
// Rewritten is false when nothing was written: a detection-only run,
// or one whose every declared group was dropped by the width floor
// with no elision to apply. The target is then untouched.
Rewritten bool `json:"rewritten"`
// Records is the record count of the source (and of the rewrite).
Records int64 `json:"records"`
// FormatVersionBefore/After, BytesBefore/After and
// StrideBefore/After describe the source and the written cohort.
// Without a rewrite the After figures repeat the Before ones.
FormatVersionBefore int `json:"format_version_before"`
FormatVersionAfter int `json:"format_version_after"`
BytesBefore int64 `json:"bytes_before"`
BytesAfter int64 `json:"bytes_after"`
StrideBefore int `json:"stride_before"`
StrideAfter int `json:"stride_after"`
// ElidedConstants names the fields ElideConstants stored once.
ElidedConstants []string `json:"elided_constants,omitempty"`
// Groups reports every declaration's verdict and figures, in
// declaration order — the same GroupReport import produces.
Groups []GroupReport `json:"groups,omitempty"`
// GroupWarnings carries the viability gate's findings
// (PULSE_GROUP_TOO_NARROW, PULSE_DEDUP_LOW_RATIO).
GroupWarnings []*errors.CodedError `json:"group_warnings,omitempty"`
// GroupCandidates is the SuggestGroups detection report, measured
// over the source's records.
GroupCandidates *GroupDetection `json:"group_candidates,omitempty"`
}
DedupReport describes a retro-dedup run.
type DiscardableWriter ¶
type DiscardableWriter = iocore.DiscardableWriter
The tabular I/O contracts live in the iocore leaf so the format adapters can implement them without importing this package (whose jobs the adapters' own tests drive). Every name is an alias: the types are identical, so an optional-interface assertion against either spelling resolves the same way.
type ExportJob ¶
type ExportJob struct {
Source string // input .pulse path
Target Writer
FS afero.Fs
// Includes restricts the export to the named source-schema fields,
// in source-schema order. Nil / empty means export every field
// (prior behaviour). Names must match Schema.Fields[i].Name
// exactly. Unknown names return PULSE_EXPORT_FIELD_UNKNOWN with
// the offending name + list of known fields. Label augment
// siblings ("<field>_label") are emitted only for included source
// fields; replace mode applies to included fields as before.
Includes []string
// Labels rewrites or augments categorical column values during
// export using embedder-registered label tables. Bindings name a
// categorical field plus a label table; mode=replace overwrites
// the column value, mode=augment emits a sibling "<field>_label"
// column. See types.LabelBinding for semantics. Nil/empty means
// the exporter writes raw resolved categorical values, matching
// pre-label behaviour.
Labels []*types.LabelBinding
// LabelResolver carries the runtime resolver built from Labels +
// the pulse Service's registered LabelTables. The pulse.Export
// facade builds the resolver and sets this field; callers using
// io.ExportJob directly without a Pulse instance must supply a
// satisfying implementation (typically wrapping
// processing.BuildLabelResolver). Nil means no label translation.
LabelResolver LabelResolver
// IncludeOverlays controls whether Response.Overlays land in the
// exported artefact for adapters that can carry them. The slot is
// a tri-state pointer:
//
// - nil ⇒ DEFAULT EMIT — when the host Response carries any
// overlay layers the adapter embeds them in the
// format-native sidecar (additive-by-default, per PRD
// §6 FR-L5). Output for an overlay-free Response is
// byte-identical to a pre-overlay ExportJob.
// - true ⇒ explicit emit — same behaviour as nil for downstream
// adapters, but the explicit toggle distinguishes the
// intent in canonical-hash composition so cache keys
// differ between "default" and "explicit yes".
// - false ⇒ opt out — overlays are dropped on export even when
// the host Response carries layers. Output is byte-
// identical to a pre-overlay ExportJob against the
// same host result.
//
// Per-format semantics (research/export-embedding-shape.md):
//
// - Arrow / Parquet — overlays ride as a top-level
// LIST<STRUCT> "overlays" field group emitted once in the
// first record-batch / row-group; the host record stream is
// byte-identical to the opt-out shape.
// - Excel — one sheet per layer named "__overlay_<layer_name>";
// the host workbook sheet is unchanged from the opt-out shape.
// - NDJSON — single trailing line {"_overlays": [...]} after the
// last host-record line; the host stream is byte-identical
// until the trailer.
// - CSV / TSV — warn-and-skip. The dispatcher emits one
// PULSE_OVERLAY_EXPORT_CSV_UNSUPPORTED warning and writes the
// host CSV verbatim; no overlay output lands. Setting
// IncludeOverlays=false suppresses the warning while keeping
// the same CSV body.
//
// The pointer shape mirrors the Includes-slot precedent (a nil
// slice means "default": include every field) — nil here means
// "default: emit overlays when present" rather than "explicit no"
// because Go bool zero is false. Marshalling via encoding/json
// honours `omitempty` so nil pointers do not appear in canonical
// JSON; explicit *true and *false both serialise as booleans and
// produce distinct canonical-hash keys via ExportJob.Hash().
IncludeOverlays *bool
// Overlays carries the Response.Overlays layers the export should
// embed in the target adapter's format-native sidecar (Arrow /
// Parquet column family, Excel sheets, NDJSON trailer) per
// research/export-embedding-shape.md. ExportJob.Run dispatches the
// slice to writers satisfying OverlayAwareWriter when IncludeOverlays
// does not explicitly opt out. The CSV / TSV warn-and-skip family
// also accepts the slice through SetOverlays but emits a
// PULSE_OVERLAY_EXPORT_CSV_UNSUPPORTED warning (surfaced on
// ExportReport.OverlayWarnings) instead of writing the layers into
// the CSV body. nil / empty leaves the export byte-identical to a
// pre-overlay job. The slot is intentionally NOT part of the
// canonical-hash composition — two jobs sharing IncludeOverlays /
// Source / Includes / Labels but differing in the overlay payload
// resolve through the SAME cache key because the cache identity is
// the export REQUEST, not the response.
Overlays []*types.OverlayLayer
}
ExportJob converts a .pulse file into tabular output.
func NewExportJob ¶
NewExportJob creates an ExportJob.
func (*ExportJob) Hash ¶
Hash returns the canonical content hash of the ExportJob. Two jobs with the same logical export shape produce the same hash; two jobs with different IncludeOverlays settings (nil / *true / *false) produce distinct hashes so consumers caching export artefacts by hash key do not return stale results when the overlay opt-out flips.
IncludeOverlays participates in the hash composition per research/export-embedding-shape.md §8: the slot is a request-side input to the adapter, so two jobs differing only in IncludeOverlays produce different export artefacts (overlays emitted in one, dropped in the other) and the cache key MUST distinguish.
The hash is namespaced under "export_job" to keep ExportJob and ConvertJob hashes disjoint even when their shapes overlap.
func (*ExportJob) Predict ¶
func (j *ExportJob) Predict(ctx context.Context) (*PredictReport, error)
Predict validates the export without writing.
It reads the source header and schema, estimates the record count, and — when the Target implements the optional CohortValidator contract — asks the target whether it could encode this cohort at all. A Target that is nil or does not implement that interface is predicted exactly as it was before the interface existed; see CohortValidator for why that promise is the whole compatibility story here.
A validating target's refusal is returned as the error, carrying the code the real export would carry, and its non-fatal diagnostics land on PredictReport.TargetWarnings. Predict remains a SOUND but INCOMPLETE filter: a validator only answers from schema and sidecar facts, so passing means no schema-level refusal was found, never that the export cannot fail.
func (*ExportJob) Run ¶
func (j *ExportJob) Run(ctx context.Context) (*ExportReport, error)
Run executes the export job, converting a .pulse file to a tabular target.
Total failure is an ERROR, not a zero-row report. If the cohort yields at least one record and the target accepts none of them, Run returns a nil report and a coded error (PULSE_EXPORT_ROW_ERROR, or the first row error's own code when it carries one) whose details name the record count, the failure count and the first failure. Partial failure is unchanged: some rows out, some on ExportReport.RowErrors, nil error. An empty cohort exports zero rows legitimately. See totalRowFailure.
The CohortWriter arm does not participate: it replaces the row loop, so it reports its own count and raises its own errors.
type ExportReport ¶
type ExportReport struct {
RowsExported int
RowErrors []RowError
LabelWarnings []LabelWarning
OverlayWarnings []*errors.CodedError
// TargetWarnings carries the non-fatal diagnostics the target
// Writer surfaced through the optional TargetWarningEmitter
// contract — today the PULSE_SPSS_SIDECAR_* and
// PULSE_SPSS_NAME_SANITIZED codes the `.sav` encode raises. Nil
// for targets that do not implement the interface and for those
// that implement it and raised nothing, so the report shape is
// unchanged for every pre-existing adapter.
TargetWarnings []*errors.CodedError
}
ExportReport summarizes the result of an export operation.
RowErrors is a PARTIAL-failure channel, exactly as on ImportReport: when a non-empty cohort yields zero exported rows, ExportJob.Run returns a coded error and no report.
OverlayWarnings carries the warn-and-skip codes the target Writer surfaced through the optional OverlayWarningEmitter contract (currently the CSV / TSV adapters via PULSE_OVERLAY_EXPORT_CSV_UNSUPPORTED). Empty / nil when the target adapter embedded the overlays natively (Arrow / Parquet / Excel / NDJSON), when no overlays were supplied, or when IncludeOverlays explicitly opted out.
type GroupCandidate ¶
type GroupCandidate struct {
Label string `json:"label"`
// Key and Members are the structured declaration — the GroupDecl
// shape {key, members}; Declaration is the same as a ready-to-paste
// --group value (empty when a name holds ',' or ':', which the CLI
// form cannot carry).
Key []string `json:"key"`
Members []string `json:"members"`
Declaration string `json:"declaration"`
// Suggested marks a candidate in GroupDetection.Suggested.
// OverlapsWith names the better-ranked suggested candidate sharing
// a field with this one (a field belongs to at most one group).
Suggested bool `json:"suggested"`
OverlapsWith string `json:"overlaps_with,omitempty"`
// RejectedMembers were constant within the key across the
// nomination window but varied later in the file.
RejectedMembers []string `json:"rejected_members,omitempty"`
// Verdict / Reason as the viability gate judges the group
// (encoding.GroupVerdict*), or CandidateVerdictUnmeasured.
Verdict string `json:"verdict"`
Reason string `json:"reason,omitempty"`
EntryCount int `json:"entry_count"`
EntryWidth int `json:"entry_width"`
MemberRowBytes int `json:"member_row_bytes"`
IndexWidth int `json:"index_width"`
DictionaryBytes int64 `json:"dictionary_bytes"`
Ratio float64 `json:"ratio"`
BreakEvenRatio float64 `json:"break_even_ratio"`
RatioFloor float64 `json:"ratio_floor"`
ByteDelta int64 `json:"byte_delta"`
GrowsFile bool `json:"grows_file"`
// ProjectedFileBytes is the exact cohort size with this group alone
// declared (compare ImportProjection.FlatFileBytes).
ProjectedFileBytes int64 `json:"projected_file_bytes"`
}
GroupCandidate is one detected parent group and its measured figures. The figures carry the same names and meaning as GroupReport's.
type GroupDecl ¶
GroupDecl declares one parent group by field NAME.
Key names the fields that identify the parent (e.g. its ID); Members names the fields the key DETERMINES (the parent's attributes). The group stores Key ∪ Members. With a Key, every row that carries a key tuple already seen must agree with that earlier row on every Member — value and null state — or the import fails with PULSE_GROUP_MEMBER_NOT_CONSTANT naming the member and the row: a declaration that is not actually a parent group is refused, never silently turned into a larger dictionary. With no Key, Members is a plain tuple group: each distinct combination is one entry and there is nothing to violate.
func ParseGroupDecl ¶
ParseGroupDecl parses the CLI form of one group declaration:
KEY[,KEY...]:MEMBER[,MEMBER...] a keyed group (members determined by the key) MEMBER[,MEMBER...] a plain tuple group (no key check)
Names are trimmed of surrounding whitespace. An empty name, an empty side of the colon, or more than one colon is PULSE_GROUP_DECLARATION_INVALID. Field names containing ',' or ':' cannot be written in this form; use ImportJob.Groups directly.
type GroupDetection ¶
type GroupDetection struct {
// Rows is the number of rows every candidate was measured over —
// the rows the import would write (row-error rows excluded).
Rows int64 `json:"rows"`
// WindowRows is how many leading rows nomination looked at;
// WindowBound is the most it would have looked at for this schema.
WindowRows int `json:"window_rows"`
WindowBound int `json:"window_bound"`
// FieldsConsidered counts the fields eligible as key or member (not
// declared in a group, not constant across the window).
FieldsConsidered int `json:"fields_considered"`
// KeysEvaluated / KeysOverBound: candidate keys whose dependencies
// were evaluated, and those skipped past detectMaxKeys.
KeysEvaluated int `json:"keys_evaluated"`
KeysOverBound int `json:"keys_over_bound"`
// CandidatesOverBound counts nominated candidates not confirmed
// because detectMaxCandidates were already carried forward.
CandidatesOverBound int `json:"candidates_over_bound"`
// CandidatesDisproved counts nominated candidates every one of
// whose members varied within the key later in the file.
CandidatesDisproved int `json:"candidates_disproved"`
// Candidates, best projected saving first. Every measured candidate
// is listed with its verdict — one below the width or ratio floor
// says so rather than disappearing.
Candidates []GroupCandidate `json:"candidates"`
// Suggested holds the --group values of the admitted candidates
// that do not overlap a better one, in rank order: the declaration
// set detection recommends. Empty when no candidate is viable.
Suggested []string `json:"suggested"`
}
GroupDetection is import predict's candidate parent-group report (ImportJob.SuggestGroups). Candidates are SUGGESTIONS: declaring one is always the user's decision (--group / ImportJob.Groups).
type GroupReport ¶
type GroupReport struct {
// Label names the group in errors and output ("group 1 [key: id]").
Label string `json:"label"`
// Key and Members are as declared; Fields is every member in
// logical (schema) order.
Key []string `json:"key,omitempty"`
Members []string `json:"members"`
Fields []string `json:"fields"`
// Verdict is admitted, low_ratio (written, with a
// PULSE_DEDUP_LOW_RATIO warning) or dropped_too_narrow (not
// written, PULSE_GROUP_TOO_NARROW). Reason is the code behind a
// non-admitted verdict.
Verdict string `json:"verdict"`
Reason string `json:"reason,omitempty"`
// EntryCount is the number of distinct tuples stored.
EntryCount int `json:"entry_count"`
// EntryWidth is the bytes per dictionary entry (member bytes plus a
// member null bitmap when any member is nullable).
EntryWidth int `json:"entry_width"`
// MemberRowBytes is the bytes the members occupied in each flat row.
MemberRowBytes int `json:"member_row_bytes"`
// IndexWidth is the bytes of the per-row index that replaces them.
IndexWidth int `json:"index_width"`
// DictionaryBytes is EntryCount × EntryWidth, resident in memory
// whenever the cohort is open.
DictionaryBytes int64 `json:"dictionary_bytes"`
// Ratio is rows ÷ EntryCount; BreakEvenRatio the ratio below which
// the group grows the file; RatioFloor the floor it was judged
// against.
Ratio float64 `json:"ratio"`
BreakEvenRatio float64 `json:"break_even_ratio"`
RatioFloor float64 `json:"ratio_floor"`
// ByteDelta is the grouped bytes (indexes + dictionary + descriptor)
// minus the members stored per row: negative is a saving.
ByteDelta int64 `json:"byte_delta"`
}
GroupReport describes one declared group: its verdict from the per-group viability gate (encoding.DedupGate) and the numbers behind it. A dropped group (verdict dropped_too_narrow) was not formed — its members stay row fields — and carries only its widths; an admitted or low_ratio group was written and carries the measured ratio, the dictionary it holds resident and the byte delta versus storing its members per row.
type ImportJob ¶
type ImportJob struct {
Source Reader
Target string // output .pulse path
// Schema is the caller-authored .pulse schema. When non-nil it wins
// over everything: inference is skipped AND a SchemaAwareReader
// source is not consulted at all. It is therefore the escape hatch
// for overriding an authoritative source dictionary.
Schema *encoding.Schema
// SampleRows caps the inference sample: default 500, min 50.
// Inert when Schema is supplied or the Source is a
// SchemaAwareReader that yields a schema — there is nothing to
// sample.
SampleRows int
FS afero.Fs
// SetInferenceMinPct configures the delimited-cell heuristic for
// inferring set_* field types during the inference pass. A column
// is classified as set_* when at least this percentage of non-
// null sampled cells contain the inferred delimiter, the
// post-split unique token count fits the widest set rung (≤256),
// and the average post-split cardinality is > 1. Zero is treated
// as 30%.
// Ignored when Schema is supplied, and inert when the Source is a
// SchemaAwareReader that yields a schema.
SetInferenceMinPct int
// ColumnTypeOverrides bypasses inference for the named columns
// (keyed by exact header name). Used by the managed-import
// sidecar's force_type escape hatch. An override is applied exactly
// or refused with PULSE_IMPORT_OVERRIDE_INVALID — never narrowed,
// widened or ignored: an unknown column, a present value the forced
// type cannot hold (on ANY row, not just the inference sample —
// never a skipped row), and an override on a job with no inferred
// schema (Schema supplied, or a SchemaAwareReader source whose
// authoritative dictionary is not a guess to override) are all
// refused. Re-type an authoritative column by supplying Schema.
// See SchemaAwareReader and import_override.go.
ColumnTypeOverrides map[string]encoding.FieldType
// SetDelimiters maps set-typed column name to the delimiter the
// importer should use when splitting cell strings into tokens
// for per-row mask packing. Populated by inference; absent
// entries (explicit-schema imports or non-set columns) fall back
// to DefaultSetDelimiter ("|"). Inert when the Source is a
// SchemaAwareReader that yields a schema: such a source builds
// set_* masks from its own set definitions, not by splitting
// delimited cell strings.
SetDelimiters map[string]string
// InferredSchema marks a supplied Schema as inference-originated so
// the row pass promotes non-nullable fields to nullable on an
// out-of-sample null instead of failing the row (see Run). When
// Schema is nil this is implied — Run infers the schema and always
// promotes. Set it explicitly only when handing Run a pre-built
// schema that came from inference (e.g. ConvertJob's KeepPulseAt
// re-import) so it inherits the same tolerance. Leave false for a
// user-authored explicit schema, where a null in a declared
// non-nullable field must stay a PULSE_IMPORT_ROW_ERROR.
//
// Inert when the Source is a SchemaAwareReader that yields a
// schema. Such a schema is authoritative, not inference-originated,
// so its declared nullability is a contract: an unexpected null is
// a row error, never a silent widening. See SchemaAwareReader.
InferredSchema bool
// ElideConstants stores every field that holds exactly one value
// (or is null) on EVERY imported row once, in the schema block, and
// drops it from each record — a format 0x02 cohort, which binaries
// older than 0x02 support cannot open. Constancy is decided over the
// full row pass, never the inference sample. Nothing is elided (and
// the output stays a byte-identical 0x01 cohort) for fewer than two
// rows, when no field is constant, or when declaring the constants
// would cost more schema bytes than it saves. When every field is
// constant the lowest-index one stays in the row. Default false.
// See encoding.PlanConstantElision.
ElideConstants bool
// Groups declares parent groups (see GroupDecl): each stores its
// distinct member tuples ONCE in the schema block and every record a
// u32 index into them — a format 0x02 cohort, which binaries older
// than 0x02 support cannot open. Groups are independent; a field
// belongs to at most one. Names are checked against the resolved
// schema (inferred, authoritative or explicit alike) before the row
// pass; the dictionaries are built in one pass over the imported
// rows. Composes with ElideConstants: declared members are never
// elided. Empty (the default) writes the 0x01 cohort unchanged.
//
// Every declared group passes the per-group viability gate
// (encoding.DedupGate): one no wider than its u32 index is dropped
// with PULSE_GROUP_TOO_NARROW; one below DedupRatioFloor rows per
// distinct tuple, or that makes the file no smaller, is written with
// PULSE_DEDUP_LOW_RATIO. Both land in ImportReport.GroupWarnings.
Groups []GroupDecl
// DedupRatioFloor is the rows-per-distinct-tuple floor below which
// a declared group draws PULSE_DEDUP_LOW_RATIO. Zero (the default)
// selects encoding.DefaultDedupRatioFloor (2); a value in (0, 1]
// disables the floor, leaving only the grows-the-file check.
DedupRatioFloor float64
// StrictDedup turns the viability gate's warnings into errors: Run
// fails with the finding's own code (PULSE_GROUP_TOO_NARROW or
// PULSE_DEDUP_LOW_RATIO) and writes nothing. It governs the gate
// only — other import warnings are unaffected.
StrictDedup bool
// SuggestGroups makes Predict detect candidate parent groups —
// single-field keys and the fields they determine — and measure
// each over the full row pass (PredictReport.GroupCandidates). It
// SUGGESTS only: Run ignores it, and a candidate is formed only when
// declared through Groups. Costs Predict a full conversion pass (as
// Groups and ElideConstants do) plus the bounded detection work
// documented on GroupDetection.
SuggestGroups bool
}
ImportJob converts tabular source data into a .pulse file.
func NewImportJob ¶
NewImportJob creates an ImportJob with default settings.
func (*ImportJob) Predict ¶
func (j *ImportJob) Predict(ctx context.Context) (*PredictReport, error)
Predict validates the import without writing any output.
func (*ImportJob) Run ¶
func (j *ImportJob) Run(ctx context.Context) (*ImportReport, error)
Run executes the import job, converting tabular source into a .pulse file.
Total failure is an ERROR, not a zero-row report. If the row pass reads at least one row and converts none of them, Run returns a nil report and a coded error (PULSE_IMPORT_ROW_ERROR, or the first row error's own code when it carries one) whose details name the row count, the failure count and the first failure — and no .pulse file is written. Partial failure is unchanged: some rows in, some on ImportReport.RowErrors, nil error. A source with no data rows at all is an empty cohort, which is a legitimate outcome and not an error. See totalRowFailure.
type ImportProjection ¶
type ImportProjection struct {
// RowsImported / RowErrors: rows that would import, and rows that
// would be skipped with a row error.
RowsImported int `json:"rows_imported"`
RowErrors int `json:"row_errors"`
// FlatFileBytes is the exact size of the 0x01 cohort (no groups,
// no elision).
FlatFileBytes int64 `json:"flat_file_bytes"`
// ProjectedFileBytes is the exact size of the cohort this job would
// write: its admitted Groups plus, with ElideConstants, the
// constant group. Equal to FlatFileBytes when neither applies.
ProjectedFileBytes int64 `json:"projected_file_bytes"`
// ElisionBytesSaved is what ElideConstants would save (0 when off
// or nothing is elided).
ElisionBytesSaved int64 `json:"elision_bytes_saved,omitempty"`
}
ImportProjection is the measured pass's view of the file the import would write.
type ImportReport ¶
type ImportReport struct {
RowsImported int
Schema *encoding.Schema
RowErrors []RowError
PromotedFields []string
// WidthWarnings carries one PULSE_IMPORT_WIDTH_PROMOTED warning per
// field the row pass promoted past its sample-inferred width
// (categorical_* rung, integer width, or integer → f64), with
// field / from / to / source_row in Details. Empty (and omitted from
// JSON) when nothing outgrew its inferred width — always, for an
// explicit or authoritative schema. See import_widen.go.
WidthWarnings []*errors.CodedError `json:"WidthWarnings,omitempty"`
// SourceWarnings carries the non-fatal diagnostics the source
// Reader surfaced through the optional SourceWarningEmitter
// contract — today the PULSE_SPSS_* family raised by the `.sav`
// dictionary walk, schema mapping and data pass. Nil for sources
// that do not implement the interface and for sources that
// implement it and raised nothing, so the report shape is
// unchanged for every pre-existing adapter.
SourceWarnings []*errors.CodedError
// ElidedConstants names the fields ImportJob.ElideConstants stored
// once in the schema block instead of per row, in schema order.
// Empty (and omitted from JSON) when elision was off or elided
// nothing, in which case the cohort is 0x01.
ElidedConstants []string `json:"ElidedConstants,omitempty"`
// Groups describes each ImportJob.Groups declaration as written, in
// declaration order: its label, fields, distinct-tuple count and
// the entry / member / index widths a viability check weighs. Empty
// (and omitted from JSON) when no group was declared.
Groups []GroupReport `json:"Groups,omitempty"`
// GroupWarnings carries the viability gate's findings, one per
// flagged group: PULSE_GROUP_TOO_NARROW (the group was dropped) and
// PULSE_DEDUP_LOW_RATIO (the group was written anyway), each with
// its numbers in Details. Empty (and omitted from JSON) when every
// declared group passed. Under ImportJob.StrictDedup a finding is
// returned as Run's error instead and there is no report.
GroupWarnings []*errors.CodedError `json:"GroupWarnings,omitempty"`
}
ImportReport summarizes the result of an import operation.
RowErrors records the rows that did not make it. It is a PARTIAL-failure channel only: a report exists precisely because some rows did import. When a non-empty source yields zero importable rows, ImportJob.Run returns a coded error and no report at all, so a caller that checks only the error return can no longer read total failure as success.
PromotedFields names the columns an inferred import widened to nullable because a null cell fell outside the bounded inference sample window (see ImportJob.InferredSchema). Empty for explicit-schema imports and for inferred imports with no out-of-sample nulls. Each promotion also surfaces a PULSE_IMPORT_NULL_PROMOTED warning to callers that thread coded warnings.
type InferOptions ¶
type InferOptions struct {
// SampleRows caps how many rows InferSchema reads before
// finalizing column types. Defaults to defaultSampleRows when
// <= 0; min-clamped to minSampleRows.
SampleRows int
// SetInferenceMinPct is the minimum percentage of non-null
// sampled cells that must contain the inferred delimiter for the
// column to be classified as set_*. Defaults to
// defaultSetInferenceMinPct (30) when 0.
SetInferenceMinPct int
// ColumnTypeOverrides maps column name to forced FieldType,
// bypassing the inference heuristics entirely for those columns.
// For set_* / categorical_* types the dictionary is still built
// from observed sample values during the inference pass; the
// override only fixes the column's storage type.
ColumnTypeOverrides map[string]encoding.FieldType
}
InferOptions parameterises InferSchemaWithOptions. The zero value is safe — SampleRows / SetInferenceMinPct fall back to their package defaults and ColumnTypeOverrides is treated as empty.
type InferenceResult ¶
type InferenceResult struct {
Schema *encoding.Schema
Warnings []InferenceWarning
Delimiters map[string]string
}
InferenceResult bundles the inference output. The Delimiters map is populated for columns classified as set_*; callers (importers) use it to pack per-cell masks during the row pass.
func InferSchemaWithOptions ¶
func InferSchemaWithOptions(reader Reader, opts InferOptions) (*InferenceResult, error)
InferSchemaWithOptions is the parameterised inference entry. Returns the schema, accumulated warnings, AND the per-column delimiter map for columns classified as set_*. The delimiter map is used by ImportJob.Run during the row pass to split delimited cells into token lists for bit-packing.
type InferenceWarning ¶
InferenceWarning records a non-fatal observation during inference.
func InferSchema ¶
InferSchema samples up to sampleRows rows from reader and proposes a Schema. If sampleRows <= 0, defaultSampleRows is used. The minimum is minSampleRows. Wrapper over InferSchemaWithOptions that drops the delimiter map; only CSV/TSV/Excel paths that ignore set-typed import packing should call this entry. Importers should call InferSchemaWithOptions directly.
type LabelResolver ¶
type LabelResolver interface {
// Has reports whether the resolver carries any binding for the
// named field.
Has(field string) bool
// Mode returns the binding mode for the named field. Empty when
// no binding exists.
Mode(field string) types.LabelMode
// Apply translates a raw value through the binding for the named
// field. See processing.LabelResolver.Apply for semantics.
Apply(field, raw string) (out string, sibling string, ok bool)
// FieldsWithAugment returns the field names that should emit a
// "<field>_label" sibling column.
FieldsWithAugment() []string
// Warnings flushes the per-binding collision and miss summaries
// once the job finishes.
Warnings() []LabelWarning
}
LabelResolver is the io-package projection of the processing-layer label resolver. ExportJob / ConvertJob consume the interface so io stays free of the processing dependency.
processing.LabelResolver satisfies this interface as-is; the pulse-package facade builds the resolver from the user-facing LabelBinding slice + LabelTable registry and hands the value to the job via ExportJob.LabelResolver.
type LabelWarning ¶
LabelWarning is the io-package projection of one resolver diagnostic record. ExportReport surfaces these for the caller; the CLI / MCP envelope wrapper promotes them to envelope warnings.
type NullAwareReader ¶
type NullAwareReader = iocore.NullAwareReader
The tabular I/O contracts live in the iocore leaf so the format adapters can implement them without importing this package (whose jobs the adapters' own tests drive). Every name is an alias: the types are identical, so an optional-interface assertion against either spelling resolves the same way.
type NullAwareWriter ¶
type NullAwareWriter = iocore.NullAwareWriter
The tabular I/O contracts live in the iocore leaf so the format adapters can implement them without importing this package (whose jobs the adapters' own tests drive). Every name is an alias: the types are identical, so an optional-interface assertion against either spelling resolves the same way.
type OverlayAwareWriter ¶
type OverlayAwareWriter = iocore.OverlayAwareWriter
The tabular I/O contracts live in the iocore leaf so the format adapters can implement them without importing this package (whose jobs the adapters' own tests drive). Every name is an alias: the types are identical, so an optional-interface assertion against either spelling resolves the same way.
type OverlayWarningEmitter ¶
type OverlayWarningEmitter = iocore.OverlayWarningEmitter
The tabular I/O contracts live in the iocore leaf so the format adapters can implement them without importing this package (whose jobs the adapters' own tests drive). Every name is an alias: the types are identical, so an optional-interface assertion against either spelling resolves the same way.
type PredictReport ¶
type PredictReport struct {
Schema *encoding.Schema
EstimatedRows int
Warnings []InferenceWarning
// SourceWarnings carries the source Reader's non-fatal coded
// diagnostics — see ImportReport.SourceWarnings. Held apart from
// Warnings, which is the inference pass's own untyped channel: a
// predict against an authoritative source runs no inference, so
// Warnings is empty there and SourceWarnings is the only signal.
SourceWarnings []*errors.CodedError
// TargetWarnings carries the non-fatal diagnostics the TARGET
// Writer would raise if the export ran, lifted off the optional
// CohortValidator contract — today the PULSE_SPSS_SIDECAR_ABSENT /
// _IGNORED and PULSE_SPSS_NAME_SANITIZED codes a `.sav` export
// raises before it reads a single record. Symmetric with
// ExportReport.TargetWarnings, and held apart from SourceWarnings
// for the same reason ConvertReport holds the two apart: one is
// about what was read, the other about what would be written.
//
// Nil for a predict whose target does not implement
// CohortValidator, which is every format but `.sav` today, and nil
// for a validating target that raised nothing.
TargetWarnings []*errors.CodedError
// The fields below are filled only by an ImportJob.Predict that runs
// the MEASURED pass — the job declares Groups, sets ElideConstants
// or sets SuggestGroups — and are nil (omitted from JSON) otherwise,
// so a plain predict's report is unchanged. The measured pass
// converts every row exactly as Run does, so each figure is what the
// import would produce, not a sample estimate.
//
// WidthWarnings are the PULSE_IMPORT_WIDTH_PROMOTED warnings Run
// would raise (see ImportReport.WidthWarnings), and Schema carries
// the promoted types. Only the measured pass converts values, so a
// plain predict never reports a width promotion: its Schema is the
// sample-inferred one.
WidthWarnings []*errors.CodedError `json:"WidthWarnings,omitempty"`
// Projection sizes the file the import would write.
Projection *ImportProjection `json:"Projection,omitempty"`
// Groups / GroupWarnings are what ImportReport.Groups /
// GroupWarnings would carry for the declared Groups. A declaration
// Run would refuse — an unknown field, or a member that varies
// within its key (PULSE_GROUP_MEMBER_NOT_CONSTANT) — is Predict's
// error too, and StrictDedup fails Predict as it fails Run.
Groups []GroupReport `json:"Groups,omitempty"`
GroupWarnings []*errors.CodedError `json:"GroupWarnings,omitempty"`
// ElidedConstants names what ElideConstants would elide.
ElidedConstants []string `json:"ElidedConstants,omitempty"`
// GroupCandidates is the SuggestGroups detection report.
GroupCandidates *GroupDetection `json:"GroupCandidates,omitempty"`
}
PredictReport summarizes a validation-only run.
type Reader ¶
The tabular I/O contracts live in the iocore leaf so the format adapters can implement them without importing this package (whose jobs the adapters' own tests drive). Every name is an alias: the types are identical, so an optional-interface assertion against either spelling resolves the same way.
type ResetReader ¶
type ResetReader = iocore.ResetReader
The tabular I/O contracts live in the iocore leaf so the format adapters can implement them without importing this package (whose jobs the adapters' own tests drive). Every name is an alias: the types are identical, so an optional-interface assertion against either spelling resolves the same way.
type SchemaAwareReader ¶
type SchemaAwareReader = iocore.SchemaAwareReader
The tabular I/O contracts live in the iocore leaf so the format adapters can implement them without importing this package (whose jobs the adapters' own tests drive). Every name is an alias: the types are identical, so an optional-interface assertion against either spelling resolves the same way.
type SchemaAwareWriter ¶
type SchemaAwareWriter = iocore.SchemaAwareWriter
The tabular I/O contracts live in the iocore leaf so the format adapters can implement them without importing this package (whose jobs the adapters' own tests drive). Every name is an alias: the types are identical, so an optional-interface assertion against either spelling resolves the same way.
type SidecarEmitter ¶
type SidecarEmitter = iocore.SidecarEmitter
The tabular I/O contracts live in the iocore leaf so the format adapters can implement them without importing this package (whose jobs the adapters' own tests drive). Every name is an alias: the types are identical, so an optional-interface assertion against either spelling resolves the same way.
type SourceAwareWriter ¶
type SourceAwareWriter = iocore.SourceAwareWriter
The tabular I/O contracts live in the iocore leaf so the format adapters can implement them without importing this package (whose jobs the adapters' own tests drive). Every name is an alias: the types are identical, so an optional-interface assertion against either spelling resolves the same way.
type SourceWarningEmitter ¶
type SourceWarningEmitter = iocore.SourceWarningEmitter
The tabular I/O contracts live in the iocore leaf so the format adapters can implement them without importing this package (whose jobs the adapters' own tests drive). Every name is an alias: the types are identical, so an optional-interface assertion against either spelling resolves the same way.
type TargetWarningEmitter ¶
type TargetWarningEmitter = iocore.TargetWarningEmitter
The tabular I/O contracts live in the iocore leaf so the format adapters can implement them without importing this package (whose jobs the adapters' own tests drive). Every name is an alias: the types are identical, so an optional-interface assertion against either spelling resolves the same way.
type TransferExportJob ¶
type TransferExportJob struct {
// FS is the filesystem both paths resolve against. Required.
FS afero.Fs
// Source is the cohort path.
Source string
// Output is the artifact path, conventionally Source + ".zst".
Output string
// Level is the zstd level, MinTransferLevel..MaxTransferLevel. Zero
// selects DefaultTransferLevel.
Level int
}
TransferExportJob compresses a cohort's exact bytes into a transfer artifact. Source must be an uncompressed `.pulse` (single-file or shard archive); Output is overwritten.
func (*TransferExportJob) Run ¶
func (j *TransferExportJob) Run(ctx context.Context) (*TransferReport, error)
Run compresses Source into Output.
type TransferImportJob ¶
type TransferImportJob struct {
// FS is the filesystem both paths resolve against. Required.
FS afero.Fs
// Source is the `.pulse.zst` artifact path.
Source string
// Output is the cohort path to write.
Output string
// Overwrite permits replacing an existing Output. Default false:
// silently replacing a working cohort is refused.
Overwrite bool
}
TransferImportJob decompresses a transfer artifact back into a byte-identical `.pulse` at rest. The output is staged beside Output and renamed over it only once the whole stream decoded, its checksum held and the decoded bytes began with a Pulse magic — a refusal or a damaged artifact leaves nothing behind.
func (*TransferImportJob) Run ¶
func (j *TransferImportJob) Run(ctx context.Context) (*TransferReport, error)
Run decompresses Source into Output.
type TransferReport ¶
type TransferReport struct {
Source string `json:"source"`
Output string `json:"output"`
Codec string `json:"codec"`
// Level is the zstd level used; set on compress only.
Level int `json:"level,omitempty"`
// Layout is single_file or shard_archive.
Layout string `json:"layout"`
// CohortBytes is the uncompressed cohort size.
CohortBytes int64 `json:"cohort_bytes"`
// CompressedBytes is the artifact size.
CompressedBytes int64 `json:"compressed_bytes"`
// Ratio is CohortBytes / CompressedBytes (0 when the artifact is
// empty, which cannot happen for a real stream).
Ratio float64 `json:"ratio"`
// SHA256 is the lowercase hex digest of the uncompressed cohort.
SHA256 string `json:"sha256"`
}
TransferReport describes one transfer compress or decompress. SHA256 is always the digest of the UNCOMPRESSED cohort bytes, so the sender's and the receiver's reports compare directly.
type Writer ¶
The tabular I/O contracts live in the iocore leaf so the format adapters can implement them without importing this package (whose jobs the adapters' own tests drive). Every name is an alias: the types are identical, so an optional-interface assertion against either spelling resolves the same way.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
Package arrow provides Arrow IPC (Feather V2) import and export for the pulse I/O pipeline, plus shared Arrow<->Pulse type-mapping helpers used by both this package and internal/io/parquet.
|
Package arrow provides Arrow IPC (Feather V2) import and export for the pulse I/O pipeline, plus shared Arrow<->Pulse type-mapping helpers used by both this package and internal/io/parquet. |
|
Package csv provides CSV format adapters for the Pulse I/O pipeline.
|
Package csv provides CSV format adapters for the Pulse I/O pipeline. |
|
Package excel provides Excel import and export for the pulse I/O pipeline.
|
Package excel provides Excel import and export for the pulse I/O pipeline. |
|
Package exportoverlay holds the higher-level integration tests for the ExportJob and ConvertJob overlay-embedding wiring.
|
Package exportoverlay holds the higher-level integration tests for the ExportJob and ConvertJob overlay-embedding wiring. |
|
Package jsonarray provides JSON-array import and export for the pulse I/O pipeline.
|
Package jsonarray provides JSON-array import and export for the pulse I/O pipeline. |
|
Package jsonshared holds value coercion helpers shared by the ndjson and jsonarray packages.
|
Package jsonshared holds value coercion helpers shared by the ndjson and jsonarray packages. |
|
Package ndjson provides NDJSON (newline-delimited JSON) import and export for the pulse I/O pipeline.
|
Package ndjson provides NDJSON (newline-delimited JSON) import and export for the pulse I/O pipeline. |
|
Package nullcell holds the cross-adapter integration tests for the TWO absent-looking states of a `categorical_*` column — a null cell and a cell whose value IS the empty string.
|
Package nullcell holds the cross-adapter integration tests for the TWO absent-looking states of a `categorical_*` column — a null cell and a cell whose value IS the empty string. |
|
Package parquet provides Parquet import and export for the pulse I/O pipeline.
|
Package parquet provides Parquet import and export for the pulse I/O pipeline. |
|
Package settristate holds the cross-adapter integration tests for the THREE states of a `set_*` column — null, empty mask ("answered, selected nothing") and non-empty mask.
|
Package settristate holds the cross-adapter integration tests for the THREE states of a `set_*` column — null, empty mask ("answered, selected nothing") and non-empty mask. |
|
Package setwide holds the per-adapter wide-set round-trip tests: one test per tabular format, proving that a 206-member `set_u256` column survives an export and a re-import with every bit in the place it started.
|
Package setwide holds the per-adapter wide-set round-trip tests: one test per tabular format, proving that a 206-member `set_u256` column survives an export and a re-import with every bit in the place it started. |
|
Package spss reads SPSS `.sav` system files for the Pulse I/O pipeline.
|
Package spss reads SPSS `.sav` system files for the Pulse I/O pipeline. |
|
Package tsv provides TSV import and export for the pulse I/O pipeline.
|
Package tsv provides TSV import and export for the pulse I/O pipeline. |