search

package module
v0.0.0-...-a0c1d78 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 26, 2026 License: BSD-3-Clause Imports: 11 Imported by: 0

README

dendra-search is the Go library Dendra uses for datastream discovery. A host passes in the sites, stations, and datastreams for one organization, and the library builds a single immutable index that can answer a faceted filter, a map viewport, and a deployment-interval query. What you get back is bytes. Serving those bytes, and deciding who may download them, belongs to the host.

You fill a Builder in a fixed order: sites, then stations, then datastreams. Finish serializes that index into a shard, which is the byte slice you store. Later, Open loads the slice and builds two R-trees, one on the shown location and one on the exact location. Query reads a single shard. A search that covers more than one organization queries each shard and passes the results to Combine, which merges them and clusters the sites once.

The same filled builder can produce two shards, and you will usually want both. Finish(FinishPrivate) writes the full shard: every datastream, with each site's shown box and exact box stored as you added them. Finish(FinishPublic) writes the public shard from those same rows. Only datastreams marked public_ok are kept, so a member-only datastream is simply not in the file, and a site appears only when at least one public datastream uses it. The exact box and exact point written there are copies of the shown values. Anyone who can read the file can read every coordinate in it, so the public shard has no true coordinates of its own. Doc ids in that shard are assigned again, following the order the public rows were added.

Finish does not throw the index away. After the private shard is written you can call Finish(FinishPublic) on the same builder, or the other way around, and a repeated call with the same mode returns the same bytes. You can upload the first buffer and drop it before the second call, which keeps you from holding both files at once. Adding another site, station, or datastream after the first Finish returns ErrFinished. Drop the builder once you have the slices you need.

On each query you name the geometry, shown or exact, and whether member-only datastreams should be included. The library will not make that choice for you. It also does not serve traffic, talk to an object store, import protobuf, or gzip. Storing shards, pinning organizations, and enforcing membership stay with the host.

Install

go get github.com/dendrascience/dendra-search

The module needs Go 1.22 or newer. Its dependencies are portable Roaring bitmaps (github.com/RoaringBitmap/roaring) and an R-tree (github.com/tidwall/rtree). Build and test with CGO_ENABLED=0.

How a shard is built

Each organization is one shard. Sites go in first, then stations, then datastreams, and the builder rejects a row that arrives out of that order. A site stores a shown box and an exact box, along with the digest points clustering uses. A datastream either names a station, whose deployment intervals were added with that station, or it carries its own intervals when it is attached to a site directly. An interval is a half-open range of Unix milliseconds, [BeginsAt, EndsBefore). EndsBefore == 0 means the deployment is still open. A non-zero EndsBefore means it has ended. A datastream has at most one open interval, and every interval may be closed. With no time window, Query keeps only the open interval, so a fully closed history is absent. A window matches every overlapping interval, including those that have ended. Pass intervals that do not overlap. The builder returns an error if they do, and it will not merge them for you. An interval may name a group id. Empty means that interval has no group. The shard stores the id and does not store the name.

AddDatastream copies what it needs into the index and then drops the struct you passed. The row is recorded in the posting lists (purpose, measurement, public_ok, member_ok, and the site of the open deployment), in the interval table, and in the forward rows that Query later turns into hits. Finish writes that index out as one blob and leaves the in-memory copy where it is, which is what makes the second Finish possible. Open reads the blob and inserts each site's shown box and exact box into its own R-tree. The trees are not stored in the file. Query intersects the predicates you set, allocates temporary bitmaps only, and is safe for concurrent readers on the same shard.

Leave a query field empty and that predicate is skipped. An empty measurement list means every measurement, and the same is true for sites, for groups, for purpose, and for a nil viewport. An empty group list matches intervals that have no group. Several group ids are a union, and the group is tested on the same interval as the site and the viewport. GroupIDs lists the group ids on the intervals in play. ReducePicker turns organization and group catalogs, the checked ids, and those lists into the picker rows. The picker rules are in docs/groups.md. IncludeMemberOnly set to false keeps the public_ok rows. Set to true, it uses the union of public_ok and member_ok. On a public shard that union cannot surface a member-only datastream, because the row was never written.

