noop.go 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. // Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved.
  2. // Use of this source code is governed by a MIT license found in the LICENSE file.
  3. // +build ignore
  4. package codec
  5. import (
  6. "math/rand"
  7. "time"
  8. )
  9. // NoopHandle returns a no-op handle. It basically does nothing.
  10. // It is only useful for benchmarking, as it gives an idea of the
  11. // overhead from the codec framework.
  12. //
  13. // LIBRARY USERS: *** DO NOT USE ***
  14. func NoopHandle(slen int) *noopHandle {
  15. h := noopHandle{}
  16. h.rand = rand.New(rand.NewSource(time.Now().UnixNano()))
  17. h.B = make([][]byte, slen)
  18. h.S = make([]string, slen)
  19. for i := 0; i < len(h.S); i++ {
  20. b := make([]byte, i+1)
  21. for j := 0; j < len(b); j++ {
  22. b[j] = 'a' + byte(i)
  23. }
  24. h.B[i] = b
  25. h.S[i] = string(b)
  26. }
  27. return &h
  28. }
  29. // noopHandle does nothing.
  30. // It is used to simulate the overhead of the codec framework.
  31. type noopHandle struct {
  32. BasicHandle
  33. binaryEncodingType
  34. noopDrv // noopDrv is unexported here, so we can get a copy of it when needed.
  35. }
  36. type noopDrv struct {
  37. d *Decoder
  38. e *Encoder
  39. i int
  40. S []string
  41. B [][]byte
  42. mks []bool // stack. if map (true), else if array (false)
  43. mk bool // top of stack. what container are we on? map or array?
  44. ct valueType // last response for IsContainerType.
  45. cb int // counter for ContainerType
  46. rand *rand.Rand
  47. }
  48. func (h *noopDrv) r(v int) int { return h.rand.Intn(v) }
  49. func (h *noopDrv) m(v int) int { h.i++; return h.i % v }
  50. func (h *noopDrv) newEncDriver(e *Encoder) encDriver { h.e = e; return h }
  51. func (h *noopDrv) newDecDriver(d *Decoder) decDriver { h.d = d; return h }
  52. func (h *noopDrv) reset() {}
  53. func (h *noopDrv) uncacheRead() {}
  54. // --- encDriver
  55. // stack functions (for map and array)
  56. func (h *noopDrv) start(b bool) {
  57. // println("start", len(h.mks)+1)
  58. h.mks = append(h.mks, b)
  59. h.mk = b
  60. }
  61. func (h *noopDrv) end() {
  62. // println("end: ", len(h.mks)-1)
  63. h.mks = h.mks[:len(h.mks)-1]
  64. if len(h.mks) > 0 {
  65. h.mk = h.mks[len(h.mks)-1]
  66. } else {
  67. h.mk = false
  68. }
  69. }
  70. func (h *noopDrv) EncodeBuiltin(rt uintptr, v interface{}) {}
  71. func (h *noopDrv) EncodeNil() {}
  72. func (h *noopDrv) EncodeInt(i int64) {}
  73. func (h *noopDrv) EncodeUint(i uint64) {}
  74. func (h *noopDrv) EncodeBool(b bool) {}
  75. func (h *noopDrv) EncodeFloat32(f float32) {}
  76. func (h *noopDrv) EncodeFloat64(f float64) {}
  77. func (h *noopDrv) EncodeRawExt(re *RawExt, e *Encoder) {}
  78. func (h *noopDrv) EncodeArrayStart(length int) { h.start(true) }
  79. func (h *noopDrv) EncodeMapStart(length int) { h.start(false) }
  80. func (h *noopDrv) EncodeEnd() { h.end() }
  81. func (h *noopDrv) EncodeString(c charEncoding, v string) {}
  82. func (h *noopDrv) EncodeSymbol(v string) {}
  83. func (h *noopDrv) EncodeStringBytes(c charEncoding, v []byte) {}
  84. func (h *noopDrv) EncodeExt(rv interface{}, xtag uint64, ext Ext, e *Encoder) {}
  85. // ---- decDriver
  86. func (h *noopDrv) initReadNext() {}
  87. func (h *noopDrv) CheckBreak() bool { return false }
  88. func (h *noopDrv) IsBuiltinType(rt uintptr) bool { return false }
  89. func (h *noopDrv) DecodeBuiltin(rt uintptr, v interface{}) {}
  90. func (h *noopDrv) DecodeInt(bitsize uint8) (i int64) { return int64(h.m(15)) }
  91. func (h *noopDrv) DecodeUint(bitsize uint8) (ui uint64) { return uint64(h.m(35)) }
  92. func (h *noopDrv) DecodeFloat(chkOverflow32 bool) (f float64) { return float64(h.m(95)) }
  93. func (h *noopDrv) DecodeBool() (b bool) { return h.m(2) == 0 }
  94. func (h *noopDrv) DecodeString() (s string) { return h.S[h.m(8)] }
  95. func (h *noopDrv) DecodeStringAsBytes() []byte { return h.DecodeBytes(nil, true) }
  96. func (h *noopDrv) DecodeBytes(bs []byte, zerocopy bool) []byte { return h.B[h.m(len(h.B))] }
  97. func (h *noopDrv) ReadEnd() { h.end() }
  98. // toggle map/slice
  99. func (h *noopDrv) ReadMapStart() int { h.start(true); return h.m(10) }
  100. func (h *noopDrv) ReadArrayStart() int { h.start(false); return h.m(10) }
  101. func (h *noopDrv) ContainerType() (vt valueType) {
  102. // return h.m(2) == 0
  103. // handle kStruct, which will bomb is it calls this and doesn't get back a map or array.
  104. // consequently, if the return value is not map or array, reset it to one of them based on h.m(7) % 2
  105. // for kstruct: at least one out of every 2 times, return one of valueTypeMap or Array (else kstruct bombs)
  106. // however, every 10th time it is called, we just return something else.
  107. var vals = [...]valueType{valueTypeArray, valueTypeMap}
  108. // ------------ TAKE ------------
  109. // if h.cb%2 == 0 {
  110. // if h.ct == valueTypeMap || h.ct == valueTypeArray {
  111. // } else {
  112. // h.ct = vals[h.m(2)]
  113. // }
  114. // } else if h.cb%5 == 0 {
  115. // h.ct = valueType(h.m(8))
  116. // } else {
  117. // h.ct = vals[h.m(2)]
  118. // }
  119. // ------------ TAKE ------------
  120. // if h.cb%16 == 0 {
  121. // h.ct = valueType(h.cb % 8)
  122. // } else {
  123. // h.ct = vals[h.cb%2]
  124. // }
  125. h.ct = vals[h.cb%2]
  126. h.cb++
  127. return h.ct
  128. // if h.ct == valueTypeNil || h.ct == valueTypeString || h.ct == valueTypeBytes {
  129. // return h.ct
  130. // }
  131. // return valueTypeUnset
  132. // TODO: may need to tweak this so it works.
  133. // if h.ct == valueTypeMap && vt == valueTypeArray || h.ct == valueTypeArray && vt == valueTypeMap {
  134. // h.cb = !h.cb
  135. // h.ct = vt
  136. // return h.cb
  137. // }
  138. // // go in a loop and check it.
  139. // h.ct = vt
  140. // h.cb = h.m(7) == 0
  141. // return h.cb
  142. }
  143. func (h *noopDrv) TryDecodeAsNil() bool {
  144. if h.mk {
  145. return false
  146. } else {
  147. return h.m(8) == 0
  148. }
  149. }
  150. func (h *noopDrv) DecodeExt(rv interface{}, xtag uint64, ext Ext) uint64 {
  151. return 0
  152. }
  153. func (h *noopDrv) DecodeNaked() {
  154. // use h.r (random) not h.m() because h.m() could cause the same value to be given.
  155. var sk int
  156. if h.mk {
  157. // if mapkey, do not support values of nil OR bytes, array, map or rawext
  158. sk = h.r(7) + 1
  159. } else {
  160. sk = h.r(12)
  161. }
  162. n := &h.d.n
  163. switch sk {
  164. case 0:
  165. n.v = valueTypeNil
  166. case 1:
  167. n.v, n.b = valueTypeBool, false
  168. case 2:
  169. n.v, n.b = valueTypeBool, true
  170. case 3:
  171. n.v, n.i = valueTypeInt, h.DecodeInt(64)
  172. case 4:
  173. n.v, n.u = valueTypeUint, h.DecodeUint(64)
  174. case 5:
  175. n.v, n.f = valueTypeFloat, h.DecodeFloat(true)
  176. case 6:
  177. n.v, n.f = valueTypeFloat, h.DecodeFloat(false)
  178. case 7:
  179. n.v, n.s = valueTypeString, h.DecodeString()
  180. case 8:
  181. n.v, n.l = valueTypeBytes, h.B[h.m(len(h.B))]
  182. case 9:
  183. n.v = valueTypeArray
  184. case 10:
  185. n.v = valueTypeMap
  186. default:
  187. n.v = valueTypeExt
  188. n.u = h.DecodeUint(64)
  189. n.l = h.B[h.m(len(h.B))]
  190. }
  191. h.ct = n.v
  192. return
  193. }