vlist.c 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. /*
  2. * Copyright (C) 2012 Felix Fietkau <nbd@openwrt.org>
  3. *
  4. * Permission to use, copy, modify, and/or distribute this software for any
  5. * purpose with or without fee is hereby granted, provided that the above
  6. * copyright notice and this permission notice appear in all copies.
  7. *
  8. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  9. * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  10. * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  11. * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  12. * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  13. * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  14. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  15. */
  16. #include "vlist.h"
  17. void
  18. vlist_init(struct vlist_tree *tree, avl_tree_comp cmp, vlist_update_cb update)
  19. {
  20. tree->update = update;
  21. tree->version = 1;
  22. avl_init(&tree->avl, cmp, 0, tree);
  23. }
  24. void
  25. vlist_delete(struct vlist_tree *tree, struct vlist_node *node)
  26. {
  27. if (!tree->no_delete)
  28. avl_delete(&tree->avl, &node->avl);
  29. tree->update(tree, NULL, node);
  30. }
  31. void
  32. vlist_add(struct vlist_tree *tree, struct vlist_node *node, const void *key)
  33. {
  34. struct vlist_node *old_node = NULL;
  35. struct avl_node *anode;
  36. node->avl.key = key;
  37. node->version = tree->version;
  38. anode = avl_find(&tree->avl, key);
  39. if (anode) {
  40. old_node = container_of(anode, struct vlist_node, avl);
  41. if (tree->keep_old || tree->no_delete) {
  42. old_node->version = tree->version;
  43. goto update_only;
  44. }
  45. avl_delete(&tree->avl, anode);
  46. }
  47. avl_insert(&tree->avl, &node->avl);
  48. update_only:
  49. tree->update(tree, node, old_node);
  50. }
  51. void
  52. vlist_flush(struct vlist_tree *tree)
  53. {
  54. struct vlist_node *node, *tmp;
  55. avl_for_each_element_safe(&tree->avl, node, avl, tmp) {
  56. if ((node->version == tree->version || node->version == -1) &&
  57. tree->version != -1)
  58. continue;
  59. vlist_delete(tree, node);
  60. }
  61. }
  62. void
  63. vlist_flush_all(struct vlist_tree *tree)
  64. {
  65. tree->version = -1;
  66. vlist_flush(tree);
  67. }