Zoom 0 is the whole world. A zero MapSiteLimit is treated as 100, and a zero MinSiteZoom is treated as 6. When the matching sites are above that limit, or the zoom is below that floor, the result is clusters and measurement counts, and the per-site counts stay empty. Otherwise you get one marker per site, both count arrays, and an optional page of hits.

Across organizations, query each shard on its own and then call Combine. Clustering happens in that merge, so you should not cluster inside the per-shard query and again afterwards. If the host pins one organization at a time, do not hold every shard's query open across the others.

The query rules are written out in docs/query.md. Groups are in docs/groups.md. The byte layout, which you want when a blob will not open, is in docs/format.md.

The public container

Once each organization has a public shard, those shards can travel as one object. WriteContainer packs them into a single uncompressed frame, and ParseContainer takes the frame apart. The first four bytes are DSPC. That string is file magic, the same kind of marker as DS01 at the start of a shard, and the letters do not stand for a longer name.

Inside the frame, each chunk is an organization id, the etag of that organization's public shard, and the shard bytes themselves. The bytes are copied through as they were given. The library does not look for a DS01 header inside them, and it does not sort the organizations, so the order you pass is the order that gets stored.

The etag is there for the next time the frame is assembled. Parse the frame, replace the chunks whose etag changed, and write it again. Open never looks at the etag. Fetching the chunks is the caller's job, and so is compression. If a host stores a gzip copy for download, it compresses outside this package and records that fact on the version file below. A browser fetch of an object served with Content-Encoding: gzip has already decompressed the body by the time your code sees it, so you call ParseContainer on those bytes and do not gunzip them again.

The version file

VersionFile is the JSON object stored as current.json beside a shard or beside a container. A reader follows that file and then fetches the object it names, rather than listing a directory and guessing which bin is current. The fields that do the naming are the object key, the etag, the size, and built_at.

A pointer for a private shard can also carry doc_count and the organization flags is_enabled, is_hidden, and public_ok. Those fields are pointers in the struct, so leaving them unset omits them from the JSON. A container pointer leaves them unset. keep lists older object keys that should be spared until until, which is how a reader who already resolved the previous pointer can finish that download. encoding is omitted when it is empty, and empty means the object is the raw bytes from Finish or WriteContainer. Setting it to gzip only labels the public download. Marshal writes JSON and does not compress.

Usage

A single organization looks like this. Finish returns the shard bytes and the number of datastreams written.

b := search.NewBuilder()
err = b.AddSite(site)
err = b.AddStation(station)
err = b.AddDatastream(datastream)
blob, n, err := b.Finish(search.FinishPrivate)

shard, err := search.Open(blob)
res, err := shard.Query(search.Query{
    Purpose:  search.PurposeReadyToUse,
    Geometry: search.GeometryShown,
    Zoom:     2,
    Viewport: &search.Box{West: -180, South: -90, East: 180, North: 90},
})

Call Finish(search.FinishPublic) on that same builder when you also want the public shard. It returns its own byte slice and its own doc count.

AddSites, AddStations, and AddDatastreams loop the singular methods. If you already have a page from the database, call AddSite (or the station or datastream method) once per row and skip rows the index should not contain:

for _, row := range sitePage {
    if !row.Enabled || row.Hidden {
        continue
    }
    err = b.AddSite(search.Site{
        ID: row.ID, Name: row.Name,
        Shown: row.Shown, Exact: row.Exact,
        ShownPoint: row.ShownPoint, ExactPoint: row.ExactPoint,
        OrganizationID: row.OrganizationID, OrganizationName: row.OrganizationName,
    })
}

