core

package
v1.0.0 Latest Latest
Warning

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

Go to latest
Published: Dec 17, 2020 License: Apache-2.0 Imports: 10 Imported by: 2

Documentation

Index

Constants

View Source
const AnonymousMagicNumber = -2

AnonymousMagicNumber is a magic number, means that we don't know the process id of a history event

View Source
const NemesisProcessMagicNumber = -1

NemesisProcessMagicNumber is a magic number to stand for nemesis related event on a history

Variables

View Source
var Models = MapToDirectedGraph(map[Vertex][]Vertex{
	Vertex{"causal-cerone"}:                     {{"read-atomic"}},
	Vertex{"consistent-view"}:                   {{"cursor-stability"}, {"monotonic-view"}},
	Vertex{"conflict-serializable"}:             {{"view-serializable"}},
	Vertex{"cursor-stability"}:                  {{"read-committed"}, {"PL-2"}},
	Vertex{"forward-consistent-view"}:           {{"consistent-view"}, {"PL-1"}},
	Vertex{"PL-3"}:                              {{"repeatable-read"}, {"update-serializable"}},
	Vertex{"update-serializable"}:               {{"forward-consistent-view"}},
	Vertex{"monotonic-atomic-view"}:             {{"read-committed"}},
	Vertex{"monotonic-view"}:                    {{"PL-2"}},
	Vertex{"monotonic-snapshot-read"}:           {{"PL-2"}},
	Vertex{"parallel-snapshot-isolation"}:       {{"causal-cerone"}},
	Vertex{"prefix"}:                            {{"causal-cerone"}},
	Vertex{"read-committed"}:                    {{"read-uncommitted"}},
	Vertex{"repeatable-read"}:                   {{"cursor-stability"}, {"monotonic-atomic-view"}},
	Vertex{"serializable"}:                      {{"repeatable-read"}, {"snapshot-isolation"}, {"view-serializable"}},
	Vertex{"session-serializable"}:              {{"1SR"}},
	Vertex{"snapshot-isolation"}:                {{"forward-consistent-view"}, {"monotonic-atomic-view"}, {"monotonic-snapshot-read"}, {"parallel-snapshot-isolation"}, {"prefix"}},
	Vertex{"strict-serializable"}:               {{"PL-3"}, {"serializable"}, {"linearizable"}, {"snapshot-isolation"}, {"strong-session-serializable"}},
	Vertex{"strong-serializable"}:               {{"session-serializable"}},
	Vertex{"strong-session-serializable"}:       {{"serializable"}},
	Vertex{"strong-session-snapshot-isolation"}: {{"snapshot-isolation"}},
	Vertex{"strong-snapshot-isolation"}:         {{"strong-session-snapshot-isolation"}},
	Vertex{"linearizable"}:                      {{"sequential"}},
	Vertex{"causal"}:                            {{"writes-follow-reads"}},
	Vertex{"causal"}:                            {{"writes-follow-reads"}, {"PRAM"}},
	Vertex{"PRAM"}:                              {{"monotonic-reads"}, {"monotonic-writes"}, {"read-your-writes"}},
}).MapVertices(canonicalModelName)

Models sees https://jepsen.io/consistency for sources.

Functions

func AllAnomaliesImplying

func AllAnomaliesImplying(anomalies []string) (res []string)

AllAnomaliesImplying yields a set of anomalies which would imply any of those anomalies

func AllImpliedAnomalies

func AllImpliedAnomalies(anomalies []string) (res []string)

AllImpliedAnomalies yields a set of anomalies implied by those

func AnomaliesProhibitedBy

func AnomaliesProhibitedBy(models []string) []string

AnomaliesProhibitedBy takes a collection of consistency models, and returns a set of anomalies

which can't be present if all of those models are to hold

func FriendlyBoundary

func FriendlyBoundary(anomalies []string) (not []string, alsoNot []string)

FriendlyBoundary takes a set of anomalies, and yields not and alsoNot where not is the weakest set of consistency models invalidated by the given anomaly, and alsoNot is the remaining set of stronger models

func MonotonicKeyGraph

func MonotonicKeyGraph(history History) (Anomalies, *DirectedGraph, DataExplainer)

MonotonicKeyGraph analyzes monotonic key

func ProcessGraph

