atomic

package module
v1.11.6 Latest Latest
Warning

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

Go to latest
Published: Feb 18, 2024 License: MIT Imports: 7 Imported by: 4

README

atomic GoDoc Build Status Coverage Status Go Report Card

Simple wrappers for primitive types to enforce atomic access.

Installation

$ go get -u github.com/p9ds/atomic@v1
Legacy Import Path

As of v1.5.0, the import path github.com/p9ds/atomic is the only supported way of using this package. If you are using Go modules, this package will fail to compile with the legacy import path path github.com/uber-go/atomic.

We recommend migrating your code to the new import path but if you're unable to do so, or if your dependencies are still using the old import path, you will have to add a replace directive to your go.mod file downgrading the legacy import path to an older version.

replace github.com/uber-go/atomic => github.com/uber-go/atomic v1.4.0

You can do so automatically by running the following command.

$ go mod edit -replace github.com/uber-go/atomic=github.com/uber-go/atomic@v1.4.0

Usage

The standard library's sync/atomic is powerful, but it's easy to forget which variables must be accessed atomically. github.com/p9ds/atomic preserves all the functionality of the standard library, but wraps the primitive types to provide a safer, more convenient API.

var atom atomic.Uint32
atom.Store(42)
atom.Sub(2)
atom.CompareAndSwap(40, 11)

See the documentation for a complete API specification.

Development Status

Stable.


Released under the MIT License.

Documentation

Overview

Package atomic provides simple wrappers around numerics to enforce atomic access.

Example
Output:

43
true
0

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Bool

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

Bool is an atomic type-safe wrapper for bool values.

func NewBool

func NewBool(val bool) *Bool

NewBool creates a new Bool.

func (*Bool) CAS deprecated added in v1.3.0

func (x *Bool) CAS(old, new bool) (swapped bool)

CAS is an atomic compare-and-swap for bool values.

Deprecated: Use CompareAndSwap.

func (*Bool) CompareAndSwap added in v1.9.1

func (x *Bool) CompareAndSwap(old, new bool) (swapped bool)

CompareAndSwap is an atomic compare-and-swap for bool values.

func (*Bool) Load

func (x *Bool) Load() bool

Load atomically loads the wrapped bool.

func (*Bool) MarshalJSON added in v1.9.1

func (x *Bool) MarshalJSON() ([]byte, error)

MarshalJSON encodes the wrapped bool into JSON.

func (*Bool) Store

func (x *Bool) Store(val bool)

Store atomically stores the passed bool.

func (*Bool) String added in v1.9.1

func (b *Bool) String() string

String encodes the wrapped value as a string.

func (*Bool) Swap

func (x *Bool) Swap(val bool) (old bool)

Swap atomically stores the given bool and returns the old value.

func (*Bool) Toggle

func (b *Bool) Toggle() (old bool)

Toggle atomically negates the Boolean and returns the previous value.

func (*Bool) UnmarshalJSON added in v1.9.1

func (x *Bool) UnmarshalJSON(b []byte) error

UnmarshalJSON decodes a bool from JSON.

type Duration added in v1.3.2

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

Duration is an atomic type-safe wrapper for time.Duration values.

func NewDuration added in v1.3.2

func NewDuration(val time.Duration) *Duration

NewDuration creates a new Duration.

func (*Duration) Add added in v1.3.2

func (d *Duration) Add(delta time.Duration) time.Duration

Add atomically adds to the wrapped time.Duration and returns the new value.

func (*Duration) CAS deprecated added in v1.3.2

func (x *Duration) CAS(old, new time.Duration) (swapped bool)

CAS is an atomic compare-and-swap for time.Duration values.

Deprecated: Use CompareAndSwap.

func (*Duration) CompareAndSwap added in v1.9.1

func (x *Duration) CompareAndSwap(old, new time.Duration) (swapped bool)

CompareAndSwap is an atomic compare-and-swap for time.Duration values.

func (*Duration) Load added in v1.3.2

func (x *Duration) Load() time.Duration

Load atomically loads the wrapped time.Duration.

func (*Duration) MarshalJSON added in v1.9.1

func (x *Duration) MarshalJSON() ([]byte, error)

MarshalJSON encodes the wrapped time.Duration into JSON.

func (*Duration) Store added in v1.3.2

func (x *Duration) Store(val time.Duration)

Store atomically stores the passed time.Duration.

func (*Duration) String added in v1.9.1

func (d *Duration) String() string

String encodes the wrapped value as a string.

func (*Duration) Sub added in v1.3.2

func (d *Duration) Sub(delta time.Duration) time.Duration

Sub atomically subtracts from the wrapped time.Duration and returns the new value.

func (*Duration) Swap added in v1.3.2

func (x *Duration) Swap(val time.Duration) (old time.Duration)

Swap atomically stores the given time.Duration and returns the old value.

func (*Duration) UnmarshalJSON added in v1.9.1

func (x *Duration) UnmarshalJSON(b []byte) error

UnmarshalJSON decodes a time.Duration from JSON.

type Error added in v1.4.0

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

Error is an atomic type-safe wrapper for error values.

func NewError added in v1.4.0

func NewError(val error) *Error

NewError creates a new Error.

func (*Error) CompareAndSwap added in v1.9.1

func (x *Error) CompareAndSwap(old, new error) (swapped bool)

CompareAndSwap is an atomic compare-and-swap for error values.

func (*Error) Load added in v1.4.0

func (x *Error) Load() error

Load atomically loads the wrapped error.

func (*Error) Store added in v1.4.0

func (x *Error) Store(val error)

Store atomically stores the passed error.

func (*Error) Swap added in v1.9.1

func (x *Error) Swap(val error) (old error)

Swap atomically stores the given error and returns the old value.

type Float32 added in v1.9.1

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

Float32 is an atomic type-safe wrapper for float32 values.

func NewFloat32 added in v1.9.1

func NewFloat32(val float32) *Float32

NewFloat32 creates a new Float32.

func (*Float32) Add added in v1.9.1

func (f *Float32) Add(delta float32) float32

Add atomically adds to the wrapped float32 and returns the new value.

func (*Float32) CAS deprecated added in v1.9.1

func (f *Float32) CAS(old, new float32) (swapped bool)

CAS is an atomic compare-and-swap for float32 values.

Deprecated: Use CompareAndSwap

func (*Float32) CompareAndSwap added in v1.9.1

func (f *Float32) CompareAndSwap(old, new float32) (swapped bool)

CompareAndSwap is an atomic compare-and-swap for float32 values.

Note: CompareAndSwap handles NaN incorrectly. NaN != NaN using Go's inbuilt operators but CompareAndSwap allows a stored NaN to compare equal to a passed in NaN. This avoids typical CompareAndSwap loops from blocking forever, e.g.,

for {
  old := atom.Load()
  new = f(old)
  if atom.CompareAndSwap(old, new) {
    break
  }
}

If CompareAndSwap did not match NaN to match, then the above would loop forever.

func (*Float32) Load added in v1.9.1

func (x *Float32) Load() float32

Load atomically loads the wrapped float32.

func (*Float32) MarshalJSON added in v1.9.1

func (x *Float32) MarshalJSON() ([]byte, error)

MarshalJSON encodes the wrapped float32 into JSON.

func (*Float32) Store added in v1.9.1

func (x *Float32) Store(val float32)

Store atomically stores the passed float32.

func (*Float32) String added in v1.9.1

func (f *Float32) String() string

String encodes the wrapped value as a string.

func (*Float32) Sub added in v1.9.1

func (f *Float32) Sub(delta float32) float32

Sub atomically subtracts from the wrapped float32 and returns the new value.

func (*Float32) Swap added in v1.9.1

func (x *Float32) Swap(val float32) (old float32)

Swap atomically stores the given float32 and returns the old value.

func (*Float32) UnmarshalJSON added in v1.9.1

func (x *Float32) UnmarshalJSON(b []byte) error

UnmarshalJSON decodes a float32 from JSON.

type Float64 added in v1.1.0

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

Float64 is an atomic type-safe wrapper for float64 values.

func NewFloat64 added in v1.1.0

func NewFloat64(val float64) *Float64

NewFloat64 creates a new Float64.

func (*Float64) Add added in v1.1.0

func (f *Float64) Add(delta float64) float64

Add atomically adds to the wrapped float64 and returns the new value.

func (*Float64) CAS deprecated added in v1.1.0

func (f *Float64) CAS(old, new float64) (swapped bool)

CAS is an atomic compare-and-swap for float64 values.

Deprecated: Use CompareAndSwap

func (*Float64) CompareAndSwap added in v1.9.1

func (f *Float64) CompareAndSwap(old, new float64) (swapped bool)

CompareAndSwap is an atomic compare-and-swap for float64 values.

Note: CompareAndSwap handles NaN incorrectly. NaN != NaN using Go's inbuilt operators but CompareAndSwap allows a stored NaN to compare equal to a passed in NaN. This avoids typical CompareAndSwap loops from blocking forever, e.g.,

for {
  old := atom.Load()
  new = f(old)
  if atom.CompareAndSwap(old, new) {
    break
  }
}

If CompareAndSwap did not match NaN to match, then the above would loop forever.

func (*Float64) Load added in v1.1.0

func (x *Float64) Load() float64

Load atomically loads the wrapped float64.

func (*Float64) MarshalJSON added in v1.9.1

func (x *Float64) MarshalJSON() ([]byte, error)

MarshalJSON encodes the wrapped float64 into JSON.

func (*Float64) Store added in v1.1.0

func (x *Float64) Store(val float64)

Store atomically stores the passed float64.

func (*Float64) String added in v1.9.1

func (f *Float64) String() string

String encodes the wrapped value as a string.

func (*Float64) Sub added in v1.1.0

func (f *Float64) Sub(delta float64) float64

Sub atomically subtracts from the wrapped float64 and returns the new value.

func (*Float64) Swap added in v1.9.1

func (x *Float64) Swap(val float64) (old float64)

Swap atomically stores the given float64 and returns the old value.

func (*Float64) UnmarshalJSON added in v1.9.1

func (x *Float64) UnmarshalJSON(b []byte) error

UnmarshalJSON decodes a float64 from JSON.

type Int32

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

Int32 is an atomic wrapper around int32.

func NewInt32

func NewInt32(val int32) *Int32

NewInt32 creates a new Int32.

func (*Int32) Add

func (i *Int32) Add(delta int32) int32

Add atomically adds to the wrapped int32 and returns the new value.

func (*Int32) CAS deprecated

func (i *Int32) CAS(old, new int32) (swapped bool)

CAS is an atomic compare-and-swap.

Deprecated: Use CompareAndSwap.

func (*Int32) CompareAndSwap added in v1.9.1

func (i *Int32) CompareAndSwap(old, new int32) (swapped bool)

CompareAndSwap is an atomic compare-and-swap.

func (*Int32) Dec

func (i *Int32) Dec() int32

Dec atomically decrements the wrapped int32 and returns the new value.

func (*Int32) Inc

func (i *Int32) Inc() int32

Inc atomically increments the wrapped int32 and returns the new value.

func (*Int32) Load

func (i *Int32) Load() int32

Load atomically loads the wrapped value.

func (*Int32) MarshalJSON added in v1.9.1

func (i *Int32) MarshalJSON() ([]byte, error)

MarshalJSON encodes the wrapped int32 into JSON.

func (*Int32) Store

func (i *Int32) Store(val int32)

Store atomically stores the passed value.

func (*Int32) String added in v1.9.1

func (i *Int32) String() string

String encodes the wrapped value as a string.

func (*Int32) Sub

func (i *Int32) Sub(delta int32) int32

Sub atomically subtracts from the wrapped int32 and returns the new value.

func (*Int32) Swap

func (i *Int32) Swap(val int32) (old int32)

Swap atomically swaps the wrapped int32 and returns the old value.

func (*Int32) UnmarshalJSON added in v1.9.1

func (i *Int32) UnmarshalJSON(b []byte) error

UnmarshalJSON decodes JSON into the wrapped int32.

type Int64

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

Int64 is an atomic wrapper around int64.

func NewInt64

func NewInt64(val int64) *Int64

NewInt64 creates a new Int64.

func (*Int64) Add