Several organizations are queried separately and then merged:

parts := make([]search.Result, len(shards))
for i, shard := range shards {
    parts[i], err = shard.Query(q)
}
res, err = search.Combine(q, parts)

Examples

go run ./examples/demo
go run ./examples/bench
./examples/wasm/build.sh examples/map/search.wasm && go run ./examples/map

demo prints a private query and then a public one from the same builder, including a container round trip and a version file, then the north and south group picker. bench runs the fixture matrix. The map page is a static Explore-style view over those fixtures, and it serves at http://127.0.0.1:8080. Notes for each program are in examples/README.md.

Development

CGO_ENABLED=0 go test ./...
go run ./examples/bench    # writes BENCHMARKS.md

Tests need no network. The fixtures and the benchmark cases are described in docs/fixtures.md. go test enforces the today-scale limits, 10 ms per query and 32 MiB of heap for today-catalog. How long Finish takes is written to BENCHMARKS.md and is not a pass or fail. The large-scale numbers are recorded there next to 100 ms and 512 MB.

License

BSD-3-Clause. Copyright The Dendra Science Contributors.

Documentation

Overview

Package search is the datastream search index.

A builder takes sites, then stations, then datastreams for one organization. The first record sets OrganizationID. Later records must use that same id. Finish writes that organization's shard. FinishPrivate keeps shown and exact geometry and every datastream. FinishPublic copies shown into the exact fields and keeps public_ok datastreams only. The index stays in place, so Finish may be called again with the other mode. Open loads those bytes into an immutable shard and builds the shown and exact R-trees. Query reads the shard. Combine merges one result per organization and clusters the sites once. An interval may carry a group id. Query.GroupIDs filters on that id. GroupIDs lists the ids on intervals in play. ReducePicker turns organization and group catalogs, the checked ids, and those lists into the picker rows.

WriteContainer and ParseContainer frame public shards in an uncompressed DSPC container. VersionFile marshals the current.json pointer. An empty Encoding means the object is raw. This package does not compress.

The caller chooses the geometry name and whether member-only datastreams are included. This package does not open sockets, and it does not decide who may see a site.

Index

Constants

View Source
const (
	GeometryShown = "shown"
	GeometryExact = "exact"
)

Geometry names stored on every site. The caller picks one per query.

View Source
const (
	DefaultMapSiteLimit uint32 = 100
	DefaultMinSiteZoom  uint32 = 6
)

Defaults when a query leaves the map limits at zero.

View Source
const (
	PurposeReadyToUse        = "ReadytoUse"
	PurposeRaw               = "Raw"
	PurposeStatusInformation = "StatusInformation"
)

Purpose values used by the fixtures. Query treats purpose as an ordinary string.

View Source
const FixtureSeed int64 = 1

FixtureSeed is the generator seed. The same seed always yields the same bytes.

Variables

View Source
var (
	// ErrOrder means a site, station, or datastream was added out of feed order.
	// Sites come first, then stations, then datastreams.
	ErrOrder = errors.New("search: sites, then stations, then datastreams")

	// ErrFinished means Add was called after Finish. Finish itself may be called again.
	ErrFinished = errors.New("search: builder is finished")

	// ErrDuplicate means a site, station, or datastream id was added twice.
	ErrDuplicate = errors.New("search: duplicate id")

	// ErrNotFound means a datastream names a site or station that was not added.
	ErrNotFound = errors.New("search: unknown site or station")

	// ErrInterval means a deployment interval is empty, overlapping, inverted,
	// or has more than one open end. Zero open ends is a deployment that has ended.
	ErrInterval = errors.New("search: invalid interval")

	// ErrDatastream means a datastream has no place, or both a station and its own intervals.
	ErrDatastream = errors.New("search: invalid datastream")

	// ErrBox means a site box or digest point is outside WGS84 or wraps the antimeridian.
	// Split a wrapping site before AddSite.
	ErrBox = errors.New("search: invalid box")

	// ErrGeometry means Query.Geometry is not "shown" or "exact".
	ErrGeometry = errors.New("search: geometry must be shown or exact")

	// ErrViewport means a viewport is outside WGS84 or has south above north.
	ErrViewport = errors.New("search: invalid viewport")

	// ErrWindow means only one time bound was set, or the end is not after the start.
	ErrWindow = errors.New("search: invalid time window")

	// ErrFormat means the bytes are not a shard this package can open.
	ErrFormat = errors.New("search: invalid shard")

	// ErrContainer means the bytes are not a DSPC frame this package can parse.
	ErrContainer = errors.New("search: invalid container")

	// ErrInvalid means a required id is empty, related records name different
	// organizations, or the receiver is nil.
	ErrInvalid = errors.New("search: invalid value")
)

