@@ -2,9 +2,9 @@ package domain
22
33import (
44 "encoding/binary"
5- "io"
65 "math/bits"
76
7+ E "github.com/sagernet/sing/common/exceptions"
88 "github.com/sagernet/sing/common/varbin"
99)
1010
@@ -47,28 +47,31 @@ func newSuccinctSet(keys []string) *succinctSet {
4747func (ss * succinctSet ) keys () []string {
4848 var result []string
4949 var currentKey []byte
50- var bmIdx , nodeId int
51-
52- var traverse func (int , int )
53- traverse = func (nodeId , bmIdx int ) {
54- if getBit (ss .leaves , nodeId ) != 0 {
55- result = append (result , string (currentKey ))
56- }
57-
58- for ; ; bmIdx ++ {
59- if getBit (ss .labelBitmap , bmIdx ) != 0 {
60- return
50+ type frame struct {
51+ nodeId , bmIdx int
52+ }
53+ if getBit (ss .leaves , 0 ) != 0 {
54+ result = append (result , "" )
55+ }
56+ stack := []frame {{0 , 0 }}
57+ for len (stack ) > 0 {
58+ top := & stack [len (stack )- 1 ]
59+ if getBit (ss .labelBitmap , top .bmIdx ) != 0 {
60+ stack = stack [:len (stack )- 1 ]
61+ if len (stack ) > 0 {
62+ currentKey = currentKey [:len (currentKey )- 1 ]
63+ stack [len (stack )- 1 ].bmIdx ++
6164 }
62- nextLabel := ss .labels [bmIdx - nodeId ]
63- currentKey = append (currentKey , nextLabel )
64- nextNodeId := countZeros (ss .labelBitmap , ss .ranks , bmIdx + 1 )
65- nextBmIdx := selectIthOne (ss .labelBitmap , ss .ranks , ss .selects , nextNodeId - 1 ) + 1
66- traverse (nextNodeId , nextBmIdx )
67- currentKey = currentKey [:len (currentKey )- 1 ]
65+ continue
6866 }
67+ currentKey = append (currentKey , ss .labels [top .bmIdx - top .nodeId ])
68+ nextNodeId := countZeros (ss .labelBitmap , ss .ranks , top .bmIdx + 1 )
69+ nextBmIdx := selectIthOne (ss .labelBitmap , ss .ranks , ss .selects , nextNodeId - 1 ) + 1
70+ if getBit (ss .leaves , nextNodeId ) != 0 {
71+ result = append (result , string (currentKey ))
72+ }
73+ stack = append (stack , frame {nextNodeId , nextBmIdx })
6974 }
70-
71- traverse (nodeId , bmIdx )
7275 return result
7376}
7477
@@ -77,18 +80,34 @@ func readSuccinctSet(reader varbin.Reader) (*succinctSet, error) {
7780 if err != nil {
7881 return nil , err
7982 }
80- leaves , err := readUint64Slice (reader )
83+ leaves , err := varbin . ReadSlice [ uint64 ] (reader , binary . BigEndian )
8184 if err != nil {
8285 return nil , err
8386 }
84- labelBitmap , err := readUint64Slice (reader )
87+ labelBitmap , err := varbin . ReadSlice [ uint64 ] (reader , binary . BigEndian )
8588 if err != nil {
8689 return nil , err
8790 }
88- labels , err := readByteSlice (reader )
91+ labels , err := varbin . ReadSlice [ byte ] (reader , binary . BigEndian )
8992 if err != nil {
9093 return nil , err
9194 }
95+ onesCount := 0
96+ lastOneIndex := - 1
97+ for wordIndex , word := range labelBitmap {
98+ onesCount += bits .OnesCount64 (word )
99+ if word != 0 {
100+ lastOneIndex = wordIndex << 6 | (63 - bits .LeadingZeros64 (word ))
101+ }
102+ }
103+ zerosCount := lastOneIndex + 1 - onesCount
104+ if onesCount != zerosCount + 1 || len (labels ) != zerosCount {
105+ return nil , E .New ("domain: malformed succinct set" )
106+ }
107+ leavesWordCount := (onesCount + 63 ) >> 6
108+ if len (leaves ) < leavesWordCount {
109+ leaves = append (leaves , make ([]uint64 , leavesWordCount - len (leaves ))... )
110+ }
92111 set := & succinctSet {
93112 leaves : leaves ,
94113 labelBitmap : labelBitmap ,
@@ -114,22 +133,6 @@ func (ss *succinctSet) Write(writer varbin.Writer) error {
114133 return writeByteSlice (writer , ss .labels )
115134}
116135
117- func readUint64Slice (reader varbin.Reader ) ([]uint64 , error ) {
118- length , err := binary .ReadUvarint (reader )
119- if err != nil {
120- return nil , err
121- }
122- if length == 0 {
123- return nil , nil
124- }
125- result := make ([]uint64 , length )
126- err = binary .Read (reader , binary .BigEndian , result )
127- if err != nil {
128- return nil , err
129- }
130- return result , nil
131- }
132-
133136func writeUint64Slice (writer varbin.Writer , value []uint64 ) error {
134137 _ , err := varbin .WriteUvarint (writer , uint64 (len (value )))
135138 if err != nil {
@@ -141,22 +144,6 @@ func writeUint64Slice(writer varbin.Writer, value []uint64) error {
141144 return binary .Write (writer , binary .BigEndian , value )
142145}
143146
144- func readByteSlice (reader varbin.Reader ) ([]byte , error ) {
145- length , err := binary .ReadUvarint (reader )
146- if err != nil {
147- return nil , err
148- }
149- if length == 0 {
150- return nil , nil
151- }
152- result := make ([]byte , length )
153- _ , err = io .ReadFull (reader , result )
154- if err != nil {
155- return nil , err
156- }
157- return result , nil
158- }
159-
160147func writeByteSlice (writer varbin.Writer , value []byte ) error {
161148 _ , err := varbin .WriteUvarint (writer , uint64 (len (value )))
162149 if err != nil {
0 commit comments