func ProcessGraph(history History, _ ...interface{}) (Anomalies, *DirectedGraph, DataExplainer)

ProcessGraph analyzes process

func RealtimeGraph

func RealtimeGraph(history History, _ ...interface{}) (Anomalies, *DirectedGraph, DataExplainer)

RealtimeGraph analyzes real-time.

func Set

func Set(slice []string) []string

Set export set

func WriteCycles

func WriteCycles(cexp CycleExplainer, exp DataExplainer, dir, filename string, cycles []string)

WriteCycles ... TODO: implement it.

Types

type Analyzer

type Analyzer func(history History, opts ...interface{}) (Anomalies, *DirectedGraph, DataExplainer)

Analyzer is a function which takes a history and returns a {:graph, :explainer, :anomalies} map; e.g. realtime-graph.

func Combine

func Combine(analyzers ...Analyzer) Analyzer

Combine composes multiple analyzers

type Anomalies

type Anomalies map[string][]Anomaly

Anomalies groups anomalies by there names

func (Anomalies) Keys

func (a Anomalies) Keys() (keys []string)

Keys returns all keys of Anomalies

func (Anomalies) Merge

func (a Anomalies) Merge(another Anomalies)

Merge merges another anomalies

func (Anomalies) SelectKeys

func (a Anomalies) SelectKeys(anomalyNames map[string]struct{}) Anomalies

SelectKeys selects specified keys and return a new Anomalies

type Anomaly

type Anomaly interface {
	IAnomaly()
}

Anomaly unifies all kinds of Anomalies, like G1a, G1b, dirty update etc.

type BFSPath

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

BFSPath ...

func NewBFSPath

func NewBFSPath(graph *DirectedGraph, start Vertex, sccSet map[Vertex]struct{}) *BFSPath

NewBFSPath ...

func (*BFSPath) DistFrom

func (path *BFSPath) DistFrom(vertex Vertex) int

DistFrom ...

func (*BFSPath) HasPathFrom

func (path *BFSPath) HasPathFrom(vertex Vertex) bool

HasPathFrom ...

func (*BFSPath) PathFrom

func (path *BFSPath) PathFrom(vertex Vertex) []CycleTrace

PathFrom ...

type CheckResult

type CheckResult struct {
	Graph     DirectedGraph
	Explainer DataExplainer
	Cycles    []string // string explaining the cycle
	Sccs      []SCC
	Anomalies Anomalies
}

CheckResult records the check result

func Check

func Check(analyzer Analyzer, history History, opts ...interface{}) CheckResult

Check receives analyzer and a history, returns a map of {graph, explainer, cycles, sccs, anomalies}

type Circle

type Circle struct {
	// Eg. [2, 1, 2] means a circle: 2 -> 1 -> 2
	Path []PathType
}

Circle ...

func NewCircle

func NewCircle(vertices []Vertex) *Circle

NewCircle returns a Circle from a Vertex slice

type CombinedExplainer

type CombinedExplainer struct {
	Explainers []DataExplainer
	// contains filtered or unexported fields
}

CombinedExplainer struct

func NewCombineExplainer

func NewCombineExplainer(explainers []DataExplainer) *CombinedExplainer

NewCombineExplainer builds a CombinedExplainer according to a explainer array

func (*CombinedExplainer) ExplainPairData

func (c *CombinedExplainer) ExplainPairData(p1, p2 PathType) ExplainResult

ExplainPairData find dependencies in a and b

func (*CombinedExplainer) RenderExplanation

func (c *CombinedExplainer) RenderExplanation(result ExplainResult, p1, p2 string) string

RenderExplanation render explanation result

type ConsistencyModelName

type ConsistencyModelName = string

ConsistencyModelName defines the consistency model name

type CycleExplainer

type CycleExplainer struct{}

CycleExplainer provides the step-by-step explanation of the relationships between pairs of operations

func (*CycleExplainer) ExplainCycle

func (c *CycleExplainer) ExplainCycle(explainer DataExplainer, circle Circle) CycleExplainerResult

ExplainCycle for a circle

func (*CycleExplainer) RenderCycleExplanation

func (c *CycleExplainer) RenderCycleExplanation(explainer DataExplainer, cr CycleExplainerResult) string

RenderCycleExplanation ...

type CycleExplainerResult

type CycleExplainerResult struct {
	Circle Circle
	Steps  []Step
	Typ    string
}

CycleExplainerResult impls Anomaly

func (CycleExplainerResult) IAnomaly

func (c CycleExplainerResult) IAnomaly()

IAnomaly ...

func (CycleExplainerResult) String

func (c CycleExplainerResult) String() string

String ...

func (CycleExplainerResult) Type

func (c CycleExplainerResult) Type() string

Type ...

type CyclePredicate

type CyclePredicate func(trace []CycleTrace) bool

CyclePredicate is a predication on a CycleTrace

type CycleTrace

type CycleTrace struct {
	Rels []Rel
	// contains filtered or unexported fields
}

CycleTrace records a cycle path

type DataExplainer

type DataExplainer interface {
	// Given a pair of operations a and b, explains why b depends on a, in the
	//    form of a data structure. Returns `nil` if b does not depend on a.
	ExplainPairData(p1, p2 PathType) ExplainResult
	// Given a pair of operations, and short names for them, explain why b
	//  depends on a, as a string. `nil` indicates that b does not depend on a.
	RenderExplanation(result ExplainResult, preName, postName string) string
}

DataExplainer ...

type DependType

type DependType string

DependType records the depend type of a relation

const (
	// RealtimeDepend ...
	RealtimeDepend DependType = "realtime"
	// MonotonicDepend ...
	MonotonicDepend DependType = "monotonic"
	// ProcessDepend ...
	ProcessDepend DependType = "process"
	// WWDepend ...
	WWDepend DependType = "ww"
	// WRDepend ...
	WRDepend DependType = "wr"
	// RWDepend ...
	RWDepend DependType = "rw"
)

type DirectedGraph

type DirectedGraph struct {
	Outs map[Vertex]map[Vertex][]Rel
	Ins  map[Vertex][]Vertex
}

DirectedGraph is a directed graph type

func DigraphUnion

func DigraphUnion(graphs ...*DirectedGraph) *DirectedGraph

DigraphUnion takes the union of n graphs, merging edges with union

func MapToDirectedGraph

func MapToDirectedGraph(m map[Vertex][]Vertex) *DirectedGraph

MapToDirectedGraph turns a sequence of [node, successors] map into a directed graph

func MonotonicKeyOrder

func MonotonicKeyOrder(history History, k string) *DirectedGraph

MonotonicKeyOrder find dependencies of a process

func NewDirectedGraph

func NewDirectedGraph() *DirectedGraph

NewDirectedGraph returns a empty DirectedGraph

func ProcessOrder

func ProcessOrder(history History, process int) *DirectedGraph

ProcessOrder find dependencies of a process

func (*DirectedGraph) Bfs

func (g *DirectedGraph) Bfs(initV []Vertex, out bool) []Vertex

Bfs searches from a vertices set, returns all vertices searchable out = true means search to downstream vertices from `out` edges out = false means search to upstream vertices from `in` edges

func (*DirectedGraph) BfsIn

func (g *DirectedGraph) BfsIn(initV []Vertex) []Vertex

BfsIn searches from a vertices set, returns all vertices searchable search to upstream vertices from `in` edges

func (*DirectedGraph) BfsOut

func (g *DirectedGraph) BfsOut(initV []Vertex) []Vertex

BfsOut searches from a vertices set, returns all vertices searchable search to downstream vertices from `out` edges

func (*DirectedGraph) Edges

func (g *DirectedGraph) Edges(a, b Vertex) []Edge

Edges returns the edge between two vertices

func (*DirectedGraph) FilterRelationships

func (g *DirectedGraph) FilterRelationships(rels []Rel) *DirectedGraph

FilterRelationships filters a graph g to just those edges which intersect with the given set of

relationships

func (*DirectedGraph) Fork

func (g *DirectedGraph) Fork() *DirectedGraph

Fork implements `forked` semantics on DirectedGraph

func (*DirectedGraph) In

func (g *DirectedGraph) In(v Vertex) []Vertex

In returns inbound vertices to v in graph g

func (*DirectedGraph) IsEmpty

func (g *DirectedGraph) IsEmpty() bool

IsEmpty return true if the graph has no vertices

func (g *DirectedGraph) Link(v Vertex, succ Vertex, rel Rel)

Link links two vertices relationship create edge from v => succ

func (*DirectedGraph) LinkAllTo

func (g *DirectedGraph) LinkAllTo(xs []Vertex, y Vertex, rel Rel)

LinkAllTo links all xs to y

func (*DirectedGraph) LinkAllToAll

func (g *DirectedGraph) LinkAllToAll(xs []Vertex, ys []Vertex, rel Rel)

LinkAllToAll links all xs to ys

func (*DirectedGraph) LinkToAll

func (g *DirectedGraph) LinkToAll(x Vertex, ys []Vertex, rel Rel)

LinkToAll links x to all ys

func (*DirectedGraph) MapVertices

func (g *DirectedGraph) MapVertices(f func(interface{}) interface{}) *DirectedGraph

MapVertices takes a function of vertices, returns graph with all

vertices mapped via f

func (*DirectedGraph) Out

func (g *DirectedGraph) Out(v Vertex) []Vertex

Out returns outbound vertices from v in graph g

func (*DirectedGraph) ProjectRelationship

func (g *DirectedGraph) ProjectRelationship(rel Rel) *DirectedGraph

ProjectRelationship filters a graph to just those edges with the given relationship

func (*DirectedGraph) RenumberGraph

func (g *DirectedGraph) RenumberGraph() (*DirectedGraph, func(interface{}) interface{})

RenumberGraph takes a Graph and rewrites each vertex to a unique integer, returning the

rewritten Graph, and a vector of the original vertices for reconstruction.

That means if we apply MapVertices to dg with remap, it can recover to g again

func (DirectedGraph) String

func (g DirectedGraph) String() string

func (*DirectedGraph) StronglyConnectedComponents

func (g *DirectedGraph) StronglyConnectedComponents() []SCC

StronglyConnectedComponents finds all strongly connected components, greater than 1 element

func (g *DirectedGraph) UnLink(a, b Vertex)

UnLink unlinks vertex a and b

func (*DirectedGraph) UnLinkSelfEdges

func (g *DirectedGraph) UnLinkSelfEdges(xs []Vertex)

UnLinkSelfEdges unlinks edges from a to a

func (*DirectedGraph) Vertices

func (g *DirectedGraph) Vertices() []Vertex

Vertices returns the set of all vertices in graph

type Edge

type Edge struct {
	From  Vertex
	To    Vertex
	Value Rel // raw value of edge
}

Edge is a intermediate representation of edge on DirectedGraph

type ExplainResult

type ExplainResult interface {
	Type() DependType
}

ExplainResult is an interface, contains rwExplainerResult, wwExplainerResult wr ExplainerResult etc

type History

type History []Op

History contains operations

func FilterFailedHistory

func FilterFailedHistory(history History) History

FilterFailedHistory ...

func FilterOkHistory

func FilterOkHistory(history History) History

FilterOkHistory ...

func FilterOkOrInfoHistory

func FilterOkOrInfoHistory(history History) History

FilterOkOrInfoHistory ...

func FilterOutNemesisHistory

func FilterOutNemesisHistory(history History) History

FilterOutNemesisHistory ...

func ParseHistory

func ParseHistory(content string) (History, error)

ParseHistory parse history from elle's row text

func (History) AttachIndexIfNoExists

func (h History) AttachIndexIfNoExists()

AttachIndexIfNoExists add the index for history with it's number in array.

func (History) FilterProcess

func (h History) FilterProcess(p int) History

FilterProcess filter by process

func (History) FilterType

func (h History) FilterType(t OpType) History

FilterType filter by type

func (History) GetKeys

func (h History) GetKeys(t MopType) []string

GetKeys get keys by a given type MopTypeAll to get keys of all types

type ICycleExplainer

type ICycleExplainer interface {
	ExplainCycle(pairExplainer DataExplainer, circle Circle) CycleExplainerResult
	RenderCycleExplanation(explainer DataExplainer, cr CycleExplainerResult) string
}

ICycleExplainer is an interface

type IntOptional

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

IntOptional is an optional int.

func NewOptInt

func NewOptInt(v int) IntOptional

NewOptInt creates an optional.Int from a int.

func (IntOptional) GetOr

func (i IntOptional) GetOr(defv int) int

GetOr gets the value of return the defv if not present

func (IntOptional) MarshalJSON

func (i IntOptional) MarshalJSON() ([]byte, error)