Functions

func Measurement

func Measurement(i int) string

Measurement returns one of the twelve synthetic measurement names.

func WriteContainer

func WriteContainer(chunks []ContainerChunk) ([]byte, error)

WriteContainer frames chunks in the order given. It does not sort organizations, inspect shard magic, or decide which etag changed.

Types

type BenchCase

type BenchCase struct {
	Name  string
	Query Query
}

BenchCase is one timed query in the benchmark matrix.

func BenchCases

func BenchCases(f Fixture) []BenchCase

BenchCases returns the four design cases. The shown-versus-exact case is two queries.

type Box

type Box struct {
	West, South, East, North float64
}

Box is a longitude/latitude rectangle. West and South are the minimums, East and North the maximums. A point is a box whose corners are equal. A viewport may wrap the antimeridian (East < West). A site box may not.

type Builder

type Builder struct {
	// contains filtered or unexported fields
}

Builder accumulates one organization. The first added record sets OrganizationID. Later records must use that same id. Feed sites, then stations, then datastreams. Each accepted datastream is recorded into the index immediately. Finish serializes that index and returns the shard bytes and the doc count.

func NewBuilder

func NewBuilder() *Builder

NewBuilder returns an empty builder for one organization.

func (*Builder) AddDatastream

func (b *Builder) AddDatastream(datastream Datastream) error

AddDatastream records one datastream into the posting lists, interval table, and forward rows. The doc id is the accept order. The struct is not retained.

func (*Builder) AddDatastreams

func (b *Builder) AddDatastreams(datastreams []Datastream) error

AddDatastreams adds each datastream in order.

func (*Builder) AddSite

func (b *Builder) AddSite(site Site) error

AddSite appends one site. It copies the struct into the builder.

func (*Builder) AddSites

func (b *Builder) AddSites(sites []Site) error

AddSites adds each site in order.

func (*Builder) AddStation

func (b *Builder) AddStation(station Station) error

AddStation appends one station and copies its intervals.

func (*Builder) AddStations

func (b *Builder) AddStations(stations []Station) error

AddStations adds each station in order.

func (*Builder) Finish

func (b *Builder) Finish(mode FinishMode) ([]byte, uint32, error)

Finish serializes the index recorded by AddDatastream. FinishPrivate writes every datastream. FinishPublic writes public_ok datastreams only, with exact geometry copied from shown. The index is left in place. Another Finish is allowed, in either order, and the same mode twice returns the same bytes. Add after the first Finish returns ErrFinished. An unknown mode returns ErrInvalid and does not seal.

func (*Builder) HasSite

func (b *Builder) HasSite(id string) bool

HasSite reports whether AddSite accepted id. The lookup uses the id map AddSite already keeps.

func (*Builder) HasStation

func (b *Builder) HasStation(id string) bool

HasStation reports whether AddStation accepted id. The lookup uses the id map AddStation already keeps.

type CatalogName

type CatalogName struct {
	ID   string
	Name string
}

CatalogName is one row from the host's organization or group list. The host supplies the name. This package does not look it up.

