1
2
3 package validate
4
5 import (
6 "fmt"
7 "runtime"
8 "sync"
9 "testing"
10
11 "github.com/go-openapi/spec"
12 )
13
14
15
16
17
18
19 var pools allPools
20
21 func init() {
22 resetPools()
23 }
24
25 func resetPools() {
26
27
28
29
30 pools = allPools{
31 poolOfSchemaValidators: schemaValidatorsPool{
32 Pool: &sync.Pool{
33 New: func() any {
34 s := &SchemaValidator{}
35
36 return s
37 },
38 },
39 debugMap: make(map[*SchemaValidator]status),
40 allocMap: make(map[*SchemaValidator]string),
41 redeemMap: make(map[*SchemaValidator]string),
42 },
43 poolOfObjectValidators: objectValidatorsPool{
44 Pool: &sync.Pool{
45 New: func() any {
46 s := &objectValidator{}
47
48 return s
49 },
50 },
51 debugMap: make(map[*objectValidator]status),
52 allocMap: make(map[*objectValidator]string),
53 redeemMap: make(map[*objectValidator]string),
54 },
55 poolOfSliceValidators: sliceValidatorsPool{
56 Pool: &sync.Pool{
57 New: func() any {
58 s := &schemaSliceValidator{}
59
60 return s
61 },
62 },
63 debugMap: make(map[*schemaSliceValidator]status),
64 allocMap: make(map[*schemaSliceValidator]string),
65 redeemMap: make(map[*schemaSliceValidator]string),
66 },
67 poolOfItemsValidators: itemsValidatorsPool{
68 Pool: &sync.Pool{
69 New: func() any {
70 s := &itemsValidator{}
71
72 return s
73 },
74 },
75 debugMap: make(map[*itemsValidator]status),
76 allocMap: make(map[*itemsValidator]string),
77 redeemMap: make(map[*itemsValidator]string),
78 },
79 poolOfBasicCommonValidators: basicCommonValidatorsPool{
80 Pool: &sync.Pool{
81 New: func() any {
82 s := &basicCommonValidator{}
83
84 return s
85 },
86 },
87 debugMap: make(map[*basicCommonValidator]status),
88 allocMap: make(map[*basicCommonValidator]string),
89 redeemMap: make(map[*basicCommonValidator]string),
90 },
91 poolOfHeaderValidators: headerValidatorsPool{
92 Pool: &sync.Pool{
93 New: func() any {
94 s := &HeaderValidator{}
95
96 return s
97 },
98 },
99 debugMap: make(map[*HeaderValidator]status),
100 allocMap: make(map[*HeaderValidator]string),
101 redeemMap: make(map[*HeaderValidator]string),
102 },
103 poolOfParamValidators: paramValidatorsPool{
104 Pool: &sync.Pool{
105 New: func() any {
106 s := &ParamValidator{}
107
108 return s
109 },
110 },
111 debugMap: make(map[*ParamValidator]status),
112 allocMap: make(map[*ParamValidator]string),
113 redeemMap: make(map[*ParamValidator]string),
114 },
115 poolOfBasicSliceValidators: basicSliceValidatorsPool{
116 Pool: &sync.Pool{
117 New: func() any {
118 s := &basicSliceValidator{}
119
120 return s
121 },
122 },
123 debugMap: make(map[*basicSliceValidator]status),
124 allocMap: make(map[*basicSliceValidator]string),
125 redeemMap: make(map[*basicSliceValidator]string),
126 },
127 poolOfNumberValidators: numberValidatorsPool{
128 Pool: &sync.Pool{
129 New: func() any {
130 s := &numberValidator{}
131
132 return s
133 },
134 },
135 debugMap: make(map[*numberValidator]status),
136 allocMap: make(map[*numberValidator]string),
137 redeemMap: make(map[*numberValidator]string),
138 },
139 poolOfStringValidators: stringValidatorsPool{
140 Pool: &sync.Pool{
141 New: func() any {
142 s := &stringValidator{}
143
144 return s
145 },
146 },
147 debugMap: make(map[*stringValidator]status),
148 allocMap: make(map[*stringValidator]string),
149 redeemMap: make(map[*stringValidator]string),
150 },
151 poolOfSchemaPropsValidators: schemaPropsValidatorsPool{
152 Pool: &sync.Pool{
153 New: func() any {
154 s := &schemaPropsValidator{}
155
156 return s
157 },
158 },
159 debugMap: make(map[*schemaPropsValidator]status),
160 allocMap: make(map[*schemaPropsValidator]string),
161 redeemMap: make(map[*schemaPropsValidator]string),
162 },
163 poolOfFormatValidators: formatValidatorsPool{
164 Pool: &sync.Pool{
165 New: func() any {
166 s := &formatValidator{}
167
168 return s
169 },
170 },
171 debugMap: make(map[*formatValidator]status),
172 allocMap: make(map[*formatValidator]string),
173 redeemMap: make(map[*formatValidator]string),
174 },
175 poolOfTypeValidators: typeValidatorsPool{
176 Pool: &sync.Pool{
177 New: func() any {
178 s := &typeValidator{}
179
180 return s
181 },
182 },
183 debugMap: make(map[*typeValidator]status),
184 allocMap: make(map[*typeValidator]string),
185 redeemMap: make(map[*typeValidator]string),
186 },
187 poolOfSchemas: schemasPool{
188 Pool: &sync.Pool{
189 New: func() any {
190 s := &spec.Schema{}
191
192 return s
193 },
194 },
195 debugMap: make(map[*spec.Schema]status),
196 allocMap: make(map[*spec.Schema]string),
197 redeemMap: make(map[*spec.Schema]string),
198 },
199 poolOfResults: resultsPool{
200 Pool: &sync.Pool{
201 New: func() any {
202 s := &Result{}
203
204 return s
205 },
206 },
207 debugMap: make(map[*Result]status),
208 allocMap: make(map[*Result]string),
209 redeemMap: make(map[*Result]string),
210 },
211 }
212 }
213
214 const (
215 statusFresh status = iota + 1
216 statusRecycled
217 statusRedeemed
218 )
219
220 func (s status) String() string {
221 switch s {
222 case statusFresh:
223 return "fresh"
224 case statusRecycled:
225 return "recycled"
226 case statusRedeemed:
227 return "redeemed"
228 default:
229 panic(fmt.Errorf("invalid status: %d", s))
230 }
231 }
232
233 type (
234
235 status uint8
236
237 allPools struct {
238
239
240
241 poolOfSchemaValidators schemaValidatorsPool
242 poolOfObjectValidators objectValidatorsPool
243 poolOfSliceValidators sliceValidatorsPool
244 poolOfItemsValidators itemsValidatorsPool
245 poolOfBasicCommonValidators basicCommonValidatorsPool
246 poolOfHeaderValidators headerValidatorsPool
247 poolOfParamValidators paramValidatorsPool
248 poolOfBasicSliceValidators basicSliceValidatorsPool
249 poolOfNumberValidators numberValidatorsPool
250 poolOfStringValidators stringValidatorsPool
251 poolOfSchemaPropsValidators schemaPropsValidatorsPool
252 poolOfFormatValidators formatValidatorsPool
253 poolOfTypeValidators typeValidatorsPool
254 poolOfSchemas schemasPool
255 poolOfResults resultsPool
256 }
257
258 schemaValidatorsPool struct {
259 *sync.Pool
260 debugMap map[*SchemaValidator]status
261 allocMap map[*SchemaValidator]string
262 redeemMap map[*SchemaValidator]string
263 mx sync.Mutex
264 }
265
266 objectValidatorsPool struct {
267 *sync.Pool
268 debugMap map[*objectValidator]status
269 allocMap map[*objectValidator]string
270 redeemMap map[*objectValidator]string
271 mx sync.Mutex
272 }
273
274 sliceValidatorsPool struct {
275 *sync.Pool
276 debugMap map[*schemaSliceValidator]status
277 allocMap map[*schemaSliceValidator]string
278 redeemMap map[*schemaSliceValidator]string
279 mx sync.Mutex
280 }
281
282 itemsValidatorsPool struct {
283 *sync.Pool
284 debugMap map[*itemsValidator]status
285 allocMap map[*itemsValidator]string
286 redeemMap map[*itemsValidator]string
287 mx sync.Mutex
288 }
289
290 basicCommonValidatorsPool struct {
291 *sync.Pool
292 debugMap map[*basicCommonValidator]status
293 allocMap map[*basicCommonValidator]string
294 redeemMap map[*basicCommonValidator]string
295 mx sync.Mutex
296 }
297
298 headerValidatorsPool struct {
299 *sync.Pool
300 debugMap map[*HeaderValidator]status
301 allocMap map[*HeaderValidator]string
302 redeemMap map[*HeaderValidator]string
303 mx sync.Mutex
304 }
305
306 paramValidatorsPool struct {
307 *sync.Pool
308 debugMap map[*ParamValidator]status
309 allocMap map[*ParamValidator]string
310 redeemMap map[*ParamValidator]string
311 mx sync.Mutex
312 }
313
314 basicSliceValidatorsPool struct {
315 *sync.Pool
316 debugMap map[*basicSliceValidator]status
317 allocMap map[*basicSliceValidator]string
318 redeemMap map[*basicSliceValidator]string
319 mx sync.Mutex
320 }
321
322 numberValidatorsPool struct {
323 *sync.Pool
324 debugMap map[*numberValidator]status
325 allocMap map[*numberValidator]string
326 redeemMap map[*numberValidator]string
327 mx sync.Mutex
328 }
329
330 stringValidatorsPool struct {
331 *sync.Pool
332 debugMap map[*stringValidator]status
333 allocMap map[*stringValidator]string
334 redeemMap map[*stringValidator]string
335 mx sync.Mutex
336 }
337
338 schemaPropsValidatorsPool struct {
339 *sync.Pool
340 debugMap map[*schemaPropsValidator]status
341 allocMap map[*schemaPropsValidator]string
342 redeemMap map[*schemaPropsValidator]string
343 mx sync.Mutex
344 }
345
346 formatValidatorsPool struct {
347 *sync.Pool
348 debugMap map[*formatValidator]status
349 allocMap map[*formatValidator]string
350 redeemMap map[*formatValidator]string
351 mx sync.Mutex
352 }
353
354 typeValidatorsPool struct {
355 *sync.Pool
356 debugMap map[*typeValidator]status
357 allocMap map[*typeValidator]string
358 redeemMap map[*typeValidator]string
359 mx sync.Mutex
360 }
361
362 schemasPool struct {
363 *sync.Pool
364 debugMap map[*spec.Schema]status
365 allocMap map[*spec.Schema]string
366 redeemMap map[*spec.Schema]string
367 mx sync.Mutex
368 }
369
370 resultsPool struct {
371 *sync.Pool
372 debugMap map[*Result]status
373 allocMap map[*Result]string
374 redeemMap map[*Result]string
375 mx sync.Mutex
376 }
377 )
378
379 func (p *schemaValidatorsPool) BorrowValidator() *SchemaValidator {
380 s := p.Get().(*SchemaValidator)
381
382 p.mx.Lock()
383 defer p.mx.Unlock()
384 x, ok := p.debugMap[s]
385 if !ok {
386 p.debugMap[s] = statusFresh
387 } else {
388 if x != statusRedeemed {
389 panic("recycled schema should have been redeemed")
390 }
391 p.debugMap[s] = statusRecycled
392 }
393 p.allocMap[s] = caller()
394
395 return s
396 }
397
398 func (p *schemaValidatorsPool) RedeemValidator(s *SchemaValidator) {
399
400 p.mx.Lock()
401 defer p.mx.Unlock()
402 x, ok := p.debugMap[s]
403 if !ok {
404 panic("redeemed schema should have been allocated")
405 }
406 if x != statusRecycled && x != statusFresh {
407 panic("redeemed schema should have been allocated from a fresh or recycled pointer")
408 }
409 p.debugMap[s] = statusRedeemed
410 p.redeemMap[s] = caller()
411 p.Put(s)
412 }
413
414 func (p *objectValidatorsPool) BorrowValidator() *objectValidator {
415 s := p.Get().(*objectValidator)
416
417 p.mx.Lock()
418 defer p.mx.Unlock()
419 x, ok := p.debugMap[s]
420 if !ok {
421 p.debugMap[s] = statusFresh
422 } else {
423 if x != statusRedeemed {
424 panic("recycled object should have been redeemed")
425 }
426 p.debugMap[s] = statusRecycled
427 }
428 p.allocMap[s] = caller()
429
430 return s
431 }
432
433 func (p *objectValidatorsPool) RedeemValidator(s *objectValidator) {
434 p.mx.Lock()
435 defer p.mx.Unlock()
436 x, ok := p.debugMap[s]
437 if !ok {
438 panic("redeemed object should have been allocated")
439 }
440 if x != statusRecycled && x != statusFresh {
441 panic("redeemed object should have been allocated from a fresh or recycled pointer")
442 }
443 p.debugMap[s] = statusRedeemed
444 p.redeemMap[s] = caller()
445 p.Put(s)
446 }
447
448 func (p *sliceValidatorsPool) BorrowValidator() *schemaSliceValidator {
449 s := p.Get().(*schemaSliceValidator)
450
451 p.mx.Lock()
452 defer p.mx.Unlock()
453 x, ok := p.debugMap[s]
454 if !ok {
455 p.debugMap[s] = statusFresh
456 } else {
457 if x != statusRedeemed {
458 panic("recycled schemaSliceValidator should have been redeemed")
459 }
460 p.debugMap[s] = statusRecycled
461 }
462 p.allocMap[s] = caller()
463
464 return s
465 }
466
467 func (p *sliceValidatorsPool) RedeemValidator(s *schemaSliceValidator) {
468 p.mx.Lock()
469 defer p.mx.Unlock()
470 x, ok := p.debugMap[s]
471 if !ok {
472 panic("redeemed schemaSliceValidator should have been allocated")
473 }
474 if x != statusRecycled && x != statusFresh {
475 panic("redeemed schemaSliceValidator should have been allocated from a fresh or recycled pointer")
476 }
477 p.debugMap[s] = statusRedeemed
478 p.redeemMap[s] = caller()
479 p.Put(s)
480 }
481
482 func (p *itemsValidatorsPool) BorrowValidator() *itemsValidator {
483 s := p.Get().(*itemsValidator)
484
485 p.mx.Lock()
486 defer p.mx.Unlock()
487 x, ok := p.debugMap[s]
488 if !ok {
489 p.debugMap[s] = statusFresh
490 } else {
491 if x != statusRedeemed {
492 panic("recycled itemsValidator should have been redeemed")
493 }
494 p.debugMap[s] = statusRecycled
495 }
496 p.allocMap[s] = caller()
497
498 return s
499 }
500
501 func (p *itemsValidatorsPool) RedeemValidator(s *itemsValidator) {
502 p.mx.Lock()
503 defer p.mx.Unlock()
504 x, ok := p.debugMap[s]
505 if !ok {
506 panic("redeemed itemsValidator should have been allocated")
507 }
508 if x != statusRecycled && x != statusFresh {
509 panic("redeemed itemsValidator should have been allocated from a fresh or recycled pointer")
510 }
511 p.debugMap[s] = statusRedeemed
512 p.redeemMap[s] = caller()
513 p.Put(s)
514 }
515
516 func (p *basicCommonValidatorsPool) BorrowValidator() *basicCommonValidator {
517 s := p.Get().(*basicCommonValidator)
518
519 p.mx.Lock()
520 defer p.mx.Unlock()
521 x, ok := p.debugMap[s]
522 if !ok {
523 p.debugMap[s] = statusFresh
524 } else {
525 if x != statusRedeemed {
526 panic("recycled basicCommonValidator should have been redeemed")
527 }
528 p.debugMap[s] = statusRecycled
529 }
530 p.allocMap[s] = caller()
531
532 return s
533 }
534
535 func (p *basicCommonValidatorsPool) RedeemValidator(s *basicCommonValidator) {
536 p.mx.Lock()
537 defer p.mx.Unlock()
538 x, ok := p.debugMap[s]
539 if !ok {
540 panic("redeemed basicCommonValidator should have been allocated")
541 }
542 if x != statusRecycled && x != statusFresh {
543 panic("redeemed basicCommonValidator should have been allocated from a fresh or recycled pointer")
544 }
545 p.debugMap[s] = statusRedeemed
546 p.redeemMap[s] = caller()
547 p.Put(s)
548 }
549
550 func (p *headerValidatorsPool) BorrowValidator() *HeaderValidator {
551 s := p.Get().(*HeaderValidator)
552
553 p.mx.Lock()
554 defer p.mx.Unlock()
555 x, ok := p.debugMap[s]
556 if !ok {
557 p.debugMap[s] = statusFresh
558 } else {
559 if x != statusRedeemed {
560 panic("recycled HeaderValidator should have been redeemed")
561 }
562 p.debugMap[s] = statusRecycled
563 }
564 p.allocMap[s] = caller()
565
566 return s
567 }
568
569 func (p *headerValidatorsPool) RedeemValidator(s *HeaderValidator) {
570 p.mx.Lock()
571 defer p.mx.Unlock()
572 x, ok := p.debugMap[s]
573 if !ok {
574 panic("redeemed header should have been allocated")
575 }
576 if x != statusRecycled && x != statusFresh {
577 panic("redeemed header should have been allocated from a fresh or recycled pointer")
578 }
579 p.debugMap[s] = statusRedeemed
580 p.redeemMap[s] = caller()
581 p.Put(s)
582 }
583
584 func (p *paramValidatorsPool) BorrowValidator() *ParamValidator {
585 s := p.Get().(*ParamValidator)
586
587 p.mx.Lock()
588 defer p.mx.Unlock()
589 x, ok := p.debugMap[s]
590 if !ok {
591 p.debugMap[s] = statusFresh
592 } else {
593 if x != statusRedeemed {
594 panic("recycled param should have been redeemed")
595 }
596 p.debugMap[s] = statusRecycled
597 }
598 p.allocMap[s] = caller()
599
600 return s
601 }
602
603 func (p *paramValidatorsPool) RedeemValidator(s *ParamValidator) {
604 p.mx.Lock()
605 defer p.mx.Unlock()
606 x, ok := p.debugMap[s]
607 if !ok {
608 panic("redeemed param should have been allocated")
609 }
610 if x != statusRecycled && x != statusFresh {
611 panic("redeemed param should have been allocated from a fresh or recycled pointer")
612 }
613 p.debugMap[s] = statusRedeemed
614 p.redeemMap[s] = caller()
615 p.Put(s)
616 }
617
618 func (p *basicSliceValidatorsPool) BorrowValidator() *basicSliceValidator {
619 s := p.Get().(*basicSliceValidator)
620
621 p.mx.Lock()
622 defer p.mx.Unlock()
623 x, ok := p.debugMap[s]
624 if !ok {
625 p.debugMap[s] = statusFresh
626 } else {
627 if x != statusRedeemed {
628 panic("recycled basicSliceValidator should have been redeemed")
629 }
630 p.debugMap[s] = statusRecycled
631 }
632 p.allocMap[s] = caller()
633
634 return s
635 }
636
637 func (p *basicSliceValidatorsPool) RedeemValidator(s *basicSliceValidator) {
638 p.mx.Lock()
639 defer p.mx.Unlock()
640 x, ok := p.debugMap[s]
641 if !ok {
642 panic("redeemed basicSliceValidator should have been allocated")
643 }
644 if x != statusRecycled && x != statusFresh {
645 panic("redeemed basicSliceValidator should have been allocated from a fresh or recycled pointer")
646 }
647 p.debugMap[s] = statusRedeemed
648 p.redeemMap[s] = caller()
649 p.Put(s)
650 }
651
652 func (p *numberValidatorsPool) BorrowValidator() *numberValidator {
653 s := p.Get().(*numberValidator)
654
655 p.mx.Lock()
656 defer p.mx.Unlock()
657 x, ok := p.debugMap[s]
658 if !ok {
659 p.debugMap[s] = statusFresh
660 } else {
661 if x != statusRedeemed {
662 panic("recycled number should have been redeemed")
663 }
664 p.debugMap[s] = statusRecycled
665 }
666 p.allocMap[s] = caller()
667
668 return s
669 }
670
671 func (p *numberValidatorsPool) RedeemValidator(s *numberValidator) {
672 p.mx.Lock()
673 defer p.mx.Unlock()
674 x, ok := p.debugMap[s]
675 if !ok {
676 panic("redeemed number should have been allocated")
677 }
678 if x != statusRecycled && x != statusFresh {
679 panic("redeemed number should have been allocated from a fresh or recycled pointer")
680 }
681 p.debugMap[s] = statusRedeemed
682 p.redeemMap[s] = caller()
683 p.Put(s)
684 }
685
686 func (p *stringValidatorsPool) BorrowValidator() *stringValidator {
687 s := p.Get().(*stringValidator)
688
689 p.mx.Lock()
690 defer p.mx.Unlock()
691 x, ok := p.debugMap[s]
692 if !ok {
693 p.debugMap[s] = statusFresh
694 } else {
695 if x != statusRedeemed {
696 panic("recycled string should have been redeemed")
697 }
698 p.debugMap[s] = statusRecycled
699 }
700 p.allocMap[s] = caller()
701
702 return s
703 }
704
705 func (p *stringValidatorsPool) RedeemValidator(s *stringValidator) {
706 p.mx.Lock()
707 defer p.mx.Unlock()
708 x, ok := p.debugMap[s]
709 if !ok {
710 panic("redeemed string should have been allocated")
711 }
712 if x != statusRecycled && x != statusFresh {
713 panic("redeemed string should have been allocated from a fresh or recycled pointer")
714 }
715 p.debugMap[s] = statusRedeemed
716 p.redeemMap[s] = caller()
717 p.Put(s)
718 }
719
720 func (p *schemaPropsValidatorsPool) BorrowValidator() *schemaPropsValidator {
721 s := p.Get().(*schemaPropsValidator)
722
723 p.mx.Lock()
724 defer p.mx.Unlock()
725 x, ok := p.debugMap[s]
726 if !ok {
727 p.debugMap[s] = statusFresh
728 } else {
729 if x != statusRedeemed {
730 panic("recycled param should have been redeemed")
731 }
732 p.debugMap[s] = statusRecycled
733 }
734 p.allocMap[s] = caller()
735
736 return s
737 }
738
739 func (p *schemaPropsValidatorsPool) RedeemValidator(s *schemaPropsValidator) {
740 p.mx.Lock()
741 defer p.mx.Unlock()
742 x, ok := p.debugMap[s]
743 if !ok {
744 panic("redeemed schemaProps should have been allocated")
745 }
746 if x != statusRecycled && x != statusFresh {
747 panic("redeemed schemaProps should have been allocated from a fresh or recycled pointer")
748 }
749 p.debugMap[s] = statusRedeemed
750 p.redeemMap[s] = caller()
751 p.Put(s)
752 }
753
754 func (p *formatValidatorsPool) BorrowValidator() *formatValidator {
755 s := p.Get().(*formatValidator)
756
757 p.mx.Lock()
758 defer p.mx.Unlock()
759 x, ok := p.debugMap[s]
760 if !ok {
761 p.debugMap[s] = statusFresh
762 } else {
763 if x != statusRedeemed {
764 panic("recycled format should have been redeemed")
765 }
766 p.debugMap[s] = statusRecycled
767 }
768 p.allocMap[s] = caller()
769
770 return s
771 }
772
773 func (p *formatValidatorsPool) RedeemValidator(s *formatValidator) {
774 p.mx.Lock()
775 defer p.mx.Unlock()
776 x, ok := p.debugMap[s]
777 if !ok {
778 panic("redeemed format should have been allocated")
779 }
780 if x != statusRecycled && x != statusFresh {
781 panic("redeemed format should have been allocated from a fresh or recycled pointer")
782 }
783 p.debugMap[s] = statusRedeemed
784 p.redeemMap[s] = caller()
785 p.Put(s)
786 }
787
788 func (p *typeValidatorsPool) BorrowValidator() *typeValidator {
789 s := p.Get().(*typeValidator)
790
791 p.mx.Lock()
792 defer p.mx.Unlock()
793 x, ok := p.debugMap[s]
794 if !ok {
795 p.debugMap[s] = statusFresh
796 } else {
797 if x != statusRedeemed {
798 panic("recycled type should have been redeemed")
799 }
800 p.debugMap[s] = statusRecycled
801 }
802 p.allocMap[s] = caller()
803
804 return s
805 }
806
807 func (p *typeValidatorsPool) RedeemValidator(s *typeValidator) {
808 p.mx.Lock()
809 defer p.mx.Unlock()
810 x, ok := p.debugMap[s]
811 if !ok {
812 panic("redeemed type should have been allocated")
813 }
814 if x != statusRecycled && x != statusFresh {
815 panic(fmt.Errorf("redeemed type should have been allocated from a fresh or recycled pointer. Got status %s, already redeamed at: %s", x, p.redeemMap[s]))
816 }
817 p.debugMap[s] = statusRedeemed
818 p.redeemMap[s] = caller()
819 p.Put(s)
820 }
821
822 func (p *schemasPool) BorrowSchema() *spec.Schema {
823 s := p.Get().(*spec.Schema)
824
825 p.mx.Lock()
826 defer p.mx.Unlock()
827 x, ok := p.debugMap[s]
828 if !ok {
829 p.debugMap[s] = statusFresh
830 } else {
831 if x != statusRedeemed {
832 panic("recycled spec.Schema should have been redeemed")
833 }
834 p.debugMap[s] = statusRecycled
835 }
836 p.allocMap[s] = caller()
837
838 return s
839 }
840
841 func (p *schemasPool) RedeemSchema(s *spec.Schema) {
842 p.mx.Lock()
843 defer p.mx.Unlock()
844 x, ok := p.debugMap[s]
845 if !ok {
846 panic("redeemed spec.Schema should have been allocated")
847 }
848 if x != statusRecycled && x != statusFresh {
849 panic("redeemed spec.Schema should have been allocated from a fresh or recycled pointer")
850 }
851 p.debugMap[s] = statusRedeemed
852 p.redeemMap[s] = caller()
853 p.Put(s)
854 }
855
856 func (p *resultsPool) BorrowResult() *Result {
857 s := p.Get().(*Result).cleared()
858
859 p.mx.Lock()
860 defer p.mx.Unlock()
861 x, ok := p.debugMap[s]
862 if !ok {
863 p.debugMap[s] = statusFresh
864 } else {
865 if x != statusRedeemed {
866 panic("recycled result should have been redeemed")
867 }
868 p.debugMap[s] = statusRecycled
869 }
870 p.allocMap[s] = caller()
871
872 return s
873 }
874
875 func (p *resultsPool) RedeemResult(s *Result) {
876 if s == emptyResult {
877 if len(s.Errors) > 0 || len(s.Warnings) > 0 {
878 panic("empty result should not mutate")
879 }
880 return
881 }
882 p.mx.Lock()
883 defer p.mx.Unlock()
884 x, ok := p.debugMap[s]
885 if !ok {
886 panic("redeemed Result should have been allocated")
887 }
888 if x != statusRecycled && x != statusFresh {
889 panic("redeemed Result should have been allocated from a fresh or recycled pointer")
890 }
891 p.debugMap[s] = statusRedeemed
892 p.redeemMap[s] = caller()
893 p.Put(s)
894 }
895
896 func (p *allPools) allIsRedeemed(t testing.TB) bool {
897 outcome := true
898 for k, v := range p.poolOfSchemaValidators.debugMap {
899 if v == statusRedeemed {
900 continue
901 }
902 t.Logf("schemaValidator should be redeemed. Allocated by: %s", p.poolOfSchemaValidators.allocMap[k])
903 outcome = false
904 }
905 for k, v := range p.poolOfObjectValidators.debugMap {
906 if v == statusRedeemed {
907 continue
908 }
909 t.Logf("objectValidator should be redeemed. Allocated by: %s", p.poolOfObjectValidators.allocMap[k])
910 outcome = false
911 }
912 for k, v := range p.poolOfSliceValidators.debugMap {
913 if v == statusRedeemed {
914 continue
915 }
916 t.Logf("sliceValidator should be redeemed. Allocated by: %s", p.poolOfSliceValidators.allocMap[k])
917 outcome = false
918 }
919 for k, v := range p.poolOfItemsValidators.debugMap {
920 if v == statusRedeemed {
921 continue
922 }
923 t.Logf("itemsValidator should be redeemed. Allocated by: %s", p.poolOfItemsValidators.allocMap[k])
924 outcome = false
925 }
926 for k, v := range p.poolOfBasicCommonValidators.debugMap {
927 if v == statusRedeemed {
928 continue
929 }
930 t.Logf("basicCommonValidator should be redeemed. Allocated by: %s", p.poolOfBasicCommonValidators.allocMap[k])
931 outcome = false
932 }
933 for k, v := range p.poolOfHeaderValidators.debugMap {
934 if v == statusRedeemed {
935 continue
936 }
937 t.Logf("headerValidator should be redeemed. Allocated by: %s", p.poolOfHeaderValidators.allocMap[k])
938 outcome = false
939 }
940 for k, v := range p.poolOfParamValidators.debugMap {
941 if v == statusRedeemed {
942 continue
943 }
944 t.Logf("paramValidator should be redeemed. Allocated by: %s", p.poolOfParamValidators.allocMap[k])
945 outcome = false
946 }
947 for k, v := range p.poolOfBasicSliceValidators.debugMap {
948 if v == statusRedeemed {
949 continue
950 }
951 t.Logf("basicSliceValidator should be redeemed. Allocated by: %s", p.poolOfBasicSliceValidators.allocMap[k])
952 outcome = false
953 }
954 for k, v := range p.poolOfNumberValidators.debugMap {
955 if v == statusRedeemed {
956 continue
957 }
958 t.Logf("numberValidator should be redeemed. Allocated by: %s", p.poolOfNumberValidators.allocMap[k])
959 outcome = false
960 }
961 for k, v := range p.poolOfStringValidators.debugMap {
962 if v == statusRedeemed {
963 continue
964 }
965 t.Logf("stringValidator should be redeemed. Allocated by: %s", p.poolOfStringValidators.allocMap[k])
966 outcome = false
967 }
968 for k, v := range p.poolOfSchemaPropsValidators.debugMap {
969 if v == statusRedeemed {
970 continue
971 }
972 t.Logf("schemaPropsValidator should be redeemed. Allocated by: %s", p.poolOfSchemaPropsValidators.allocMap[k])
973 outcome = false
974 }
975 for k, v := range p.poolOfFormatValidators.debugMap {
976 if v == statusRedeemed {
977 continue
978 }
979 t.Logf("formatValidator should be redeemed. Allocated by: %s", p.poolOfFormatValidators.allocMap[k])
980 outcome = false
981 }
982 for k, v := range p.poolOfTypeValidators.debugMap {
983 if v == statusRedeemed {
984 continue
985 }
986 t.Logf("typeValidator should be redeemed. Allocated by: %s", p.poolOfTypeValidators.allocMap[k])
987 outcome = false
988 }
989 for k, v := range p.poolOfSchemas.debugMap {
990 if v == statusRedeemed {
991 continue
992 }
993 t.Logf("schemas should be redeemed. Allocated by: %s", p.poolOfSchemas.allocMap[k])
994 outcome = false
995 }
996 for k, v := range p.poolOfResults.debugMap {
997 if v == statusRedeemed {
998 continue
999 }
1000 t.Logf("result should be redeemed. Allocated by: %s", p.poolOfResults.allocMap[k])
1001 outcome = false
1002 }
1003
1004 return outcome
1005 }
1006
1007 func caller() string {
1008 pc, _, _, _ := runtime.Caller(3)
1009 from, line := runtime.FuncForPC(pc).FileLine(pc)
1010
1011 return fmt.Sprintf("%s:%d", from, line)
1012 }
1013
View as plain text