@@ -662,72 +662,116 @@ insert_store_key_value_pair:
662662 # ANCHOR_END: insert-allocate
663663
664664# ANCHOR: insert-search
665- insert_search:
666- ldxh r4, [r2 + INSN_INSERT_KEY_OFF] # r4 = insn.key;
667- mov64 r2, NULL # r2 = parent = null;
668- ldxdw r3, [r1 + IB_TREE_DATA_ROOT_OFF] # r3 = cursor = root;
665+ insert_search: # r9 = node
666+ ldxh r4, [r2 + INSN_INSERT_KEY_OFF] # r4 = insn.key;
667+ mov64 r2, NULL # r2 = parent = null;
668+ ldxdw r3, [r1 + IB_TREE_DATA_ROOT_OFF] # r3 = cursor = root;
669669
670670insert_search_loop:
671671 jeq r3, NULL, insert_to_tree
672- mov64 r2, r3 # r2 = parent = cursor;
673- ldxh r5, [r3 + TREE_NODE_KEY_OFF] # r5 = cursor.key;
672+ mov64 r2, r3 # r2 = parent = cursor;
673+ ldxh r5, [r3 + TREE_NODE_KEY_OFF] # r5 = cursor.key;
674674 jlt r4, r5, insert_search_branch_l
675675 jgt r4, r5, insert_search_branch_r
676676 mov64 r0, E_KEY_EXISTS # Error if key already exists.
677677 exit
678678insert_search_branch_l:
679- ldxdw r3, [r3 + TREE_NODE_CHILD_L_OFF] # r3 = cursor.child[left];
679+ ldxdw r3, [r3 + TREE_NODE_CHILD_L_OFF] # r3 = cursor.child[left];
680680 ja insert_search_loop
681681insert_search_branch_r:
682- ldxdw r3, [r3 + TREE_NODE_CHILD_R_OFF] # r3 = cursor.child[right];
682+ ldxdw r3, [r3 + TREE_NODE_CHILD_R_OFF] # r3 = cursor.child[right];
683683 ja insert_search_loop
684684# ANCHOR_END: insert-search
685685
686686# ANCHOR: insert-to-tree
687687insert_to_tree:
688688 # Flag new node as red and store parent pointer.
689689 # ---------------------------------------------------------------------
690- stb [r9 + TREE_NODE_COLOR_OFF], TREE_COLOR_R # node.color = red;
691- stxdw [r9 + TREE_NODE_PARENT_OFF], r2 # node.parent = parent;
690+ stb [r9 + TREE_NODE_COLOR_OFF], TREE_COLOR_R # node.color = red;
691+ stxdw [r9 + TREE_NODE_PARENT_OFF], r2 # node.parent = parent;
692692
693693 # Handle case of new node at root.
694694 # ---------------------------------------------------------------------
695695 jne r2, NULL, insert_get_child_dir
696- stxdw [r1 + IB_TREE_DATA_ROOT_OFF], r9 # root = node;
696+ stxdw [r1 + IB_TREE_DATA_ROOT_OFF], r9 # root = node;
697697 exit # Parent is null, new node at root.
698698# ANCHOR_END: insert-to-tree
699699
700700# ANCHOR: insert-fixup
701701insert_get_child_dir:
702702 # Get child direction, set at parent.
703703 # ---------------------------------------------------------------------
704- ldxh r5, [r2 + TREE_NODE_KEY_OFF] # r5 = parent.key;
704+ ldxh r5, [r2 + TREE_NODE_KEY_OFF] # r5 = parent.key;
705705 jgt r4, r5, insert_get_child_dir_branch_r
706706insert_get_child_dir_branch_l:
707- stxdw [r2 + TREE_NODE_CHILD_L_OFF], r9 # parent.child[left] = node;
707+ stxdw [r2 + TREE_NODE_CHILD_L_OFF], r9 # parent.child[left] = node;
708708 ja insert_fixup_main
709709insert_get_child_dir_branch_r:
710- stxdw [r2 + TREE_NODE_CHILD_R_OFF], r9 # parent.child[right] = node;
710+ stxdw [r2 + TREE_NODE_CHILD_R_OFF], r9 # parent.child[right] = node;
711711
712712insert_fixup_main:
713713 # Case 1.
714714 # ---------------------------------------------------------------------
715- ldxb r6, [r2 + TREE_NODE_COLOR_OFF] # r6 = parent.color;
715+ ldxb r6, [r2 + TREE_NODE_COLOR_OFF] # r6 = parent.color;
716716 jne r6, TREE_COLOR_B, insert_fixup_check_case_4
717717 exit # If parent is black, tree is still valid, so exit.
718718
719719insert_fixup_check_case_4:
720720 # Check case 4.
721721 # ---------------------------------------------------------------------
722- ldxdw r3, [r2 + TREE_NODE_PARENT_OFF] # r3 = grandparent;
722+ ldxdw r3, [r2 + TREE_NODE_PARENT_OFF] # r3 = grandparent;
723723 jne r3, NULL, insert_fixup_check_case_5_6
724- stb [r2 + TREE_NODE_COLOR_OFF], TREE_COLOR_B # parent.color = black;
724+ stb [r2 + TREE_NODE_COLOR_OFF], TREE_COLOR_B # parent.color = black;
725725 exit
726726
727727insert_fixup_check_case_5_6:
728- # Get parent's direction as a child .
728+ # Get uncle and check for case 5 or 6 .
729729 # ---------------------------------------------------------------------
730+ ldxh r4, [r3 + TREE_NODE_KEY_OFF] # r4 = grandparent.key;
731+ jgt r5, r4, insert_fixup_check_case_5_6_dir_r
732+
733+ insert_fixup_check_case_5_6_dir_l:
734+ ldxdw r7, [r3 + TREE_NODE_CHILD_R_OFF] # r7 = uncle;
735+ jeq r7, NULL, insert_fixup_case_5_6_dir_l
736+ ldxb r8, [r7 + TREE_NODE_COLOR_OFF] # r8 = uncle.color;
737+ jne r8, TREE_COLOR_B, insert_fixup_case_2
738+
739+ insert_fixup_case_5_6_dir_l:
740+ ldxdw r8, [r2 + TREE_NODE_CHILD_R_OFF] # r8 = parent.child[right];
741+ jne r9, r8, insert_fixup_case_6_dir_l
742+
743+ insert_fixup_case_5_dir_l:
744+ # rotate_subtree(tree_header, parent, left);
745+ # ---------------------------------------------------------------------
746+
747+ insert_fixup_case_6_dir_l:
748+ exit
749+
750+ insert_fixup_check_case_5_6_dir_r:
751+ ldxdw r7, [r3 + TREE_NODE_CHILD_L_OFF] # r7 = uncle;
752+ jeq r7, NULL, insert_fixup_case_5_6_dir_r
753+ ldxb r8, [r7 + TREE_NODE_COLOR_OFF] # r8 = uncle.color;
754+ jne r8, TREE_COLOR_B, insert_fixup_case_2
755+
756+ insert_fixup_case_5_6_dir_r:
757+ ldxdw r8, [r2 + TREE_NODE_CHILD_L_OFF] # r8 = parent.child[left];
758+ jne r9, r8, insert_fixup_case_6_dir_r
759+
760+ insert_fixup_case_5_dir_r:
761+ # rotate_subtree(tree_header, parent, right);
762+ # ---------------------------------------------------------------------
763+
764+ insert_fixup_case_6_dir_r:
730765 exit
766+
767+ insert_fixup_case_2:
768+ stb [r2 + TREE_NODE_COLOR_OFF], TREE_COLOR_B # parent.color = black;
769+ stb [r7 + TREE_NODE_COLOR_OFF], TREE_COLOR_B # uncle.color = black;
770+ stb [r3 + TREE_NODE_COLOR_OFF], TREE_COLOR_R # grandparent.color = red;
771+ mov64 r9, r3 # r9 = node = grandparent;
772+ ldxdw r2, [r9 + TREE_NODE_PARENT_OFF] # r2 = parent = node.parent;
773+ jne r2, NULL, insert_fixup_main
774+ exit # Case 3.
731775# ANCHOR_END: insert-fixup
732776
733777
0 commit comments