type Cluster

type Cluster struct {
	Centroid  Point
	SiteCount uint32
	Expansion Box
}

Cluster is a web-mercator cell of candidate sites.

type ContainerChunk

type ContainerChunk struct {
	OrganizationID string
	ETag           string
	Bytes          []byte
}

ContainerChunk is one organization's public shard inside an uncompressed DSPC frame. Bytes are stored and returned unchanged.

func ParseContainer

func ParseContainer(frame []byte) ([]ContainerChunk, error)

ParseContainer reads an uncompressed DSPC frame. The chunk bytes are copies.

type Count

type Count struct {
	Value            string
	Count            uint32
	Name             string
	OrganizationID   string
	OrganizationName string
}

Count is one disjunctive facet row. Name and organization fields are set on site counts (from the Site record) so a host can label zero-count rows that never appear as map markers. Measurement counts leave them empty.

type Datastream

type Datastream struct {
	ID             string
	Name           string
	OrganizationID string
	StationID      string
	UnitName       string
	Measurement    string
	Purpose        string
	PublicOK       bool
	MemberOK       bool
	// FieldNames are the datastream output field names, in display order.
	// Empty means the datastream has none. The builder copies the slice.
	FieldNames []string
	// HasInfo is set by the host when the datastream has extra info to show.
	// The library stores the bit and does not decide which fields count.
	HasInfo   bool
	Intervals []Interval
}

Datastream is one searchable row. Set StationID, or set Intervals for a site-attached datastream, not both. OrganizationID is required and must match the builder. Doc ids are assigned in AddDatastream order.

type FinishMode

type FinishMode int

FinishMode selects which shard Finish writes. The index stays in place, so Finish may be called again with the other mode.

const (
	// FinishPrivate writes shown and exact boxes and every accepted datastream.
	FinishPrivate FinishMode = iota
	// FinishPublic writes exact boxes and points copied from shown, and
	// public_ok datastreams only. Sites with no public datastream are omitted.
	FinishPublic
)

type Fixture

type Fixture struct {
	Name          string
	Seed          int64
	Orgs          int
	Sites         int
	Datastreams   int
	Blobs         [][]byte
	DocCounts     []uint32
	ShiftedSiteID string
	ShiftedExact  Point
	ShiftedShown  Point
	Finish        time.Duration
}

Fixture is a deterministic catalog of shard bytes.

func Generate

func Generate(spec Spec) (Fixture, error)

Generate builds shard bytes for spec. Coordinates come from FixtureSeed.

func LargeCatalog

func LargeCatalog() (Fixture, error)

LargeCatalog is ten times TodayCatalog.

func LargeOrg

func LargeOrg() (Fixture, error)

LargeOrg is ten times TodayOrg.

func TodayCatalog

func TodayCatalog() (Fixture, error)

TodayCatalog is the public catalog, rounded.

func TodayOrg

func TodayOrg() (Fixture, error)

TodayOrg is about one organization in the public census.

type Hit

type Hit struct {
	DocID            uint32
	DatastreamID     string
	Name             string
	OrganizationID   string
	OrganizationName string
	StationID        string
	StationName      string
	SiteID           string
	SiteName         string
	UnitName         string
	Measurement      string
	Purpose          string
	FieldNames       []string
	// HasInfo is the forward-row bit the host set. It does not name a field.
	HasInfo bool
	// BeginsAt and EndsBefore are the outer deployment window, Unix
	// milliseconds. EndsBefore is 0 when the last deployment is still open.
	// They do not follow the query window or the site on this hit.
	BeginsAt   int64
	EndsBefore int64
}

Hit is one matching datastream in doc id order.

type Interval

type Interval struct {
	SiteID     string
	BeginsAt   int64
	EndsBefore int64
	GroupID    string
}

Interval is a half-open deployment [BeginsAt, EndsBefore) in Unix milliseconds. EndsBefore == 0 means the interval is still open, the same as an unset ends_before on the wire. A non-zero EndsBefore means the deployment has ended. A datastream has at most one open interval. Every interval may be closed. GroupID is optional. Empty means the interval has no group. The builder stores the id and does not look up a name.

type KeepEntry

type KeepEntry struct {
	ObjectKey string    `json:"object_key"`
	Until     time.Time `json:"until"`
}

KeepEntry is one version bin the tidy pass must spare until Until.

type Kind

type Kind int

Kind is the map layer for a result.

const (
	KindClusters Kind = 1
	KindSites    Kind = 2
)

func (Kind) String

func (k Kind) String() string

type PickerRow

type PickerRow struct {
	ID   string
	Name string
	Grey bool
}

PickerRow is one visible picker row. Grey means the row is checked, the other side has at least one check, and this id is not relevant. The host keeps that check until the user clears it.

func ReducePicker

func ReducePicker(orgs, groups []CatalogName, checkedOrgs, checkedGroups []string, groupsByOrg map[string][]string) (orgRows, groupRows []PickerRow)

ReducePicker builds the organization list and the group list.

orgs and groups are the catalogs after the host's text filter, in the order to display. checkedOrgs and checkedGroups are the full check sets, including ids the text filter hid. A hidden check still narrows the other side and is omitted from the returned rows. groupsByOrg maps each visible organization to the group ids GroupIDs returned for it.

A checked id that is not in the catalog argument is omitted here. This function does not change the check sets. The host drops a check that is outside the unfiltered catalog.

Neither side checked: both lists are the filtered catalogs, and nothing is grey. Checking organizations whittles groups to the union of groupsByOrg for those organizations. Checking groups whittles organizations to those whose set intersects the checked groups. The two reductions are independent.

type Point

type Point struct {
	Lon, Lat float64
}

Point is a WGS84 digest point. Clustering uses this, not a centroid substituted for an area box.

type Query

type Query struct {
	Purpose      string
	Measurements []string
	SiteIDs      []string
	// GroupIDs filters intervals. Empty means every datastream, including
	// intervals with no group. Several ids are a union: a datastream matches
	// when one qualifying interval carries any listed id.
	GroupIDs          []string
	BeginsAt          int64
	EndsBefore        int64
	Viewport          *Box
	Geometry          string
	Zoom              uint32
	IncludeMemberOnly bool
	MapSiteLimit      uint32
	MinSiteZoom       uint32
	// AllHits returns every matching hit when the layer is sites, and no hit
	// rows when the layer is clusters. TotalCount is still set. PageSize and
	// PageAfter are ignored. HasMore is false.
	AllHits bool
	// PageSize is the maximum number of hits to return. Zero returns none.
	// TotalCount is still set. Ignored when AllHits is set.
	PageSize uint32
	// PageAfter is the first doc id to return, inclusive. Zero starts at the
	// beginning. Pass Result.NextPageAfter only when Result.HasMore is set.
	// The cursor is valid only for the byte slice this shard was opened from.
	PageAfter uint32
}

Query is one read of a shard. Empty slices and a nil viewport leave that predicate out. Both time bounds zero means the open deployment.

type Result

type Result struct {
	Kind              Kind
	Clusters          []Cluster
	Sites             []SiteMarker
	Candidates        []SiteMarker
	SiteTotal         uint32
	Bounds            Box
	SiteCounts        []Count
	MeasurementCounts []Count
	Hits              []Hit
	TotalCount        uint32
	NextPageAfter     uint32
	HasMore           bool
}

Result is the map layer for one shard, or for Combine. Candidates is the filtered site list before the cluster/site switch. Combine uses it. Measurement counts are always set. Site counts are set only for KindSites.

func Combine

func Combine(q Query, parts []Result) (Result, error)

