// Package limits provides the engine's topology ceilings and reusable work// accounting primitives. It deliberately has no dependency on graph, layout,// or routing types so every layout domain can consume the same limits without// introducing package cycles.
package limitsimport ()const (// MaxEngineNodes is the largest node count the engine processes in one attempt.MaxEngineNodes = 10_000// MaxEngineEdges is the largest edge count the engine processes in one attempt.MaxEngineEdges = 50_000// MaxEngineRoutePoints bounds aggregate route storage throughout the engine.MaxEngineRoutePoints = 1_000_000// MaxEngineTreeDepth bounds recursive topology throughout the engine.MaxEngineTreeDepth = 256// MaxGraphSize is the maximum supported width or height at a pipeline stage // boundary.MaxGraphSize = 30_000 contextCheckStride = 64 cancellableContextCheckStride = 1024 workUnitsPerEntity = 1_024// MaxEngineWorkUnits is the default aggregate work budget for a graph.MaxEngineWorkUnits = int64(MaxEngineNodes+MaxEngineEdges) * workUnitsPerEntity// MaxTransactionWorkUnits allows a complete layout transaction to compare // many nearby placements without resetting the ordinary engine budget for // every candidate.MaxTransactionWorkUnitsint64 = 1_000_000_000// MaxTransactionOverlapReferences bounds retained existing-overlap // references. Exceptions are retained in both directions because hot // placement checks key by the moved node.MaxTransactionOverlapReferencesint64 = 4_000_000// MaxBinPackWorkUnits spans the complete recursive bin-packing operation, // including speculative transactions and route scans.MaxBinPackWorkUnitsint64 = 1_000_000_000// MaxPlaceTreesWorkUnits is calibrated for the superlinear candidate and // obstacle work performed by tree placement.MaxPlaceTreesWorkUnitsint64 = 68_000_000// MaxLabelPlacementWorkUnits bounds the quadratic overlap and candidate // search performed while positioning labels and icons.MaxLabelPlacementWorkUnitsint64 = 50_000_000)// WorkGuard accounts a complete operation's signed work units and polls its// context at a fixed stride. The limit is an explicit non-negative ceiling;// zero permits cancellation checks but no charged work.typeWorkGuardstruct { ctx context.Context done <-chanstruct{} location string used int64 limit int64}// NewWorkGuard constructs a work guard and observes cancellation before any// operation work begins.func ( context.Context, string, int64) (*WorkGuard, error) {if == nil {returnnil, fmt.Errorf("TALA %s requires a context", ) }if < 0 {returnnil, fmt.Errorf("TALA %s work limit must not be negative", ) } := &WorkGuard{ctx: ,done: .Done(),location: ,limit: , }if := .Finish(); != nil {returnnil, }return , nil}// Step charges one work unit.func ( *WorkGuard) () error { .used++if .used > .limit {returnfmt.Errorf("TALA %s work exceeds limit %d", .location, .limit, ) }return .checkAtStride()}// Add records multiple work units as one accounting operation. It enforces// Step's work limit and polls cancellation when the accepted charge reaches or// crosses a Step polling boundary. On a positive-limit overflow, Used reports// the first rejected unit even when a crossed boundary observes cancellation.func ( *WorkGuard) ( int64) error {if < 0 {returnfmt.Errorf("TALA %s work charge must not be negative", .location) }if > .limit || .used > .limit- { := .used .used = .limit + 1 := .pollingStride()if <= .limit && / != .limit/ {if := .Check(); != nil {return } }returnfmt.Errorf("TALA %s work exceeds limit %d", .location, .limit) } := .used .used += return .checkAfterAdd()}func ( *WorkGuard) ( int64) error { := .pollingStride()// Add(0) polls an exact boundary; positive charges also poll when their // interval crosses one.if .used% != 0 && / == .used/ {returnnil }return .Check()}func ( *WorkGuard) () error { := .pollingStride()if .used% != 0 {returnnil }return .Check()}func ( *WorkGuard) () int64 {if .done == nil {// Contexts without Done need the shorter stride because cancellation is // observable only by polling Err.returncontextCheckStride }returncancellableContextCheckStride}// Check observes cancellation immediately. Step and Add use a bounded stride// in hot loops, while callers use Check at explicit cancellation boundaries.func ( *WorkGuard) () error {if := cachedContextErr(.ctx, .done); != nil {returnfmt.Errorf("%s: %w", .location, ) }returnnil}// Finish observes cancellation regardless of the current work count.func ( *WorkGuard) () error {return .Check()}// SetLimit changes the ceiling without resetting already consumed work.func ( *WorkGuard) ( int64) { .limit = }// Used returns the number of charged or first-rejected work units.func ( *WorkGuard) () int64 {return .used}// cachedContextErr avoids repeatedly traversing context value wrappers in hot// guarded loops. Standard cancellable contexts close Done before Err becomes// observable. Context implementations without a Done channel retain per-call// Err polling, which also preserves synthetic cancellation contexts.func cachedContextErr( context.Context, <-chanstruct{}) error {if == nil {return .Err() }select {case<-:return .Err()default:returnnil }}
The pages are generated with Goldsv0.8.7. (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu.
PR and bug reports are welcome and can be submitted to the issue list.
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds.