rb_tree_fuzzing.cpp 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. #include <library/cpp/containers/intrusive_rb_tree/rb_tree.h>
  2. #include <util/generic/deque.h>
  3. #include <stdint.h>
  4. #include <stddef.h>
  5. struct TCmp {
  6. template <class T>
  7. static inline bool Compare(const T& l, const T& r) {
  8. return l.N < r.N;
  9. }
  10. template <class T>
  11. static inline bool Compare(const T& l, ui8 r) {
  12. return l.N < r;
  13. }
  14. template <class T>
  15. static inline bool Compare(ui8 l, const T& r) {
  16. return l < r.N;
  17. }
  18. };
  19. class TNode: public TRbTreeItem<TNode, TCmp> {
  20. public:
  21. inline TNode(ui8 n) noexcept
  22. : N(n)
  23. {
  24. }
  25. ui8 N;
  26. };
  27. using TTree = TRbTree<TNode, TCmp>;
  28. extern "C" int LLVMFuzzerTestOneInput(const ui8* data, size_t size) {
  29. TDeque<TNode> records;
  30. const ui8 half = 128u;
  31. TTree tree;
  32. for (size_t i = 0; i < size; ++i) {
  33. if (data[i] / half == 0) {
  34. records.emplace_back(data[i] % half);
  35. tree.Insert(&records.back());
  36. } else {
  37. auto* ptr = tree.Find(data[i] % half);
  38. if (ptr != nullptr) {
  39. tree.Erase(ptr);
  40. }
  41. }
  42. auto check = [](const TNode& node) {
  43. size_t childrens = 1;
  44. if (node.Left_) {
  45. Y_ENSURE(static_cast<const TNode*>(node.Left_)->N <= node.N);
  46. childrens += node.Left_->Children_;
  47. }
  48. if (node.Right_) {
  49. Y_ENSURE(node.N <= static_cast<const TNode*>(node.Right_)->N);
  50. childrens += node.Right_->Children_;
  51. }
  52. Y_ENSURE(childrens == node.Children_);
  53. };
  54. tree.ForEach(check);
  55. }
  56. return 0;
  57. }