Skip to content

Commit e308399

Browse files
committed
opt: rearrange the matrix and map of connections
1 parent 6136138 commit e308399

File tree

3 files changed

+177
-177
lines changed

3 files changed

+177
-177
lines changed

conn_map.go

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
// Copyright (c) 2023 The Gnet Authors. All rights reserved.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
//go:build (linux || freebsd || dragonfly || darwin) && !gc_opt
16+
// +build linux freebsd dragonfly darwin
17+
// +build !gc_opt
18+
19+
package gnet
20+
21+
import (
22+
"sync/atomic"
23+
24+
"github.com/panjf2000/gnet/v2/internal/gfd"
25+
)
26+
27+
type connMatrix struct {
28+
connCount int32
29+
connMap map[int]*conn
30+
}
31+
32+
func (cm *connMatrix) init() {
33+
cm.connMap = make(map[int]*conn)
34+
}
35+
36+
func (cm *connMatrix) iterate(f func(*conn) bool) {
37+
for _, c := range cm.connMap {
38+
if c != nil {
39+
if !f(c) {
40+
return
41+
}
42+
}
43+
}
44+
}
45+
46+
func (cm *connMatrix) incCount(_ int, delta int32) {
47+
atomic.AddInt32(&cm.connCount, delta)
48+
}
49+
50+
func (cm *connMatrix) loadCount() (n int32) {
51+
return atomic.LoadInt32(&cm.connCount)
52+
}
53+
54+
func (cm *connMatrix) addConn(c *conn, index int) {
55+
c.gfd = gfd.NewGFD(c.fd, index, 0, 0)
56+
cm.connMap[c.fd] = c
57+
cm.incCount(0, 1)
58+
}
59+
60+
func (cm *connMatrix) delConn(c *conn) {
61+
delete(cm.connMap, c.fd)
62+
cm.incCount(0, -1)
63+
}
64+
65+
func (cm *connMatrix) getConn(fd int) *conn {
66+
return cm.connMap[fd]
67+
}
68+
69+
/*
70+
func (cm *connMatrix) getConnByGFD(fd gfd.GFD) *conn {
71+
return cm.connMap[fd.Fd()]
72+
}
73+
*/

conn_matrix.go

Lines changed: 104 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15-
//go:build (linux || freebsd || dragonfly || darwin) && !gc_opt
15+
//go:build (linux || freebsd || dragonfly || darwin) && gc_opt
1616
// +build linux freebsd dragonfly darwin
17-
// +build !gc_opt
17+
// +build gc_opt
1818

1919
package gnet
2020

@@ -25,49 +25,134 @@ import (
2525
)
2626

2727
type connMatrix struct {
28-
connCount int32
29-
connMap map[int]*conn
28+
disableCompact bool // disable compaction when it is true
29+
connCounts [gfd.ConnMatrixRowMax]int32 // number of active connections in event-loop
30+
row int // next available row index
31+
column int // next available column index
32+
table [gfd.ConnMatrixRowMax][]*conn // connection matrix of *conn, multiple slices
33+
fd2gfd map[int]gfd.GFD // fd -> gfd.GFD
3034
}
3135

3236
func (cm *connMatrix) init() {
33-
cm.connMap = make(map[int]*conn)
37+
cm.fd2gfd = make(map[int]gfd.GFD)
3438
}
3539