MarshalJSON ...

func (IntOptional) MustGet

func (i IntOptional) MustGet() int

MustGet gets values or panic if isn't present

func (IntOptional) Present

func (i IntOptional) Present() bool

Present returns whether or not the value is present.

func (*IntOptional) Set

func (i *IntOptional) Set(v int)

Set sets the int value.

func (IntOptional) String

func (i IntOptional) String() string

func (*IntOptional) UnmarshalJSON

func (i *IntOptional) UnmarshalJSON(data []byte) error

UnmarshalJSON ...

type KVEntity

type KVEntity struct {
	K string
	V interface{}
}

KVEntity struct

func (KVEntity) String

func (kv KVEntity) String() string

type MonotonicKeyExplainer

type MonotonicKeyExplainer struct{}

MonotonicKeyExplainer ... Note: MonotonicKey is used on rw_register, so I don't explain it currently.

func (MonotonicKeyExplainer) ExplainPairData

func (e MonotonicKeyExplainer) ExplainPairData(p1, p2 PathType) ExplainResult

ExplainPairData ...

func (MonotonicKeyExplainer) RenderExplanation

func (e MonotonicKeyExplainer) RenderExplanation(result ExplainResult, preName, postName string) string

RenderExplanation render explanation

type Mop

type Mop struct {
	T MopType                `json:"type"`
	M map[string]interface{} `json:"m"`
}

Mop interface

func Append

func Append(key string, value int) Mop

Append implements Mop

func Read

func Read(key string, values []int) Mop

Read ...

func (Mop) Copy

func (m Mop) Copy() Mop

Copy ...

func (Mop) GetKey

func (m Mop) GetKey() string

GetKey ...

func (Mop) GetMopType

func (m Mop) GetMopType() MopType

GetMopType ...

func (Mop) GetValue

func (m Mop) GetValue() MopValueType

GetValue ...

func (Mop) IsAppend

func (m Mop) IsAppend() bool

IsAppend ...

func (Mop) IsEqual

func (m Mop) IsEqual(n Mop) bool

IsEqual ...

func (Mop) IsRead

func (m Mop) IsRead() bool

IsRead ...

func (Mop) IsWrite

func (m Mop) IsWrite() bool

IsWrite ...

func (Mop) String

func (m Mop) String() string

String ...

type MopType

type MopType string

MopType ...

const (
	MopTypeAll     MopType = "all"
	MopTypeAppend  MopType = "append"
	MopTypeRead    MopType = "read"
	MopTypeWrite   MopType = "write"
	MopTypeUnknown MopType = "unknown"
)

MopType enums

type MopValueType

type MopValueType interface{}

MopValueType ...

type Op

type Op struct {
	Index   IntOptional `json:"index,omitempty"`
	Process IntOptional `json:"process,omitempty"`
	Time    time.Time   `json:"time"`
	Type    OpType      `json:"type"`
	Value   *[]Mop      `json:"value"`
	Error   string      `json:"error,omitempty"`
}

Op is operation

func ParseOp

func ParseOp(opString string) (Op, error)

ParseOp parse operation from elle's row text TODO: parse process and time field (they are optional)

func (Op) Copy

func (op Op) Copy() Op

Copy ...

func (*Op) HasMopType

func (op *Op) HasMopType(tp MopType) bool

HasMopType ...

func (Op) String

func (op Op) String() string

func (Op) ValueLength

func (op Op) ValueLength() int

ValueLength ...

func (Op) WithIndex

func (op Op) WithIndex(i interface{}) Op

WithIndex ...

func (Op) WithProcess

func (op Op) WithProcess(p interface{}) Op

WithProcess ...

func (Op) WithType

func (op Op) WithType(tp OpType) Op

WithType ...

type OpBinding

type OpBinding struct {
	Operation Op
	Name      string
}

OpBinding binds the operation with Txx name

type OpType

type OpType string

OpType ...

const (
	OpTypeInvoke  OpType = "invoke"
	OpTypeOk      OpType = "ok"
	OpTypeFail    OpType = "fail"
	OpTypeInfo    OpType = "info"
	OpTypeUnknown OpType = "unknown"
)

OpType enums

type PathType

type PathType = Op

PathType type aliases Op

func (PathType) IndexOfMop

func (op PathType) IndexOfMop(mop Mop) int

IndexOfMop returns the index of mop in op

type ProcessExplainer

type ProcessExplainer struct{}

ProcessExplainer ...

func (ProcessExplainer) ExplainPairData

func (e ProcessExplainer) ExplainPairData(p1, p2 PathType) ExplainResult

ExplainPairData explain pair data

func (ProcessExplainer) RenderExplanation

func (e ProcessExplainer) RenderExplanation(result ExplainResult, preName, postName string) string

RenderExplanation render explanation

type ProcessResult

type ProcessResult struct {
	Process int
}

ProcessResult ...

func (ProcessResult) Type

func (ProcessResult) Type() DependType

Type ...

type RealtimeExplainResult

type RealtimeExplainResult struct {
	PreEnd    Op
	PostStart Op
}

RealtimeExplainResult records a real time explain result

func (RealtimeExplainResult) Type

Type ...

type RealtimeExplainer

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

RealtimeExplainer is Realtime order explainer

func (RealtimeExplainer) ExplainPairData

func (r RealtimeExplainer) ExplainPairData(preEnd, postEnd PathType) ExplainResult

ExplainPairData ...

func (RealtimeExplainer) RenderExplanation

func (r RealtimeExplainer) RenderExplanation(result ExplainResult, preName, postName string) string

RenderExplanation ...

type Rel

type Rel string

Rel stands for relation in dependencies

const (
	Empty        Rel = ""
	WW           Rel = "ww"
	WR           Rel = "wr"
	RW           Rel = "rw"
	Process      Rel = "process"
	Realtime     Rel = "realtime"
	ExtKey       Rel = "ext-key"
	Version      Rel = "version"
	InitialState Rel = "initial-state"
	WFR          Rel = "write-follow-read"
	// Note: currently we don't support MonotonicKey
	MonotonicKey Rel = "monotonic-key"
)

Rel enums

func IntersectionRel

func IntersectionRel(rels1 []Rel, rels2 []Rel) []Rel

IntersectionRel returns the intersection of res1 and res2

type RelSet

type RelSet []Rel

RelSet type aliases []Rel

func (RelSet) Append

func (r RelSet) Append(rels map[Rel]struct{}) (rs RelSet)

Append returns a new RelSet contains the old and appended relations

func (RelSet) Len

func (r RelSet) Len() int

func (RelSet) Less

func (r RelSet) Less(i, j int) bool

func (RelSet) Swap

func (r RelSet) Swap(i, j int)

type Rels

type Rels []Rel

Rels type aliases []Rel

type SCC

type SCC struct {
	Vertices []Vertex
}

SCC indexes all vertices of a strongly connected component

type SameKeyOpsByLength

type SameKeyOpsByLength [][]MopValueType

SameKeyOpsByLength ...

func (SameKeyOpsByLength) Len

func (b SameKeyOpsByLength) Len() int

func (SameKeyOpsByLength) Less

func (b SameKeyOpsByLength) Less(i, j int) bool

func (SameKeyOpsByLength) Swap

func (b SameKeyOpsByLength) Swap(i, j int)

type Step

type Step struct {
	Result ExplainResult
}

Step saves a explain result of one step of a cycle

type Vertex

type Vertex struct {
	Value interface{}
}

Vertex is a vertex on the directed graph

func FindCycle

func FindCycle(graph *DirectedGraph, scc SCC) []Vertex

FindCycle receives a graph and a scc, finds a short cycle in that component

func FindCycleStartingWith

func FindCycleStartingWith(graph *DirectedGraph, scc SCC, first Rel, rest []Rel) []Vertex

FindCycleStartingWith ...

func FindCycleWith

func FindCycleWith(graph *DirectedGraph, scc SCC, isWith CyclePredicate) []Vertex

FindCycleWith ...

func (Vertex) String

func (v Vertex) String() string

type Vertices

type Vertices []Vertex

Vertices type aliases []Vertex

func NewVerticesFromOp

func NewVerticesFromOp(items []Op) Vertices

NewVerticesFromOp ...

func (Vertices) Len

func (v Vertices) Len() int

Len ...

func (Vertices) Less

func (v Vertices) Less(i, j int) bool

Less ...

func (Vertices) Swap

func (v Vertices) Swap(i, j int)

Swap ...

Jump to

Keyboard shortcuts

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