Skip to content

Commit

Permalink
ipaddr: add Prev, Reset methods to Cursor, IsBroadcast, IsSubnetRoute…
Browse files Browse the repository at this point in the history
…rAnycast methods to Position
  • Loading branch information
cixtor committed Aug 30, 2015
1 parent 6b85405 commit 702bedf
Show file tree
Hide file tree
Showing 8 changed files with 342 additions and 117 deletions.
20 changes: 20 additions & 0 deletions benchmark_test.go
Expand Up @@ -97,6 +97,26 @@ func BenchmarkCursorNextIPv6(b *testing.B) {
}
}

func BenchmarkCursorPrevIPv4(b *testing.B) {
ps := toPrefixes([]string{"192.168.0.255/24"})
c := ipaddr.NewCursor(ps)

for i := 0; i < b.N; i++ {
for c.Prev() != nil {
}
}
}

func BenchmarkCursorPrevIPv6(b *testing.B) {
ps := toPrefixes([]string{"2001:db8::ff/120"})
c := ipaddr.NewCursor(ps)

for i := 0; i < b.N; i++ {
for c.Prev() != nil {
}
}
}

func BenchmarkPrefixEqualIPv4(b *testing.B) {
ps := toPrefixes([]string{"192.168.1.0/24", "192.168.2.0/24"})

Expand Down
83 changes: 53 additions & 30 deletions cursor.go
Expand Up @@ -9,44 +9,28 @@ import (
"net"
)

// A Position represents a position on a cursor.
type Position struct {
IP net.IP // IP address
Prefix Prefix // IP address prefix
}

// A Cursor repesents a movable indicator on multiple prefixes.
// A Cursor repesents a movable indicator on a single or multiple
// prefixes.
type Cursor struct {
curr, last ipv6Int
curr, start, end ipv6Int

pi int
ps []Prefix // IP address prefixes
}

func (c *Cursor) next() {
c.pi++
ip := c.ps[c.pi].IP.To16()
c.curr = ipToIPv6Int(ip)
if ip.To4() != nil {
c.last = c.ps[c.pi].lastIPv4MappedInt()
}
if ip.To16() != nil && ip.To4() == nil {
c.last = c.ps[c.pi].lastIPv6Int()
}
ps []Prefix
}

func (c *Cursor) set(pi int, ip net.IP) {
c.pi = pi
c.curr = ipToIPv6Int(ip.To16())
c.start = ipToIPv6Int(c.ps[c.pi].IP.To16())
if ip.To4() != nil {
c.last = c.ps[c.pi].lastIPv4MappedInt()
c.end = c.ps[c.pi].lastIPv4MappedIPv6Int()
}
if ip.To16() != nil && ip.To4() == nil {
c.last = c.ps[c.pi].lastIPv6Int()
c.end = c.ps[c.pi].lastIPv6Int()
}
}

// First returns the first position on the cursor c.
// First returns the start position on the cursor c.
func (c *Cursor) First() *Position {
return &Position{IP: c.ps[0].IP, Prefix: c.ps[0]}
}
Expand All @@ -61,15 +45,23 @@ func (c *Cursor) List() []Prefix {
return c.ps
}

// Next returns the next position on the cursor c.
// Next turns to the next postion on the cursor c.
// It returns nil at the end on the cursor c.
func (c *Cursor) Next() *Position {
n := c.curr.cmp(&c.last)
n := c.curr.cmp(&c.end)
if n == 0 {
if c.pi == len(c.ps)-1 {
return nil
}
c.next()
c.pi++
c.curr = ipToIPv6Int(c.ps[c.pi].IP.To16())
c.start = c.curr
if c.ps[c.pi].IP.To4() != nil {
c.end = c.ps[c.pi].lastIPv4MappedIPv6Int()
}
if c.ps[c.pi].IP.To16() != nil && c.ps[c.pi].IP.To4() == nil {
c.end = c.ps[c.pi].lastIPv6Int()
}
} else {
c.curr.incr()
}
Expand All @@ -81,6 +73,40 @@ func (c *Cursor) Pos() *Position {
return &Position{IP: c.curr.ip(), Prefix: c.ps[c.pi]}
}

// Prev turns to the previous position on the cursor c.
// It returns nil at the start on the cursor c.
func (c *Cursor) Prev() *Position {
n := c.curr.cmp(&c.start)
if n == 0 {
if c.pi == 0 {
return nil
}
c.pi--
if c.ps[c.pi].IP.To4() != nil {
c.curr = c.ps[c.pi].lastIPv4MappedIPv6Int()
c.end = c.curr
}
if c.ps[c.pi].IP.To16() != nil && c.ps[c.pi].IP.To4() == nil {
c.curr = c.ps[c.pi].lastIPv6Int()
c.end = c.curr
}
c.start = ipToIPv6Int(c.ps[c.pi].IP.To16())
} else {
c.curr.decr()
}
return c.Pos()
}

// Reset resets all state and switches the prefixes to ps.
// It uses the existing prefixes when ps is nil.
func (c *Cursor) Reset(ps []Prefix) {
ps = sortAndDedup(ps, false)
if len(ps) > 0 {
c.ps = ps
}
c.set(0, c.ps[0].IP.To16())
}

// Set sets the current postion on the cursor c to pos.
func (c *Cursor) Set(pos *Position) error {
if pos == nil {
Expand All @@ -102,9 +128,6 @@ func (c *Cursor) Set(pos *Position) error {

// NewCursor returns a new cursor.
func NewCursor(ps []Prefix) *Cursor {
if len(ps) == 0 {
return nil
}
ps = sortAndDedup(ps, false)
if len(ps) == 0 {
return nil
Expand Down

0 comments on commit 702bedf

Please sign in to comment.