Skip to content

Commit 6d7344e

Browse files
author
vvitkovskiy
committed
More strict MutateToInt(), MutateToArray() added
1 parent ebaf2da commit 6d7344e

File tree

5 files changed

+141
-237
lines changed

5 files changed

+141
-237
lines changed

insane.go

+67-8
Original file line numberDiff line numberDiff line change
@@ -1240,6 +1240,17 @@ func (n *Node) MutateToObject() *Node {
12401240
return n
12411241
}
12421242

1243+
func (n *Node) MutateToArray() *Node {
1244+
if n == nil || n.bits&hellBitField == hellBitField {
1245+
return n
1246+
}
1247+
1248+
n.bits = hellBitArray
1249+
n.nodes = n.nodes[:0]
1250+
1251+
return n
1252+
}
1253+
12431254
func (n *Node) MutateToStrict() *StrictNode {
12441255
return &StrictNode{n}
12451256
}
@@ -1486,22 +1497,27 @@ func (n *Node) AsInt() int {
14861497
return 0
14871498
}
14881499

1500+
if n.bits&hellBitTypeFilter == hellBitEscapedString {
1501+
n.unescapeStr()
1502+
}
1503+
14891504
switch n.bits & hellBitTypeFilter {
14901505
case hellBitString:
1491-
return int(math.Round(decodeFloat64(n.data)))
1492-
case hellBitEscapedString:
1493-
n.unescapeStr()
1494-
return int(math.Round(decodeFloat64(n.data)))
1506+
fallthrough
1507+
case hellBitField:
1508+
fallthrough
14951509
case hellBitNumber:
1496-
return int(math.Round(decodeFloat64(n.data)))
1510+
if strings.IndexByte(n.data, '.') != -1 {
1511+
return int(math.Round(decodeFloat64(n.data)))
1512+
} else {
1513+
return int(decodeInt64(n.data))
1514+
}
14971515
case hellBitTrue:
14981516
return 1
14991517
case hellBitFalse:
15001518
return 0
15011519
case hellBitNull:
15021520
return 0
1503-
case hellBitField:
1504-
return int(math.Round(decodeFloat64(n.data)))
15051521
case hellBitEscapedField:
15061522
panic("insane json really goes outta its mind")
15071523
default:
@@ -1520,6 +1536,50 @@ func (n *StrictNode) AsInt() (int, error) {
15201536
return int(num), nil
15211537
}
15221538

1539+
func (n *Node) AsInt64() int64 {
1540+
if n == nil {
1541+
return 0
1542+
}
1543+
1544+
if n.bits&hellBitTypeFilter == hellBitEscapedString {
1545+
n.unescapeStr()
1546+
}
1547+
1548+
switch n.bits & hellBitTypeFilter {
1549+
case hellBitString:
1550+
fallthrough
1551+
case hellBitField:
1552+
fallthrough
1553+
case hellBitNumber:
1554+
if strings.IndexByte(n.data, '.') != -1 {
1555+
return int64(math.Round(decodeFloat64(n.data)))
1556+
} else {
1557+
return decodeInt64(n.data)
1558+
}
1559+
case hellBitTrue:
1560+
return 1
1561+
case hellBitFalse:
1562+
return 0
1563+
case hellBitNull:
1564+
return 0
1565+
case hellBitEscapedField:
1566+
panic("insane json really goes outta its mind")
1567+
default:
1568+
return 0
1569+
}
1570+
}
1571+
1572+
func (n *StrictNode) AsInt64() (int64, error) {
1573+
if n == nil || n.bits&hellBitNumber != hellBitNumber {
1574+
return 0, ErrNotNumber
1575+
}
1576+
num := decodeInt64(n.data)
1577+
if num == 0 && n.data != "0" {
1578+
return 0, ErrNotNumber
1579+
}
1580+
return num, nil
1581+
}
1582+
15231583
func (n *Node) AsFloat() float64 {
15241584
switch n.bits & hellBitTypeFilter {
15251585
case hellBitString:
@@ -2213,4 +2273,3 @@ func insaneErr(err error, json string, offset int) error {
22132273

22142274
return errors.New(fmt.Sprintf("%s near `%s`\n%s", err.Error(), str, pointer))
22152275
}
2216-

insane.s

-92
This file was deleted.

insane_asm.go

-7
This file was deleted.

insane_perf_test.go

+1-130
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,11 @@ package insaneJSON
22

33
import (
44
"bufio"
5-
"bytes"
65
"fmt"
76
"io/ioutil"
87
"math/rand"
98
"os"
10-
"reflect"
119
"testing"
12-
"unsafe"
1310
)
1411

1512
type workload struct {
@@ -267,130 +264,4 @@ func BenchmarkValueEscapeString(b *testing.B) {
267264
out = escapeString(out[:0], test.s)
268265
}
269266
}
270-
}
271-
272-
func BenchmarkNg1(b *testing.B) {
273-
content, err := ioutil.ReadFile("benchdata/insane.json")
274-
if err != nil {
275-
panic(err.Error())
276-
}
277-
278-
b.SetBytes(int64(len(content)))
279-
x := 0
280-
for i := 0; i < b.N; i++ {
281-
for _, c := range content {
282-
if c == '{' || c == '}' || c == '[' || c == ']' || c == '"' || c == ',' {
283-
x++
284-
}
285-
}
286-
}
287-
288-
fmt.Printf("\ncount: %d\n", x/b.N)
289-
}
290-
291-
func BenchmarkNg2(b *testing.B) {
292-
content, err := ioutil.ReadFile("benchdata/insane.json")
293-
if err != nil {
294-
panic(err.Error())
295-
}
296-
297-
b.SetBytes(int64(len(content)))
298-
x := 0
299-
m := make([]byte, 256)
300-
m['{'] = 1
301-
m['}'] = 1
302-
m['['] = 1
303-
m[']'] = 1
304-
m[','] = 1
305-
m['"'] = 1
306-
for i := 0; i < b.N; i++ {
307-
for i := 0; i < len(content); i += 8 {
308-
l := content[i : i+8]
309-
if m[l[0]]+m[l[1]]+m[l[2]]+m[l[3]]+m[l[4]]+m[l[5]]+m[l[6]]+m[l[7]] > 0 {
310-
if m[l[0]] == 1 {
311-
x++
312-
}
313-
if m[l[1]] == 1 {
314-
x++
315-
}
316-
if m[l[2]] == 1 {
317-
x++
318-
}
319-
if m[l[3]] == 1 {
320-
x++
321-
}
322-
if m[l[4]] == 1 {
323-
x++
324-
}
325-
if m[l[5]] == 1 {
326-
x++
327-
}
328-
if m[l[6]] == 1 {
329-
x++
330-
}
331-
if m[l[7]] == 1 {
332-
x++
333-
}
334-
}
335-
}
336-
}
337-
338-
fmt.Printf("\ncount: %d\n", x/b.N)
339-
}
340-
341-
func BenchmarkNg3(b *testing.B) {
342-
content, err := ioutil.ReadFile("benchdata/insane.json")
343-
if err != nil {
344-
panic(err.Error())
345-
}
346-
347-
b.SetBytes(int64(len(content)))
348-
x := 0
349-
root := Spawn()
350-
for i := 0; i < b.N; i++ {
351-
_ = root.DecodeBytes(content)
352-
}
353-
354-
fmt.Printf("\ncount: %d\n", x/b.N)
355-
}
356-
357-
func BenchmarkNg4(b *testing.B) {
358-
content, err := ioutil.ReadFile("benchdata/insane.json")
359-
if err != nil {
360-
panic(err.Error())
361-
}
362-
363-
header := (*reflect.SliceHeader)(unsafe.Pointer(&content))
364-
365-
ccc := content
366-
header2 := (*reflect.SliceHeader)(unsafe.Pointer(&ccc))
367-
b.SetBytes(int64(len(content)))
368-
x := 0
369-
flows := []byte(`{}[],`)
370-
for i := 0; i < b.N; i++ {
371-
for _, flow := range flows {
372-
header2.Len = header.Len
373-
header2.Data = header.Data
374-
header2.Cap = header.Cap
375-
data := &header2.Data
376-
l := &header2.Len
377-
for {
378-
pos := bytes.IndexByte(*(*[]byte)(unsafe.Pointer(header2)), flow) + 1
379-
if pos <= 0 {
380-
fmt.Printf("pos: %d\n", pos)
381-
break
382-
}
383-
x++
384-
*data += uintptr(pos)
385-
*l -= pos
386-
}
387-
}
388-
}
389-
390-
fmt.Printf("\ncount: %d\n", x/b.N)
391-
}
392-
393-
func BenchmarkNg5(b *testing.B) {
394-
r1, r2 := InsaneSkipWC_([]byte(` .`), []byte(`........`))
395-
fmt.Printf("res=%d/%d\n", r1%256, r2%256)
396-
}
267+
}

0 commit comments

Comments
 (0)