func (i *Int64) Add(delta int64) int64

Add atomically adds to the wrapped int64 and returns the new value.

func (*Int64) CAS deprecated

func (i *Int64) CAS(old, new int64) (swapped bool)

CAS is an atomic compare-and-swap.

Deprecated: Use CompareAndSwap.

func (*Int64) CompareAndSwap added in v1.9.1

func (i *Int64) CompareAndSwap(old, new int64) (swapped bool)

CompareAndSwap is an atomic compare-and-swap.

func (*Int64) Dec

func (i *Int64) Dec() int64

Dec atomically decrements the wrapped int64 and returns the new value.

func (*Int64) Inc

func (i *Int64) Inc() int64

Inc atomically increments the wrapped int64 and returns the new value.

func (*Int64) Load

func (i *Int64) Load() int64

Load atomically loads the wrapped value.

func (*Int64) MarshalJSON added in v1.9.1

func (i *Int64) MarshalJSON() ([]byte, error)

MarshalJSON encodes the wrapped int64 into JSON.

func (*Int64) Store

func (i *Int64) Store(val int64)

Store atomically stores the passed value.

func (*Int64) String added in v1.9.1

func (i *Int64) String() string

String encodes the wrapped value as a string.

func (*Int64) Sub

func (i *Int64) Sub(delta int64) int64

Sub atomically subtracts from the wrapped int64 and returns the new value.

func (*Int64) Swap

func (i *Int64) Swap(val int64) (old int64)

Swap atomically swaps the wrapped int64 and returns the old value.

func (*Int64) UnmarshalJSON added in v1.9.1

func (i *Int64) UnmarshalJSON(b []byte) error

UnmarshalJSON decodes JSON into the wrapped int64.

type Pointer added in v1.9.1

type Pointer[T any] struct {
	// contains filtered or unexported fields
}

Pointer is an atomic pointer of type *T.

func NewPointer added in v1.9.1

func NewPointer[T any](v *T) *Pointer[T]

NewPointer creates a new Pointer.

func (*Pointer[T]) CompareAndSwap added in v1.9.1

func (p *Pointer[T]) CompareAndSwap(old, new *T) (swapped bool)

CompareAndSwap is an atomic compare-and-swap.

func (*Pointer[T]) Load added in v1.9.1

func (p *Pointer[T]) Load() *T

Load atomically loads the wrapped value.

func (*Pointer[T]) Store added in v1.9.1

func (p *Pointer[T]) Store(val *T)

Store atomically stores the passed value.

func (*Pointer[T]) String added in v1.9.1

func (p *Pointer[T]) String() string

String returns a human readable representation of a Pointer's underlying value.

func (*Pointer[T]) Swap added in v1.9.1

func (p *Pointer[T]) Swap(val *T) (old *T)

Swap atomically swaps the wrapped pointer and returns the old value.

type String

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

String is an atomic type-safe wrapper for string values.

func NewString

func NewString(val string) *String

NewString creates a new String.

func (*String) CompareAndSwap added in v1.9.1

func (x *String) CompareAndSwap(old, new string) (swapped bool)

CompareAndSwap is an atomic compare-and-swap for string values.

func (*String) Load

func (x *String) Load() string

Load atomically loads the wrapped string.

func (*String) MarshalText added in v1.9.1

func (s *String) MarshalText() ([]byte, error)

MarshalText encodes the wrapped string into a textual form.

This makes it encodable as JSON, YAML, XML, and more.

func (*String) Store

func (x *String) Store(val string)

Store atomically stores the passed string.

func (*String) String added in v1.9.1

func (s *String) String() string

String returns the wrapped value.

func (*String) Swap added in v1.9.1

func (x *String) Swap(val string) (old string)

Swap atomically stores the given string and returns the old value.

func (*String) UnmarshalText added in v1.9.1

func (s *String) UnmarshalText(b []byte) error

UnmarshalText decodes text and replaces the wrapped string with it.

This makes it decodable from JSON, YAML, XML, and more.

type Time added in v1.9.1

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

Time is an atomic type-safe wrapper for time.Time values.

func NewTime added in v1.9.1

func NewTime(val time.Time) *Time

NewTime creates a new Time.

func (*Time) Load added in v1.9.1

func (x *Time) Load() time.Time

Load atomically loads the wrapped time.Time.

func (*Time) Store added in v1.9.1

func (x *Time) Store(val time.Time)

Store atomically stores the passed time.Time.

type Uint32

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

Uint32 is an atomic wrapper around uint32.

func NewUint32

func NewUint32(val uint32) *Uint32

NewUint32 creates a new Uint32.

func (*Uint32) Add

func (i *Uint32) Add(delta uint32) uint32

Add atomically adds to the wrapped uint32 and returns the new value.

func (*Uint32) CAS deprecated

func (i *Uint32) CAS(old, new uint32) (swapped bool)

CAS is an atomic compare-and-swap.

Deprecated: Use CompareAndSwap.

func (*Uint32) CompareAndSwap added in v1.9.1

func (i *Uint32) CompareAndSwap(old, new uint32) (swapped bool)

CompareAndSwap is an atomic compare-and-swap.

func (*Uint32) Dec

func (i *Uint32) Dec() uint32

Dec atomically decrements the wrapped uint32 and returns the new value.

func (*Uint32) Inc

func (i *Uint32) Inc() uint32

Inc atomically increments the wrapped uint32 and returns the new value.

func (*Uint32) Load

func (i *Uint32) Load() uint32

Load atomically loads the wrapped value.

func (*Uint32) MarshalJSON added in v1.9.1

func (i *Uint32) MarshalJSON() ([]byte, error)

MarshalJSON encodes the wrapped uint32 into JSON.

func (*Uint32) Store

func (i *Uint32) Store(val uint32)

Store atomically stores the passed value.

func (*Uint32) String added in v1.9.1

func (i *Uint32) String() string

String encodes the wrapped value as a string.

func (*Uint32) Sub

func (i *Uint32) Sub(delta uint32) uint32

Sub atomically subtracts from the wrapped uint32 and returns the new value.

func (*Uint32) Swap

func (i *Uint32) Swap(val uint32) (old uint32)

Swap atomically swaps the wrapped uint32 and returns the old value.

func (*Uint32) UnmarshalJSON added in v1.9.1

func (i *Uint32) UnmarshalJSON(b []byte) error

UnmarshalJSON decodes JSON into the wrapped uint32.

type Uint64

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

Uint64 is an atomic wrapper around uint64.

func NewUint64

func NewUint64(val uint64) *Uint64

NewUint64 creates a new Uint64.

func (*Uint64) Add

func (i *Uint64) Add(delta uint64) uint64

Add atomically adds to the wrapped uint64 and returns the new value.

func (*Uint64) CAS deprecated

func (i *Uint64) CAS(old, new uint64) (swapped bool)

CAS is an atomic compare-and-swap.

Deprecated: Use CompareAndSwap.

func (*Uint64) CompareAndSwap added in v1.9.1

func (i *Uint64) CompareAndSwap(old, new uint64) (swapped bool)

CompareAndSwap is an atomic compare-and-swap.

func (*Uint64) Dec

func (i *Uint64) Dec() uint64

Dec atomically decrements the wrapped uint64 and returns the new value.

func (*Uint64) Inc

func (i *Uint64) Inc() uint64

Inc atomically increments the wrapped uint64 and returns the new value.

func (*Uint64) Load

func (i *Uint64) Load() uint64

Load atomically loads the wrapped value.

func (*Uint64) MarshalJSON added in v1.9.1

func (i *Uint64) MarshalJSON() ([]byte, error)

MarshalJSON encodes the wrapped uint64 into JSON.

func (*Uint64) Store

func (i *Uint64) Store(val uint64)

Store atomically stores the passed value.

func (*Uint64) String added in v1.9.1

func (i *Uint64) String() string

String encodes the wrapped value as a string.

func (*Uint64) Sub

func (i *Uint64) Sub(delta uint64) uint64

Sub atomically subtracts from the wrapped uint64 and returns the new value.

func (*Uint64) Swap

func (i *Uint64) Swap(val uint64) (old uint64)

Swap atomically swaps the wrapped uint64 and returns the old value.