Combine merges per-organization results and chooses the map layer once. Measurement counts are summed on every result. Site counts are summed only when the merged layer is sites. Hits are concatenated in the order of parts; paging stays on each shard. Pass the same query that produced the parts, including zoom and the site limit.

type Shard

type Shard struct {
	// contains filtered or unexported fields
}

Shard is an immutable index. Query may run from many goroutines. Open inserts both R-trees. Query allocates temporary bitmaps only.

func Open

func Open(b []byte) (*Shard, error)

Open unmarshals a shard and inserts each site's shown and exact box.

func (*Shard) DocCount

func (s *Shard) DocCount() int

DocCount is the number of datastreams in the shard.

func (*Shard) GroupIDs

func (s *Shard) GroupIDs(beginsAt, endsBefore int64, includeMemberOnly bool) ([]string, error)

GroupIDs returns the distinct group ids on in-play intervals of datastreams the caller may see. The result is sorted. Empty group ids are omitted. There is no count. Purpose, measurement, site, viewport, and Query.GroupIDs are not applied. includeMemberOnly false uses public_ok. True uses public_ok ∪ member_ok.

func (*Shard) Query

func (s *Shard) Query(q Query) (Result, error)

Query evaluates the predicates that are set. Shard bitmaps are not modified.

type Site

type Site struct {
	ID               string
	Name             string
	OrganizationID   string
	OrganizationName string
	Shown            Box
	Exact            Box
	ShownPoint       Point
	ExactPoint       Point
}

Site is one place in an organization shard. OrganizationID is required. Shown and Exact are both stored. Open inserts each box into its own R-tree.

type SiteMarker

type SiteMarker struct {
	SiteID           string
	Name             string
	OrganizationID   string
	OrganizationName string
	Point            Point
	Box              Box
	DatastreamCount  uint32
}

SiteMarker is one candidate site in the geometry the caller named.

type Spec

type Spec struct {
	Name        string
	Orgs        int
	Sites       int
	Datastreams int
}

Spec is one generated catalog.

type Station

type Station struct {
	ID             string
	Name           string
	OrganizationID string
	Intervals      []Interval
}

Station holds deployment intervals for station-attached datastreams. OrganizationID is required and must match the builder.

type VersionFile

type VersionFile struct {
	ObjectKey string      `json:"object_key"`
	ETag      string      `json:"etag"`
	Size      int64       `json:"size"`
	BuiltAt   time.Time   `json:"built_at,omitempty"`
	DocCount  *uint32     `json:"doc_count,omitempty"`
	IsEnabled *bool       `json:"is_enabled,omitempty"`
	IsHidden  *bool       `json:"is_hidden,omitempty"`
	PublicOK  *bool       `json:"public_ok,omitempty"`
	Encoding  string      `json:"encoding,omitempty"`
	Keep      []KeepEntry `json:"keep,omitempty"`
}

VersionFile is the current.json pointer for a shard or a container. An empty Encoding means the object is raw bytes. "gzip" is a label the caller sets; this struct does not compress.

func ParseVersionFile

func ParseVersionFile(b []byte) (VersionFile, error)

ParseVersionFile decodes a current.json pointer. Unknown fields are rejected.

func (VersionFile) Marshal

func (v VersionFile) Marshal() ([]byte, error)

Marshal encodes the pointer as JSON. An empty Encoding is omitted.

Directories

Path Synopsis
examples
bench command
Command bench runs the fixture matrix and writes BENCHMARKS.md.
Command bench runs the fixture matrix and writes BENCHMARKS.md.
demo command
Command demo builds a handful of sites and prints one cluster query and one site query, then the north and south group picker.
Command demo builds a handful of sites and prints one cluster query and one site query, then the north and south group picker.
map command
Command map serves the static Explore demo.
Command map serves the static Explore demo.
wasm command
Browser wrappers for Generate, Open, Query, and Combine.
Browser wrappers for Generate, Open, Query, and Combine.
Product browser host for Explore.
Product browser host for Explore.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL