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
1919package gnet
2020
@@ -25,49 +25,134 @@ import (
2525)
2626
2727type 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
3236func (cm * connMatrix ) init () {
33- cm .connMap = make (map [int ]* conn )
37+ cm .fd2gfd = make (map [int ]gfd. GFD )
3438}
3539
3640func (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
5058func (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
5465func (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
6085func (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
65140func (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/*
70152func (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*/
0 commit comments