func (*Uint64) UnmarshalJSON added in v1.9.1

func (i *Uint64) UnmarshalJSON(b []byte) error

UnmarshalJSON decodes JSON into the wrapped uint64.

type Uintptr added in v1.9.1

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

Uintptr is an atomic wrapper around uintptr.

func NewUintptr added in v1.9.1

func NewUintptr(val uintptr) *Uintptr

NewUintptr creates a new Uintptr.

func (*Uintptr) Add added in v1.9.1

func (i *Uintptr) Add(delta uintptr) uintptr

Add atomically adds to the wrapped uintptr and returns the new value.

func (*Uintptr) CAS deprecated added in v1.9.1

func (i *Uintptr) CAS(old, new uintptr) (swapped bool)

CAS is an atomic compare-and-swap.

Deprecated: Use CompareAndSwap.

func (*Uintptr) CompareAndSwap added in v1.9.1

func (i *Uintptr) CompareAndSwap(old, new uintptr) (swapped bool)

CompareAndSwap is an atomic compare-and-swap.

func (*Uintptr) Dec added in v1.9.1

func (i *Uintptr) Dec() uintptr

Dec atomically decrements the wrapped uintptr and returns the new value.

func (*Uintptr) Inc added in v1.9.1

func (i *Uintptr) Inc() uintptr

Inc atomically increments the wrapped uintptr and returns the new value.

func (*Uintptr) Load added in v1.9.1

func (i *Uintptr) Load() uintptr

Load atomically loads the wrapped value.

func (*Uintptr) MarshalJSON added in v1.9.1

func (i *Uintptr) MarshalJSON() ([]byte, error)

MarshalJSON encodes the wrapped uintptr into JSON.

func (*Uintptr) Store added in v1.9.1

func (i *Uintptr) Store(val uintptr)

Store atomically stores the passed value.

func (*Uintptr) String added in v1.9.1

func (i *Uintptr) String() string

String encodes the wrapped value as a string.

func (*Uintptr) Sub added in v1.9.1

func (i *Uintptr) Sub(delta uintptr) uintptr

Sub atomically subtracts from the wrapped uintptr and returns the new value.

func (*Uintptr) Swap added in v1.9.1

func (i *Uintptr) Swap(val uintptr) (old uintptr)

Swap atomically swaps the wrapped uintptr and returns the old value.

func (*Uintptr) UnmarshalJSON added in v1.9.1

func (i *Uintptr) UnmarshalJSON(b []byte) error

UnmarshalJSON decodes JSON into the wrapped uintptr.

type UnsafePointer added in v1.9.1

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

UnsafePointer is an atomic wrapper around unsafe.Pointer.

func NewUnsafePointer added in v1.9.1

func NewUnsafePointer(val unsafe.Pointer) *UnsafePointer

NewUnsafePointer creates a new UnsafePointer.

func (*UnsafePointer) CAS deprecated added in v1.9.1

func (p *UnsafePointer) CAS(old, new unsafe.Pointer) (swapped bool)

CAS is an atomic compare-and-swap.

Deprecated: Use CompareAndSwap

func (*UnsafePointer) CompareAndSwap added in v1.9.1

func (p *UnsafePointer) CompareAndSwap(old, new unsafe.Pointer) (swapped bool)

CompareAndSwap is an atomic compare-and-swap.

func (*UnsafePointer) Load added in v1.9.1

func (p *UnsafePointer) Load() unsafe.Pointer

Load atomically loads the wrapped value.

func (*UnsafePointer) Store added in v1.9.1

func (p *UnsafePointer) Store(val unsafe.Pointer)

Store atomically stores the passed value.

func (*UnsafePointer) Swap added in v1.9.1

func (p *UnsafePointer) Swap(val unsafe.Pointer) (old unsafe.Pointer)

Swap atomically swaps the wrapped unsafe.Pointer and returns the old value.

type Value added in v1.2.0

type Value struct {
	atomic.Value
	// contains filtered or unexported fields
}

Value shadows the type of the same name from sync/atomic https://godoc.org/sync/atomic#Value

Directories

Path Synopsis
internal

Jump to

Keyboard shortcuts

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