3640
func (cm *connMatrix) iterate(f func(*conn) bool) {
37-
for _, c := range cm.connMap {
38-
if c != nil {
39-
if !f(c) {
40-
return
41+
cm.disableCompact = true
42+
defer func() { cm.disableCompact = false }()
43+
for _, conns := range cm.table {
44+
for _, c := range conns {
45+
if c != nil {
46+
if !f(c) {
47+
return
48+
}
4149
}
4250
}
4351
}
4452
}
4553

46-
func (cm *connMatrix) incCount(_ int, delta int32) {
47-
atomic.AddInt32(&cm.connCount, delta)
54+
func (cm *connMatrix) incCount(row int, delta int32) {
55+
atomic.AddInt32(&cm.connCounts[row], delta)
4856
}
4957

5058
func (cm *connMatrix) loadCount() (n int32) {
51-
return atomic.LoadInt32(&cm.connCount)
59+
for i := 0; i < len(cm.connCounts); i++ {
60+
n += atomic.LoadInt32(&cm.connCounts[i])
61+
}
62+
return
5263
}
5364

5465
func (cm *connMatrix) addConn(c *conn, index int) {
55-
c.gfd = gfd.NewGFD(c.fd, index, 0, 0)
56-
cm.connMap[c.fd] = c
57-
cm.incCount(0, 1)
66+
if cm.row >= gfd.ConnMatrixRowMax {
67+
return
68+
}
69+
70+
if cm.table[cm.row] == nil {
71+
cm.table[cm.row] = make([]*conn, gfd.ConnMatrixColumnMax)
72+
}
73+
74+
c.gfd = gfd.NewGFD(c.fd, index, cm.row, cm.column)
75+
cm.fd2gfd[c.fd] = c.gfd
76+
cm.table[cm.row][cm.column] = c
77+
cm.incCount(cm.row, 1)
78+
79+
if cm.column++; cm.column == gfd.ConnMatrixColumnMax {
80+
cm.row++
81+
cm.column = 0
82+
}
5883
}
5984

6085
func (cm *connMatrix) delConn(c *conn) {
61-
delete(cm.connMap, c.fd)
62-
cm.incCount(0, -1)
86+
cfd, cgfd := c.fd, c.gfd
87+
88+
delete(cm.fd2gfd, cfd)
89+
cm.incCount(cgfd.ConnMatrixRow(), -1)
90+
if cm.connCounts[cgfd.ConnMatrixRow()] == 0 {
91+
cm.table[cgfd.ConnMatrixRow()] = nil
92+
} else {
93+
cm.table[cgfd.ConnMatrixRow()][cgfd.ConnMatrixColumn()] = nil
94+
}
95+
if cm.row > cgfd.ConnMatrixRow() || cm.column > cgfd.ConnMatrixColumn() {
96+
cm.row, cm.column = cgfd.ConnMatrixRow(), cgfd.ConnMatrixColumn()
97+
}
98+
99+
// Locate the last *conn in table and move it to the deleted location.
100+
101+
if cm.disableCompact || cm.table[cgfd.ConnMatrixRow()] == nil { // the deleted *conn is the last one, do nothing here.
102+
return
103+
}
104+
105+
// Traverse backward to find the first non-empty point in the matrix until we reach the deleted position.
106+
for row := gfd.ConnMatrixRowMax - 1; row >= cgfd.ConnMatrixRow(); row-- {
107+
if cm.connCounts[row] == 0 {
108+
continue
109+
}
110+
columnMin := -1
111+
if row == cgfd.ConnMatrixRow() {
112+
columnMin = cgfd.ConnMatrixColumn()
113+
}
114+
for column := gfd.ConnMatrixColumnMax - 1; column > columnMin; column-- {
115+
if cm.table[row][column] == nil {
116+
continue
117+
}
118+
119+
gFd := cm.table[row][column].gfd
120+
gFd.UpdateIndexes(cgfd.ConnMatrixRow(), cgfd.ConnMatrixColumn())
121+
cm.table[row][column].gfd = gFd
122+
cm.fd2gfd[gFd.Fd()] = gFd
123+
cm.table[cgfd.ConnMatrixRow()][cgfd.ConnMatrixColumn()] = cm.table[row][column]
124+
cm.incCount(row, -1)
125+
cm.incCount(cgfd.ConnMatrixRow(), 1)
126+
127+
if cm.connCounts[row] == 0 {
128+
cm.table[row] = nil
129+
} else {
130+
cm.table[row][column] = nil
131+
}
132+
133+
cm.row, cm.column = row, column
134+
135+
return
136+
}
137+
}
63138
}
64139

65140
func (cm *connMatrix) getConn(fd int) *conn {
66-
return cm.connMap[fd]
141+
gFD, ok := cm.fd2gfd[fd]
142+
if !ok {
143+
return nil
144+
}
145+
if cm.table[gFD.ConnMatrixRow()] == nil {
146+
return nil
147+
}
148+
return cm.table[gFD.ConnMatrixRow()][gFD.ConnMatrixColumn()]
67149
}
68150

69151
/*
70152
func (cm *connMatrix) getConnByGFD(fd gfd.GFD) *conn {
71-
return cm.connMap[fd.Fd()]
153+
if cm.table[fd.ConnMatrixRow()] == nil {
154+
return nil
155+
}
156+
return cm.table[fd.ConnMatrixRow()][fd.ConnMatrixColumn()]
72157
}
73158
*/

conn_matrix_gcopt.go

Lines changed: 0 additions & 158 deletions
This file was deleted.

0 commit comments

Comments
 (0)