<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Documentudy</title>
    <description>UNIX &amp; Linux Kernel</description>
    <link>https://soopsaram.com/documentudy/</link>
    <atom:link href="https://soopsaram.com/documentudy/feed.xml" rel="self" type="application/rss+xml"/>
    <pubDate>Mon, 01 Aug 2022 01:14:06 +0000</pubDate>
    <lastBuildDate>Mon, 01 Aug 2022 01:14:06 +0000</lastBuildDate>
    <generator>Jekyll v3.9.2</generator>
    
      <item>
        <title>Red-Black Tree in Linux Kernel - Part 2</title>
        <description>&lt;blockquote&gt;
  &lt;p&gt;작성: 숲사람&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href=&quot;http://soopsaram.com/documentudy/2021/11/14/rbtree-in-linux-kernel-part1&quot;&gt;지난 포스트&lt;/a&gt;에서 Red Black Tree의 일반적인 동작 방식을 이해&lt;del&gt;하려고 시도&lt;/del&gt;해 보았다. 이번 포스트에서는 Linux Kernel에서 RB Tree가 어떻게 구현되었는지 살펴볼 것이다. 최신 리눅스 커널 버전은 v5.15 이지만, 이 문서를 쓰던 당시 커널버전은 v4.6 이었기 때문에 소스코드 분석은 v4.6버전 기준으로 하였다. 참고한 소스코드는 문서 하단 References 참고.&lt;/p&gt;

&lt;p&gt;Kernel source에는 lib/rbtree_test.c 파일이 있다. Kernel에서 RB tree를 어떻게 사용하는지 친절하게 예를 들어주는 파일이다. 이를 통해 RB tree 사용법, 그리고 lib/rbtree.c 파일을 분석함으로써, Kernel에서 RB tree의 Insert / Erase 동작은 어떻게 구현되었는지 파악 해볼 것이다.&lt;/p&gt;

&lt;p&gt;아래 소스코드를 보면 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;|&lt;/code&gt; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;+&lt;/code&gt; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;&quot;&lt;/code&gt; 등이 함께 표현되어있는데, 이는 중요도가 낮은 코드는 제거, 불필요한 공백과 indent 를 처리하고, 다른 파일에 위치한 코드를 쉽게 따라가기 위해 내가 만든 코드 분석 방법이다(추후 설명페이지 공유예정).&lt;/p&gt;

&lt;ul id=&quot;markdown-toc&quot;&gt;
  &lt;li&gt;&lt;a href=&quot;#사용법-및-구조체-분석&quot; id=&quot;markdown-toc-사용법-및-구조체-분석&quot;&gt;사용법 및 구조체 분석&lt;/a&gt;    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;#linux-kernel-rb-tree-api-사용법-요약&quot; id=&quot;markdown-toc-linux-kernel-rb-tree-api-사용법-요약&quot;&gt;Linux Kernel RB Tree API 사용법 요약&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#rb_node-구조체&quot; id=&quot;markdown-toc-rb_node-구조체&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;rb_node&lt;/code&gt; 구조체&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#rbtree가-적용된-노드-구조체&quot; id=&quot;markdown-toc-rbtree가-적용된-노드-구조체&quot;&gt;rbtree가 적용된 노드 구조체&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#root-노드-생성&quot; id=&quot;markdown-toc-root-노드-생성&quot;&gt;root 노드 생성&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#삽입과-삭제-연산에서-자주-사용하는-내부api-정리&quot; id=&quot;markdown-toc-삽입과-삭제-연산에서-자주-사용하는-내부api-정리&quot;&gt;삽입과 삭제 연산에서 자주 사용하는 내부API 정리&lt;/a&gt;    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;#주요-define&quot; id=&quot;markdown-toc-주요-define&quot;&gt;주요 define&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#rb_entry&quot; id=&quot;markdown-toc-rb_entry&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;rb_entry()&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#rb_red_parentred&quot; id=&quot;markdown-toc-rb_red_parentred&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;rb_red_parent(red)&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#rb_set_parent_colorrb-p-color&quot; id=&quot;markdown-toc-rb_set_parent_colorrb-p-color&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;rb_set_parent_color(rb, p, color)&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#rb_set_parentrb-p&quot; id=&quot;markdown-toc-rb_set_parentrb-p&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;rb_set_parent(rb, p)&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#__rb_rotate_set_parentsold-new--color&quot; id=&quot;markdown-toc-__rb_rotate_set_parentsold-new--color&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;__rb_rotate_set_parents(old, new, ..., color)&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#__rb_change_childold-new-parent-&quot; id=&quot;markdown-toc-__rb_change_childold-new-parent-&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;__rb_change_child(old, new, parent, ...)&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#삽입-연산&quot; id=&quot;markdown-toc-삽입-연산&quot;&gt;삽입 연산&lt;/a&gt;    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;#__rb_insert-분석&quot; id=&quot;markdown-toc-__rb_insert-분석&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;__rb_insert()&lt;/code&gt; 분석&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#삭제-연산&quot; id=&quot;markdown-toc-삭제-연산&quot;&gt;삭제 연산&lt;/a&gt;    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;#__rb_erase_augmented-분석&quot; id=&quot;markdown-toc-__rb_erase_augmented-분석&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;__rb_erase_augmented()&lt;/code&gt; 분석&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#____rb_erase_color-분석&quot; id=&quot;markdown-toc-____rb_erase_color-분석&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;____rb_erase_color()&lt;/code&gt; 분석&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#references&quot; id=&quot;markdown-toc-references&quot;&gt;References&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;hr /&gt;

&lt;h1 id=&quot;사용법-및-구조체-분석&quot;&gt;사용법 및 구조체 분석&lt;/h1&gt;

&lt;h2 id=&quot;linux-kernel-rb-tree-api-사용법-요약&quot;&gt;Linux Kernel RB Tree API 사용법 요약&lt;/h2&gt;
&lt;p&gt;자세한 내용은 &lt;a href=&quot;https://github.com/torvalds/linux/blob/master/lib/rbtree_test.c&quot;&gt;lib/rbtree_test.c 파일&lt;/a&gt; 참고&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;구조체에 struct rb_node * 멤버 추가&lt;/li&gt;
  &lt;li&gt;전역 rb_root 구조체 변수 생성&lt;/li&gt;
  &lt;li&gt;my_insert 함수 작성&lt;/li&gt;
  &lt;li&gt;my_erase 함수 작성&lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&quot;rb_node-구조체&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;rb_node&lt;/code&gt; 구조체&lt;/h2&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rb_node&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;  
	&lt;span class=&quot;kt&quot;&gt;unsigned&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;long&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;__rb_parent_color&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;cm&quot;&gt;/* rb parent and color */&lt;/span&gt;  
	&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rb_node&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rb_right&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  
	&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rb_node&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rb_left&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;__attribute__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;aligned&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;sizeof&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;long&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))));&lt;/span&gt;  
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;실제 rb tree규칙으로 트리의 균형이 맞는지 rebalence 되는 노드의 구조체.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;__attribute__((aligned(sizeof(long))));&lt;/code&gt; 의미는?&lt;br /&gt;
구조체의 시작 주소 정렬 &lt;br /&gt;
구조체의 시작주소가 4또는8의 배수(long크기)가 됨.&lt;br /&gt;
long형은 32bit 일때는 4byte, 64bit 일때는 8byte&lt;br /&gt;
참고: &lt;a href=&quot;http://gcc.gnu.org/onlinedocs/gcc-4.6.1/gcc/Type-Attributes.html#Type-Attributes&quot;&gt;http://gcc.gnu.org/onlinedocs/gcc-4.6.1/gcc/Type-Attributes.html#Type-Attributes&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;__rb_parent_color&lt;/code&gt;에는 부모노드의 주소값이 long으로 형변환되어 저장된다.&lt;br /&gt;
주소는 4 혹은 8의 배수로 증가하기 때문에 하위 2~3비트는 사용되지 않는다.&lt;br /&gt;
rb_node에서는 이 사용하지 않는 비트를 색 지정으로 사용하여 추가 변수 필요없이 메모리 공간을 절약한다.&lt;br /&gt;
그래서 rb_parent_color 멤버 변수를 통해 &lt;strong&gt;부모노드 주소__와 __본인노드 색&lt;/strong&gt; 두가지를 동시에 가질 수 있다.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;__rb_parent_color&lt;/code&gt; 변수의 더 정확한 의미는 rb parent and color이다.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;과거 Linux Kernel 2.4.31의 rb_node 구조체
과거에는 rb_parent와 rb_color가 독립적인 변수로 존재하는것을 알 수 있다. 메모리 공간이 더 낭비 되었을 것이다.&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;typedef&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rb_node_s&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rb_node_s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rb_parent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rb_color&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;#define RB_RED          0
#define RB_BLACK        1
&lt;/span&gt;        &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rb_node_s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rb_right&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rb_node_s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rb_left&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;rb_node_t&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;blockquote&gt;
  &lt;p&gt;소스코드 확인: &lt;a href=&quot;https://elixir.bootlin.com/linux/2.4.31/source/include/linux/rbtree.h#L100&quot;&gt;https://elixir.bootlin.com/linux/2.4.31/source/include/linux/rbtree.h#L100&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2 id=&quot;rbtree가-적용된-노드-구조체&quot;&gt;rbtree가 적용된 노드 구조체&lt;/h2&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;s&quot;&gt;&quot;lib/rbtree_test.c&quot;&lt;/span&gt;  
&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;test_node&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;  
	&lt;span class=&quot;n&quot;&gt;u32&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  
	&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rb_node&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rb&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  
	&lt;span class=&quot;n&quot;&gt;u32&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;val&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;u32&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;augmented&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;  
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;User가 실제 사용하는 구조체를(여기서는 struct test_node) rbtree로 구성하고 싶으면, 해당 구조체에 struct rb_node rb; 멤버를 추가하면 된다.&lt;br /&gt;
따라서 rbtree API에서는 rb멤버 포인터의 상위 구조체 포인터를(rb tree로 구성된 사용자 구조체가됨) 얻기위해 항상 rb_entry()를 사용하는데 이게 중요하다(container_of() 랑 동일한 역할을 하는 매크로 함수이다)&lt;/p&gt;

&lt;h2 id=&quot;root-노드-생성&quot;&gt;root 노드 생성&lt;/h2&gt;
&lt;p&gt;rbtree를 사용하려면 아래 처럼 전역으로 rb tree의 root 초기화 해야한다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;lib/rbtree_test.c&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;s&quot;&gt;&quot;lib/rbtree_test.c&quot;&lt;/span&gt;  
&lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rb_root&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;root&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;RB_ROOT&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;include/linux/rbtree.h&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;s&quot;&gt;&quot;include/linux/rbtree.h&quot;&lt;/span&gt;  

&lt;span class=&quot;cp&quot;&gt;#define RB_ROOT	(struct rb_root) { NULL, }
&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rb_root&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rb_node&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rb_node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;hr /&gt;

&lt;h1 id=&quot;삽입과-삭제-연산에서-자주-사용하는-내부api-정리&quot;&gt;삽입과 삭제 연산에서 자주 사용하는 내부API 정리&lt;/h1&gt;

&lt;h2 id=&quot;주요-define&quot;&gt;주요 define&lt;/h2&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cp&quot;&gt;#define	RB_RED		0
#define	RB_BLACK	1
&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;#define __rb_color(pc)     ((pc) &amp;amp; 1) 		&quot;마지막 색지정 비트만 추출&quot;
#define __rb_is_black(pc)  __rb_color(pc) 	&quot;마지막 비트가 1이면 black&quot;
#define __rb_is_red(pc)    (!__rb_color(pc)) 	&quot;마지막 비트가 0이면 red&quot;
&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;#define rb_color(rb)       __rb_color((rb)-&amp;gt;__rb_parent_color)
#define rb_is_red(rb)      __rb_is_red((rb)-&amp;gt;__rb_parent_color)
#define rb_is_black(rb)    __rb_is_black((rb)-&amp;gt;__rb_parent_color)
&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;#define rb_parent(r)   ((struct rb_node *)((r)-&amp;gt;__rb_parent_color &amp;amp; ~3))
#define __rb_parent(pc)    ((struct rb_node *)(pc &amp;amp; ~3))
&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;마지막 두비트를 0으로 만듦으로써 순수한 주소값으로 만듦&quot;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;rb_entry&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;rb_entry()&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;container_of와 같음. 구조체 멤버 포인터를 알때 그 구조체 포인터를 얻는 매크로
rb_node 포인터를 가지고있는 my_rb_struct같은 사용자 구조체의 포인터를 얻을 수 있음.&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cp&quot;&gt;#define	rb_entry(ptr, type, member) container_of(ptr, type, member)
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;rb_red_parentred&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;rb_red_parent(red)&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;전달받은 노드의 부모노드 주소(pointer) 리턴&lt;br /&gt;
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;__rb_parent_color&lt;/code&gt; 가 (struct rb_node *) 로 형변환 됨에 주의&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kr&quot;&gt;inline&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rb_node&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rb_red_parent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rb_node&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;red&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rb_node&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;red&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;__rb_parent_color&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;rb_set_parent_colorrb-p-color&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;rb_set_parent_color(rb, p, color)&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;첫번째 파라미터 rb의 부모주소변수에 p저장, 동시에 rb의 color도 지정&lt;br /&gt;
두가지 일을 한번에함&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kr&quot;&gt;inline&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rb_set_parent_color&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rb_node&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rb&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;  
				       &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rb_node&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;color&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rb&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;__rb_parent_color&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;unsigned&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;long&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;color&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;rb_set_parentrb-p&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;rb_set_parent(rb, p)&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;위 rb_set_parent_color 와 동일한데 따로 color지정 필요없이 색지정은 p의 색으로.&lt;br /&gt;
rb의 부모주소 변수에 p 저장, 동시에 색은 p의 색으로 지정&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kr&quot;&gt;inline&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rb_set_parent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rb_node&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rb&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rb_node&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rb&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;__rb_parent_color&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rb_color&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rb&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;unsigned&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;long&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;__rb_rotate_set_parentsold-new--color&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;__rb_rotate_set_parents(old, new, ..., color)&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;old 노드(O)를 기준으로 new 노드(N)를 올리는 회전연산이 일어날때 부모 변경시 사용.&lt;br /&gt;
old 자리가 new로 대체 될때 사용. 부모주소 변경.&lt;br /&gt;
new의 rb_parent_color에 old의 부모 주소를 저장,&lt;br /&gt;
동시에 old색 color로 변경&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;       P               P  
      /               /  
    (O)             (N)  
    / \             / \  
   l  (N)   --&amp;gt;   (O)  r  
      / \         / \  
     m   r       l   m  
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;__rb_rotate_set_parents&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rb_node&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;old&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rb_node&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; 		&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rb_root&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;root&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;color&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rb_node&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;parent&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rb_parent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;old&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;O의 부모노드 P 얻음&quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;__rb_parent_color&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;old&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;__rb_parent_color&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;N의 부모로 old의 부모노드 P 지정&quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rb_set_parent_color&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;old&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;color&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;O의 부모로 N 지정&quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;__rb_change_child&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;old&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;parent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;root&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;P의 자식에 new연결&quot;&lt;/span&gt;  
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;__rb_change_childold-new-parent-&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;__rb_change_child(old, new, parent, ...)&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;parent의 자식노드에 new연결 (기존에 old가 parent의 어느쪽 자식이었는지에 따라서)&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;__rb_change_child&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rb_node&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;old&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rb_node&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;  
		  &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rb_node&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;parent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rb_root&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;root&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;parent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;parent&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rb_left&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;old&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;parent&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rb_left&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;parent&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rb_right&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;root&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rb_node&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;hr /&gt;

&lt;h1 id=&quot;삽입-연산&quot;&gt;삽입 연산&lt;/h1&gt;

&lt;p&gt;먼저 어떤 기준으로 rbtree 를 정렬할지는 user가 직접 작성해야할 몫이다. 그래서 아래 insert()함수는 rbtree api를 사용하여 user가 직접 구현한 함수이다.&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;s&quot;&gt;&quot;lib/rbtree_test.c&quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;insert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;test_node&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rb_root&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;root&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot; *node : 새로 삽입할 노드, *root 현재 트리의 root 전역변수임 &quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rb_node&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;**&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;root&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rb_node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;parent&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;NULL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot; **new는 처음에 root-&amp;gt;rb_node의 포인터를 가지고 있음&quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;u32&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;key&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;parent&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;key&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rb_entry&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;parent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;test_node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rb&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot; rb_entry로 얻은 현재 부모노드의 key랑 삽입노드의 key비교 &quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;parent&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rb_left&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;new는 결국 새node를 삽입할 위치를 가리키는 포인터의 포인터가 됨&quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;parent&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rb_right&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rb_link_node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rb&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;parent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;new의 위치에 삽입할 node를 연결함&quot;&lt;/span&gt;   
&lt;span class=&quot;o&quot;&gt;|---&lt;/span&gt;   
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;include/linux/rbtree.h&quot;&lt;/span&gt;   
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kr&quot;&gt;inline&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rb_link_node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rb_node&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rb_node&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;parent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;  
				&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rb_node&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;**&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rb_link&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;__rb_parent_color&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;unsigned&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;long&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;parent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;parent node의 주소를 저장함, 이 변수는 나중에 color를 지정하는 역할도 함&quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rb_left&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rb_right&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;NULL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;새 node의 자식은 NULL&quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rb_link&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;삽입할 위치 rb_link에 새node 연결&quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|---&lt;/span&gt;   
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rb_insert_color&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rb&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;root&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;rb tree balancing 동작 수행&quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|---&lt;/span&gt;   
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;rb_insert_color&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rb_node&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rb_root&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;root&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;__rb_insert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;root&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dummy_rotate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;  
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;여기까지가 user가 구현해야할 함수 이고 내부에 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;__rb_insert()&lt;/code&gt;  함수가 실제 RB Tree의 Balancing이 일어나는 함수이다.&lt;/p&gt;

&lt;h2 id=&quot;__rb_insert-분석&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;__rb_insert()&lt;/code&gt; 분석&lt;/h2&gt;

&lt;p&gt;RB tree에서 삽입하는 동작은 아래와 같이 세가지 형태 변화가 있다. 이전 포스트의 case 3/4/5와 동일한 동작. 아래 그림에서 소문자 노드는 빨간색, 대문자 노드는 검정색을 표현했다.&lt;br /&gt;
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;FIXME&lt;/code&gt; 참고로 실제 소스코드에서 case가 1,2,3으로 되어있으나, 여기서 case가 3,4,5 로 표기한 이유는, 이해의 편의를 위해 &lt;a href=&quot;http://soopsaram.com/documentudy/2021/11/14/rbtree-in-linux-kernel-part1&quot;&gt;지난 포스트&lt;/a&gt;에서 정의한 case와 동일하게 맞추기 위함이다.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Case 3 - color flips  
  
      G            g  
     / \          / \  
    p   u  --&amp;gt;   P   U  
   /            /  
  n            n  
  
Case 4 - left rotate at parent  
  
     G             G  
    / \           / \  
   p   U  --&amp;gt;    n   U  
    \           /  
     n         p  
  
Case 5 - right rotate at gparent  
  
       G           P  
      / \         / \  
     p   U  --&amp;gt;  n   g  
    /                 \  
   n                   U  
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;이제 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;__rb_insert()&lt;/code&gt; 소스코드를 분석해보자.&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;__rb_insert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rb_node&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rb_root&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;root&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot; *node : 삽입된 노드, *root 루트노드&quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rb_node&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;parent&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rb_red_parent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;gparent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tmp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;삽입된 노드를 이용해 루트노드 얻어옴 : parent 주소 리턴하는 함수&quot;&lt;/span&gt;   
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;   
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;parent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;parent가 없는 root노드인경우&quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rb_set_parent_color&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;NULL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;RB_BLACK&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;node를(root) black으로 하고 종료&quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;break&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;   
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rb_is_black&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;parent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot; parent가 black인 경우 문제없으므로 종료&quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;break&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;gparent&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rb_red_parent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;parent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot; 할아버지 노드&quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tmp&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;gparent&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rb_right&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot; 삼촌노드&quot;&lt;/span&gt;  
  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;parent&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tmp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; 	&lt;span class=&quot;s&quot;&gt;&quot; parent == gparent-&amp;gt;rb_left 이고&quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tmp&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rb_is_red&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tmp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;tmp는 삼촌노드가 됨, 삼촌이 빨강이면&quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot; Case 3 - color flips &quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;   
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; 	     &lt;span class=&quot;n&quot;&gt;G&lt;/span&gt;            &lt;span class=&quot;n&quot;&gt;g&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; 	    &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;\&lt;/span&gt;          &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;\&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; 	   &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;   &lt;span class=&quot;n&quot;&gt;u&lt;/span&gt;  &lt;span class=&quot;o&quot;&gt;--&amp;gt;&lt;/span&gt;   &lt;span class=&quot;n&quot;&gt;P&lt;/span&gt;   &lt;span class=&quot;n&quot;&gt;U&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; 	  &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;            &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; 	 &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;            &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;   
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rb_set_parent_color&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tmp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;gparent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;RB_BLACK&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;삼촌 블랙&quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rb_set_parent_color&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;parent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;gparent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;RB_BLACK&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;부모 블랙으로&quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;node&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;gparent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;현재노드 gparent로 변경&quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;parent&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rb_parent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rb_set_parent_color&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;parent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;RB_RED&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;할아버지노드 빨간색&quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;continue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;현재노드는 gparent로 재귀적으로 다시 수행 while 다시반복&quot;&lt;/span&gt;  
  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tmp&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;parent&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rb_right&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;   
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;node&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tmp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;현재 노드가 부모의 오른쪽 자식 이면&quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot; Case 4 - left rotate at parent : left 회전 부모색 빨강&quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;   
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; 	    &lt;span class=&quot;n&quot;&gt;G&lt;/span&gt;             &lt;span class=&quot;n&quot;&gt;G&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; 	   &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;\&lt;/span&gt;           &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;\&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; 	  &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;   &lt;span class=&quot;n&quot;&gt;U&lt;/span&gt;  &lt;span class=&quot;o&quot;&gt;--&amp;gt;&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;   &lt;span class=&quot;n&quot;&gt;U&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; 	   &lt;span class=&quot;err&quot;&gt;\&lt;/span&gt;           &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; 	    &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;         &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;   
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;parent&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rb_right&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tmp&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rb_left&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rb_left&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;parent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;parent는 현재노드의 좌측 자식으로 &quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tmp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rb_set_parent_color&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tmp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;parent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;RB_BLACK&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rb_set_parent_color&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;parent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;RB_RED&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;parent의 부모노드주소에 node가 저장됨&quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;augment_rotate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;parent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;현재 이 함수는 dummy_rotate()이므로 무시&quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;parent&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;현재노드가 부모노드가 됨, 어차피 gparent-&amp;gt;left는 parent였으니 이부분은 수정 필요 없음&quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;그렇다면 현재노드위치는 어디? -&amp;gt; 이 이후부터 p의 left(현재노드)는  &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;고려할 필요가 없음. 그래서 따로 현재노드를 지정해줄 필요없이 앞으로는 g와 p의 관계만만 고려하면 됨 &quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tmp&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rb_right&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot; Case 5 - right rotate at gparent &quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot; case 5 동작 으로 마무리&quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;	      &lt;span class=&quot;n&quot;&gt;G&lt;/span&gt;           &lt;span class=&quot;n&quot;&gt;P&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;	     &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;\&lt;/span&gt;         &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;\&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;	    &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;   &lt;span class=&quot;n&quot;&gt;U&lt;/span&gt;  &lt;span class=&quot;o&quot;&gt;--&amp;gt;&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;   &lt;span class=&quot;n&quot;&gt;g&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;	   &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;                 &lt;span class=&quot;err&quot;&gt;\&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;	  &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;                   &lt;span class=&quot;n&quot;&gt;U&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;gparent&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rb_left&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tmp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  &lt;span class=&quot;cm&quot;&gt;/* == parent-&amp;gt;rb_right */&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;parent&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rb_right&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;gparent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tmp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rb_set_parent_color&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tmp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;gparent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;RB_BLACK&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;__rb_rotate_set_parents&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;gparent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;parent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;root&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;RB_RED&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;parent색을 gparent의 부모색으로 변경(==부모주소변경), gprent는 빨강으로 변경&quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|---&lt;/span&gt;   
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;__rb_rotate_set_parents&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rb_node&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;old&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rb_node&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; 		&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rb_root&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;root&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;color&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;old : gparent, new : parent&quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rb_node&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;parent&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rb_parent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;old&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;__rb_parent_color&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;old&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;__rb_parent_color&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;parent의 부모주소 값을 gparent의 부모주소로 변경&quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rb_set_parent_color&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;old&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;color&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;gparent의 부모주소 값을 parent 로&quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;__rb_change_child&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;old&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;parent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;root&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot; (gparent의 부모밑에 parent연결)&quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|---&lt;/span&gt;   
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;parent 자식으로 new를 연결 하는 함수&quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;__rb_change_child&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rb_node&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;old&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rb_node&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; 		  &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rb_node&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;parent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rb_root&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;root&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;parent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;parent&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rb_left&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;old&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;parent&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rb_left&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;parent&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rb_right&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;root&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rb_node&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|---&lt;/span&gt;   
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|---&lt;/span&gt;   
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;augment_rotate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;gparent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;parent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;dummy&quot;&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;break&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  

&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot; 여기부터는 parent == gparent-&amp;gt;rb_right 인 반대의 경우이고&quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;아래 코드는 case 3,4,5 로 위에서 분석한 내용과 방향만 반대일뿐 동일함&quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tmp&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;gparent&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rb_left&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tmp&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rb_is_red&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tmp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot; Case 3 - color flips &quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;...&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tmp&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;parent&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rb_left&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;node&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tmp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot; Case 4 - right rotate at parent &quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;...&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot; Case 5 - left rotate at gparent &quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;...&lt;/span&gt;  
  
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;hr /&gt;

&lt;h1 id=&quot;삭제-연산&quot;&gt;삭제 연산&lt;/h1&gt;

&lt;p&gt;삭제 연산도 마찬가지로 유져가 직접 rb_erase() api를 이용해 함수를 작성한다. 여기까지가 user가 구현해야할 함수 이다.&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;s&quot;&gt;&quot;lib/rbtree_test.c&quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kr&quot;&gt;inline&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;erase&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;test_node&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rb_root&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;root&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot; *node : tree에서 삭제할 노드&quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rb_erase&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rb&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;root&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;  
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;이제 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;rb_erase()&lt;/code&gt; 소스코드를 분석해보자. 대략적인 개요는 다음과 같다.&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;s&quot;&gt;&quot;lib/rbtree.c&quot;&lt;/span&gt;  
&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rb_erase&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rb_node&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rb_root&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;root&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rb_node&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rebalance&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rebalance&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;__rb_erase_augmented&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;root&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dummy_callbacks&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;1. 노드 삭제시키고 tree가 rebalence대상이 되는지 판단&quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rebalance&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;____rb_erase_color&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rebalance&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;root&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dummy_rotate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;2. 삭제 연산의 rebalence 동작 수행&quot;&lt;/span&gt;  
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;__rb_erase_augmented-분석&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;__rb_erase_augmented()&lt;/code&gt; 분석&lt;/h2&gt;

&lt;p&gt;노드를 삭제하고 그자리에 successor(후계노드)를 찾아서 대체 시키는 함수이다. 그뒤 트리의 균형이 맞는지 rebalence가 필요한지 판단해서 리턴값으로 알려준다. 참고로 Linux Kernel에서는 leftmost successor(오른쪽 sub트리중 가장 작은 노드)를 후계노드로 선정한다. 그래서 코드는 오른쪽 한방향일 경우만 고려해서 작성되어 있다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;__rb_erase_augmented()&lt;/code&gt; 개요&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;__rb_erase_augmented&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rb_node&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rb_root&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;root&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;  
		     &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rb_augment_callbacks&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;augment&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rb_node&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;child&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rb_right&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tmp&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rb_left&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rb_node&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;parent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rebalance&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;unsigned&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;long&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;case 1&quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tmp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;오른쪽 자식만 있거나 아얘없는 경우&quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;     &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;          &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;       &lt;span class=&quot;err&quot;&gt;\&lt;/span&gt;     &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;     
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;       &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;오른쪽 자식을 대체시키고 끝&quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;child&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;삭제노드에 오른쪽 자식만 있는경우&quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;대체된 child의 색을 삭제되는 노드색으로 (동시에 부모노드의 주소도 됨&quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;삭제될 노드에 자식이 없는 경우&quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;삭제될 노드 색이 black이면 5)black height규칙에 위반되기 때문에 rebalence 대상임&quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;child&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;왼쪽 자식만 있는 경우&quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;위와 똑같이 삭제노드를 왼쪽자식으로 대체시키고 끝&quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;양쪽 자식이 존재하는 경우&quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tmp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;case 2 :삭제노드의 오른자식(successor)에 왼쪽자식이 없는경우&quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;이경우는 삭제노드의 오른쪽자식이 바로 후계노드가 되기 때문에 간단&quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;     &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;          &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;     &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;\&lt;/span&gt;          &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; \
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;   &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;  &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;         \
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;         &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;case 3 : 삭제노드의 오른자식에 왼쪽 sub 트리가 존재하는 경우&quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;          &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;    &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;\&lt;/span&gt;          &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; \
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;  &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;      &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;            &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;          &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;    &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;            &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;          &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;    \
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;   
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;삭제노드의 왼쪽 자식은 successor의 왼쪽자식이됨&quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;삭제노드의 부모노드의 자식으로 successor연결&quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;child2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot; successor의 우측 자식(child2)이 있었다면 &quot;&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;child2는 블랙으로&quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;s, c둘중 적어도 하나는 무조건 블랙이었기 때문&quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;삭제 노드의 부모 노드 저장, 동시에 색은 삭제노드와 동일하게&quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;successor의 기존 부모의 색이 블랙 이었다면? rebalence대상임&quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;   
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rebalance&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;__rb_erase_augmented()&lt;/code&gt; 분석&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;s&quot;&gt;&quot;include/linux/rbtree_augmented.h&quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;__rb_erase_augmented&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rb_node&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rb_root&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;root&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;  
		     &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rb_augment_callbacks&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;augment&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rb_node&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;child&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rb_right&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tmp&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rb_left&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rb_node&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;parent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rebalance&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;unsigned&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;long&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;case 1&quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tmp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;오른쪽 자식만 있거나 아얘없는 경우&quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;오른쪽 자식을 대체시키고 끝&quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pc&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;__rb_parent_color&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;삭제할 노드의 색&quot;&lt;/span&gt; 
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;parent&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;__rb_parent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;삭제할 노드의 부모노드&quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;__rb_change_child&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;child&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;parent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;root&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;parent의 자식에 child연결&quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;   
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;child&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;삭제노드에 오른쪽 자식만 있는경우&quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;child&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;__rb_parent_color&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;대체된 child의 색을 삭제되는 노드색으로 (동시에 부모노드의 주소도 됨&quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rebalance&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;NULL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;rebalance필요없음&quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;삭제될 노드에 자식이 없는 경우&quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rebalance&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;__rb_is_black&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;parent&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;NULL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;삭제될 노드 색이 black이면 5)black height규칙에 위반되기 때문에 rebalence 대상임&quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;child&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;왼쪽 자식만 있는 경우&quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;위와 똑같이 삭제노드를 왼쪽자식으로 대체시키고 끝&quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;양쪽 자식이 존재하는 경우&quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;kernel rbtree 에서는 leftmost successor(오른쪽 sub트리중 가장 작은 노드)를 후계노드로 대체함&quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rb_node&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;successor&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;child&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;child2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tmp&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;child&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rb_left&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tmp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;case 2 :삭제노드의 오른자식(successor)에 왼쪽자식이 없는경우&quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;이경우는 삭제노드의 오른쪽자식이 바로 후계노드가 되기 때문에 간단&quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;     &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;          &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;     &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;\&lt;/span&gt;          &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; \
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;   &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;  &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;         \
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;         &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;parent&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;successor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;parent는 successor를 의미&quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;child2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;successor&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rb_right&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;case 3 : 삭제노드의 오른자식에 왼쪽 sub 트리가 존재하는 경우&quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;          &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;    &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;\&lt;/span&gt;          &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; \
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;  &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;      &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;            &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;          &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;    &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;            &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;          &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;    \
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;   
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;parent&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;successor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;y&quot;&lt;/span&gt; 
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;successor&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tmp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tmp&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tmp&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rb_left&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tmp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;오른자식 y 왼쪽 sub트리에서 가장 왼쪽(작은) 노드(tmp) 찾기 &quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;parent&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rb_left&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;child2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;successor&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rb_right&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;successor&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rb_right&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;child&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rb_set_parent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;child&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;successor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;   
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;삭제노드자리에 successor위치 시킴, 그에따른 자식노드 처리&quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;   
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;case 2,3 모두해당&quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;successor&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rb_left&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tmp&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rb_left&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rb_set_parent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tmp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;successor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;삭제노드의 왼쪽 자식은 successor의 왼쪽자식이됨&quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pc&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;__rb_parent_color&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tmp&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;__rb_parent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;__rb_change_child&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;successor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tmp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;root&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;삭제노드의 부모노드의 자식으로 successor연결&quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;child2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot; successor의 우측 자식(child2)이 있었다면 &quot;&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;successor&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;__rb_parent_color&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rb_set_parent_color&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;child2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;parent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;RB_BLACK&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rebalance&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;NULL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;child2는 블랙으로&quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot; s, c둘중 적어도 하나는 무조건 블랙이었기 때문&quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;unsigned&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;long&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pc2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;successor&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;__rb_parent_color&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;successor&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;__rb_parent_color&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;삭제 노드의 부모 노드 저장, 동시에 색은 삭제노드와 동일하게&quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rebalance&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;__rb_is_black&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pc2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;parent&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;NULL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;successor의 기존 부모의 색이 블랙 이었다면? rebalence대상임&quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;   
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rebalance&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;만약 rebalance가 NULL이 아니라면 return되는 rebalance는 &quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;case 1 : n(삭제할노드)의 부모 &quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;case 2 : successor임 (successor자체가 successor원래 부모위치로 올라가기때문)&quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;case 3 : 대체되기 전 successor의 원래 부모 &quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;   
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;결국 삭제되는 위치(후계노드-successor이든, 실제 자식없는 삭제노드이든)의 부모노드임&quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;successor가 없다면 (case1) -&amp;gt; 삭제노드의 부모노드&quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;successor가 있다면 (case 2,3) -&amp;gt; 대체되기전 successor의 부모위치와 같음&quot;&lt;/span&gt;  
  
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;____rb_erase_color-분석&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;____rb_erase_color()&lt;/code&gt; 분석&lt;/h2&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;__rb_erase_augmented()&lt;/code&gt; 이후 &lt;br /&gt;
이미 삭제할 노드는 트리에서 제거 되었고 후계자노드(successor)로 대체된 상태부터 시작된다. 매개변수로 넘어온 parent는 삭제된(대체노드) 노드의 원래 부모노드임을 주의.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;____rb_erase_color()&lt;/code&gt; 개요&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;____rb_erase_color&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rb_node&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;parent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rb_root&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;root&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;  
	&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;augment_rotate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rb_node&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;old&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rb_node&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rb_node&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;node&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;NULL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sibling&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tmp1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tmp2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sibling&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;parent&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rb_right&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;node&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sibling&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; 	&lt;span class=&quot;cm&quot;&gt;/* node == parent-&amp;gt;rb_left */&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rb_is_red&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sibling&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;   
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot; delete_case 2 : 형제가 레드인 경우&quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tmp1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rb_is_black&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tmp1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;   
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tmp2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rb_is_black&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tmp2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;   
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rb_is_red&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;parent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;delete_case 4 : 형제자식 모두 블랙, 부모 레드&quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;delete_case 3: 형제자식 모두 블랙, 부모 블랙&quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;delete_case 5 : 무조건 형제가 검은색인경우가 됨&quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;...&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;delete_case6&quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;	&lt;span class=&quot;cm&quot;&gt;/* node == parent-&amp;gt;rb_right */&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;위와 동일한 케이스 방향만 반대&quot;&lt;/span&gt;  
  
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;참고로 위의 case번호는 rbtree_general.md 파일에서 규정한 번호임, 실제코드랑은 다름&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;____rb_erase_color()&lt;/code&gt; 분석&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;____rb_erase_color&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rb_node&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;parent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rb_root&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;root&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;  
	&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;augment_rotate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rb_node&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;old&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rb_node&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rb_node&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;node&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;NULL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sibling&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tmp1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tmp2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sibling&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;parent&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rb_right&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;node&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sibling&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; 	&lt;span class=&quot;s&quot;&gt;&quot; node == parent-&amp;gt;rb_left &quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rb_is_red&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sibling&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;   
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot; delete_case 2 : 형제가 레드인 경우&quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot; Case 1 - Left rotate at parent&quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; 	     &lt;span class=&quot;n&quot;&gt;P&lt;/span&gt;               &lt;span class=&quot;n&quot;&gt;S&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; 	    &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;\&lt;/span&gt;             &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;\&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; 	   &lt;span class=&quot;n&quot;&gt;N&lt;/span&gt;   &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;    &lt;span class=&quot;o&quot;&gt;--&amp;gt;&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;   &lt;span class=&quot;n&quot;&gt;Sr&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; 	      &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;\&lt;/span&gt;         &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;\&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; 	     &lt;span class=&quot;n&quot;&gt;Sl&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;Sr&lt;/span&gt;      &lt;span class=&quot;n&quot;&gt;N&lt;/span&gt;   &lt;span class=&quot;n&quot;&gt;Sl&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;parent&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rb_right&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tmp1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sibling&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rb_left&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sibling&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rb_left&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;parent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rb_set_parent_color&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tmp1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;parent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;RB_BLACK&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;형제를 블랙으로&quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;__rb_rotate_set_parents&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;parent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sibling&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;root&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;RB_RED&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;회전연산&quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sibling&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tmp1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;형제를 Sl 로 변경, Sl은 무조건 블랙 이 이후 형제는 무조건 블랙&quot;&lt;/span&gt;  
  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tmp1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sibling&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rb_right&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tmp1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rb_is_black&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tmpl1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;형제 우측자식 블랙 이고&quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tmp2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sibling&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rb_left&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tmp2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rb_is_black&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tmp2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;  &lt;span class=&quot;s&quot;&gt;&quot;형제 좌측자식 블랙&quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot; Case 2 - Sibling color flip  &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;| | | | |   (p could be either color here)&quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; 	     &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;           &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; 	     &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;\&lt;/span&gt;           &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;\&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; 	    &lt;span class=&quot;n&quot;&gt;N&lt;/span&gt;   &lt;span class=&quot;n&quot;&gt;S&lt;/span&gt;    &lt;span class=&quot;o&quot;&gt;--&amp;gt;&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;N&lt;/span&gt;   &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; 	       &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;\&lt;/span&gt;           &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;\&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; 	      &lt;span class=&quot;n&quot;&gt;Sl&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;Sr&lt;/span&gt;        &lt;span class=&quot;n&quot;&gt;Sl&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;Sr&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rb_set_parent_color&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sibling&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;parent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;RB_RED&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;형제를 레드로&quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rb_is_red&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;parent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;delete_case 4 : 형제자식 모두 블랙, 부모 레드 경우&quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rb_set_black&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;parent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;부모를 블랙으로&quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;delete_case 3: 형제자식 모두 블랙, 부모 블랙 경우&quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;node&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;parent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;parent&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rb_parent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;parent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;continue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;부모노드 기준으로 다시 처음부터&quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;break&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;종료&quot;&lt;/span&gt;  
  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot; delete_case 5 : 무조건 형제가 검은색인경우가 됨&quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot; Case 3 - Right rotate at sibling  &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;| | | |   (p could be either color here)&quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; 	  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; 	   &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;           &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; 	   &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;\&lt;/span&gt;           &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;\&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; 	  &lt;span class=&quot;n&quot;&gt;N&lt;/span&gt;   &lt;span class=&quot;n&quot;&gt;S&lt;/span&gt;    &lt;span class=&quot;o&quot;&gt;--&amp;gt;&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;N&lt;/span&gt;   &lt;span class=&quot;n&quot;&gt;Sl&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; 	     &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;\&lt;/span&gt;             &lt;span class=&quot;err&quot;&gt;\&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; 	    &lt;span class=&quot;n&quot;&gt;sl&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;Sr&lt;/span&gt;            &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; 	      &lt;span class=&quot;err&quot;&gt;\&lt;/span&gt;              &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;\&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; 	      &lt;span class=&quot;n&quot;&gt;tmp1&lt;/span&gt;        &lt;span class=&quot;n&quot;&gt;tmp1&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;Sr&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sibling&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rb_left&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tmp1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tmp2&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rb_right&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;tmp2: sl&quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tmp2&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rb_right&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sibling&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;parent&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rb_right&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tmp2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;s 기준 right 회전연산&quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tmp1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rb_set_parent_color&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tmp1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sibling&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;RB_BLACK&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;tmp1의 부모를 s 로&quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tmp1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sibling&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sibling&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tmp2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  
  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;delete_case6&quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot; Case 4 - Left rotate at parent + color flips  &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;| | |   (p and sl could be either color here. After rotation, p becomes black, s acquires  &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;| | |   p`s color, and sl keeps its color) &quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;   
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; 	       &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;             &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; 	       &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;\&lt;/span&gt;             &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;\&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; 	      &lt;span class=&quot;n&quot;&gt;N&lt;/span&gt;   &lt;span class=&quot;n&quot;&gt;S&lt;/span&gt;     &lt;span class=&quot;o&quot;&gt;--&amp;gt;&lt;/span&gt;   &lt;span class=&quot;n&quot;&gt;P&lt;/span&gt;   &lt;span class=&quot;n&quot;&gt;Sr&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; 	         &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;\&lt;/span&gt;         &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;\&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; 	       &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sr&lt;/span&gt;      &lt;span class=&quot;n&quot;&gt;N&lt;/span&gt;  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;   
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;parent&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rb_right&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tmp2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sibling&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rb_left&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;tmp2: sl&quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sibling&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rb_left&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;parent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rb_set_parent_color&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tmp1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sibling&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;RB_BLACK&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;tmp1 : sr&quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;p 기준 left회전&quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tmp2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rb_set_parent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tmp2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;parent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;sl은 p색으로&quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;__rb_rotate_set_parents&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;parent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sibling&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;root&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;RB_BLACK&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;p 기준 left회전, p색 블랙으로&quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;break&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;종료&quot;&lt;/span&gt;  
  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;	&lt;span class=&quot;s&quot;&gt;&quot; node == parent-&amp;gt;rb_right &quot;&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;여기부터는 위와 동일한 케이스 방향만 반대&quot;&lt;/span&gt;  
  
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;hr /&gt;

&lt;h1 id=&quot;references&quot;&gt;References&lt;/h1&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.cs.usfca.edu/~galles/visualization/RedBlack.html&quot;&gt;https://www.cs.usfca.edu/~galles/visualization/RedBlack.html&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://lwn.net/Articles/184495/&quot;&gt;http://lwn.net/Articles/184495/&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://kldp.org/node/117200&quot;&gt;https://kldp.org/node/117200&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;a href=&quot;http://gcc.gnu.org/onlinedocs/gcc-4.6.1/gcc/Type-Attributes.html#Type-Attributes&quot;&gt;http://gcc.gnu.org/onlinedocs/gcc-4.6.1/gcc/Type-Attributes.html#Type-Attributes&lt;/a&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;Source Code (Linux Kernel v4.6)  &lt;br /&gt;
&lt;a href=&quot;https://github.com/torvalds/linux/blob/v4.6/lib/rbtree.c&quot;&gt;lib/rbtree.c&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;https://github.com/torvalds/linux/blob/v4.6/lib/rbtree_test.c&quot;&gt;lib/rbtree_test.c&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;https://github.com/torvalds/linux/blob/v4.6/include/linux/rbtree.h&quot;&gt;include/linux/rbtree.h&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;https://github.com/torvalds/linux/blob/v4.6/include/linux/rbtree_augmented.h&quot;&gt;include/linux/rbtree_augmented.h&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
        <pubDate>Mon, 15 Nov 2021 13:00:00 +0000</pubDate>
        <link>https://soopsaram.com/documentudy/2021/11/15/rbtree-in-linux-kernel-part2/</link>
        <guid isPermaLink="true">https://soopsaram.com/documentudy/2021/11/15/rbtree-in-linux-kernel-part2/</guid>
        
        <category>Linux</category>
        
        <category>LinuxKernel</category>
        
        <category>Algorithm</category>
        
        
        <category>LinuxKernel</category>
        
      </item>
    
      <item>
        <title>Red-Black Tree in Linux Kernel - Part 1</title>
        <description>&lt;blockquote&gt;
  &lt;p&gt;작성: 숲사람&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul id=&quot;markdown-toc&quot;&gt;
  &lt;li&gt;&lt;a href=&quot;#red-black-tree-란&quot; id=&quot;markdown-toc-red-black-tree-란&quot;&gt;Red-Black Tree 란?&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#rb-tree의-5가지-규칙&quot; id=&quot;markdown-toc-rb-tree의-5가지-규칙&quot;&gt;RB tree의 5가지 규칙&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#삽입-연산&quot; id=&quot;markdown-toc-삽입-연산&quot;&gt;삽입 연산&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#삭제-연산&quot; id=&quot;markdown-toc-삭제-연산&quot;&gt;삭제 연산&lt;/a&gt;    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;#삭제되는-노드-처리&quot; id=&quot;markdown-toc-삭제되는-노드-처리&quot;&gt;삭제되는 노드 처리&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#후계자-노드-처리&quot; id=&quot;markdown-toc-후계자-노드-처리&quot;&gt;후계자 노드 처리&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#references&quot; id=&quot;markdown-toc-references&quot;&gt;References&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;red-black-tree-란&quot;&gt;Red-Black Tree 란?&lt;/h1&gt;

&lt;p&gt;RB-Tree 는 Radix-Tree와 더불어 Linux Kernel에서 가장 많이 사용하는 Tree 자료구조이다. I/O scheduler(CFQ, deadline 등), ext filesystem, Virtual memory areas 등 Kernel의 여러 Subsystem에서 사용된다. 기존 Tree자료구조의 단점은 최악의 경우 노드가 Linked-List의 형태로 저장되어 탐색 시간복잡도가 O(N) 이 된다는 점이다. 하지만 RB Tree는 노드의 삽입과 삭제가 이루어 질때, Tree가 자동으로 회전하며 O(logN)의 시간복잡도를 보장한다.&lt;/p&gt;

&lt;p&gt;이 글에서는 일반적인 RB Tree에서 가장 복잡한 연산인 삽입과 삭제가 어떤 방식으로 동작 하는지 알아본다. 경우의 수만 잘 따지고 그때그때 어떻게 해주는지 규칙만 잘 파악하면 쉽게 따라갈 수 있다. 이를 기반으로 해서 다음 글에서 Linux Kernel 에서 RB Tree가 어떻게 구현되었는지 살펴 볼것이다.&lt;/p&gt;

&lt;h1 id=&quot;rb-tree의-5가지-규칙&quot;&gt;RB tree의 5가지 규칙&lt;/h1&gt;
&lt;p&gt;노드의 삽입과 삭제연산을 할때마다, 아래의 규칙을 만족시키도록 트리의 노드위치를 변경하거나 유지하는것이 RB Tree이다.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;노드는 빨간색 검은색 둘 중 하나다(A node is either red or black)&lt;/li&gt;
  &lt;li&gt;Root 노드는 검은색이다. (The root is black)&lt;/li&gt;
  &lt;li&gt;모든 말단 노드는 검은색이다 (All leaves (NULL) are black)&lt;/li&gt;
  &lt;li&gt;빨간색 노드는 중첩될 수 없다. (Both children of every red node are black)&lt;/li&gt;
  &lt;li&gt;각 말단노드의 Black Height는 모두 동일하다 (Every simple path from root to leaves contains the same number of black nodes)
    &lt;blockquote&gt;
      &lt;p&gt;Black Height: 말단노드에서부터 Root노드 사이의 검은색 노드 갯수&lt;/p&gt;
    &lt;/blockquote&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;h1 id=&quot;삽입-연산&quot;&gt;삽입 연산&lt;/h1&gt;

&lt;p&gt;새노드가 트리에 삽입될때, 부모노드는 검은색인경우 빨간색인 경우 두가지가 있다. 아래 설명된 각각의 경우의 수에따라 5가지 종류의 삽입연산이 필요하다.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;새노드 삽입 insert_case1() 수행  
  
-검은색에 삽입 -&amp;gt; 문제가 되지 않음   
-빨간색에 삽입   
	(1) 삼촌도 빨간색인 경우 insert_case3(n)  
		부모,삼촌 검은 색, 할아버지 빨간색으로   
	(2) 삼촌이 검은색인 경우 (여기서 삼촌은 할아버지의 오른쪽 자식으로 가정)  
    		1) 삽입노드가 부모노드의 오른쪽 자식인 경우 insert_case4(n)  
			삽입노드와 부모노드를 회전시켜 부모노드를 삽입노드의   
			왼쪽 자식으로 만든다.  --&amp;gt;  2)과 구조가 됨  
    		2) 삽입노드가 부모노드의 왼쪽 자식인 경우 insert_case5(n)   
			부모노드를 검은색 할아버지 노드를 빨간색으로 바꾸고  
			오른쪽회전 (부모노드가 루트위치로)  
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;일부 삽입연산은 트리의 회전연산이 필요하다(rotation_left() 및 rotation_right()). 회전연산은 매개변수로 전달된 노드의 자식을 치켜세워주는 연산이라고 생각하면 이해하기 쉽다 : 자식이 위로 부모는 아래로. 아래 그림은 부모노드(O)와 자식노드(N) 기준으로 rotation_left 회전이 일어날때 트리의 구조 변화이다.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;       P               P  
      /               /  
    (O)             (N)  
    / \             / \  
   l  (N)   --&amp;gt;   (O)  r  
      / \         / \  
     m   r       l   m  
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;각각의 삽입 연산 동작 방식은 아래와 같다.&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;insert_case1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;  
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;  
	&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;부모노드가&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;없는경우&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;을&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;블랙&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;루트노드가됨&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;  
	&lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;부모노드&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;있으면&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;  
		&lt;span class=&quot;n&quot;&gt;insert_case2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;수행&lt;/span&gt;  
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;  
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;insert_case2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;  
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;  
	&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;부모노드가&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;블랙인경우&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; 
		&lt;span class=&quot;err&quot;&gt;그냥&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;삽입해도&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;문제&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;안되므로&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt;  
	&lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;부모노드&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;빨강&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;  
		&lt;span class=&quot;n&quot;&gt;insert_case3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;수행&lt;/span&gt;		  
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;  
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;insert_case3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;  
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;  
   	&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;삼촌노드&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;빨간색이면&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;삼촌노드&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;있으면&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;  
		&lt;span class=&quot;err&quot;&gt;부모&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;삼촌노드&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;검은색으로&lt;/span&gt;  
		&lt;span class=&quot;err&quot;&gt;할아버지노드&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;빨간색으로&lt;/span&gt;  
		&lt;span class=&quot;n&quot;&gt;insert_case1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;할아버지노드&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;   &lt;span class=&quot;s&quot;&gt;&quot; 재귀적으로 수행 !!&quot;&lt;/span&gt;  
	&lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;  &lt;span class=&quot;s&quot;&gt;&quot;그외 나머지 경우 (삼촌 노드가 검정색 || 삼촌노드 없으면)&quot;&lt;/span&gt;  
		&lt;span class=&quot;n&quot;&gt;insert_case4&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;  
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;  
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;insert_case4()는 case5 함수를 수행할 구조로 만드는 작업이다.&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;insert_case4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; 
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;	  
	&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;부모노드가&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;할아버지&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;노드의&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;왼쪽자식&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;새노드가&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;부모노드의&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;오른쪽자식&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;  
		&lt;span class=&quot;n&quot;&gt;rotation_left&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;부모노드&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;	  
		&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;왼쪽노드&lt;/span&gt;  
	&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;부모가&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;할아버지의&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;오른쪽&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;자식&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;새노드가&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;부모&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;노드의&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;왼쪽&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;자식&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;					  
		&lt;span class=&quot;n&quot;&gt;rotation_right&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;부모노드&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;  
		&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;오른쪽노드&lt;/span&gt;  
  
	&lt;span class=&quot;err&quot;&gt;둘다&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;아니거나&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;위내용을&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;수행했으면&lt;/span&gt;  
	&lt;span class=&quot;n&quot;&gt;insert_case5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;수행&lt;/span&gt;  
  
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;  
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;insert_case5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; 
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;  
	&lt;span class=&quot;err&quot;&gt;부모는&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;검은색으로&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;할아버지는&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;빨간색으로&lt;/span&gt;   
	&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;부모가&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;할아버지의&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;왼쪽자식&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;이&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;부모의&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;왼쪽자식&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;  
		&lt;span class=&quot;n&quot;&gt;rotation_right&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;할아버지&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;노드&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;  
	&lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;부모가&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;할아버지&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;오른쪽&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;자식&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;이&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;부모의&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;오른쪽&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;자식&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;  
		&lt;span class=&quot;n&quot;&gt;rotation_left&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;할아버지&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;노드&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;  
  
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;  
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;삭제-연산&quot;&gt;삭제 연산&lt;/h1&gt;

&lt;p&gt;삭제 연산은 삽입 연산보다는 다소 복잡한데, 삭제되는 노드를 처리해야하고, 삭제된 자리를 새로운 후계자 노드로 변경해야하기 때문이다.&lt;/p&gt;

&lt;h2 id=&quot;삭제되는-노드-처리&quot;&gt;삭제되는 노드 처리&lt;/h2&gt;

&lt;p&gt;삭제되는 노드에 대체되는 노드를 복사한다. 색은 삭제되는 노드색을 유지하고, 노드만 바로 복사된다. 대체될 수 있는 후계자는 이진트리 삭제와 마찬가지로 left 하위트리 에서 가장 큰 노드인데(삭제 노드의 왼쪽sub트리는  Inorder Predecessor 오른쪽은 Inorder successor라고 표현함), 보통 맨 아래 노드이고 (leaf node가 1개와 Null leaf1개) 이거나 (Null leaf만 두개)인 경우밖에 없다. 중요한건 이 대체되는 후계 노드가 그 자리에서 삭제 된다는것인데, 이때 RB트리의 규칙이 무너지는 경우가 있기 때문에, 대체되는 노드를 기준으로 아래 2번의 알고리즘을 따르게 된다. 가령 아래 트리에서 노드 40이 삭제된다면 그자리를 대체할 수 있는 후계노드는 노드 30이 될것이다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/documentudy/assets/img/rbtree_inorder_predecessor.png&quot; alt=&quot;rbtree inorder predecessor&quot; /&gt;&lt;/p&gt;

&lt;p&gt;아래 설명에서 n은 대체될 노드의 자식이다. 일반 노드가 될 수 도 있고 Null leaf(검은색)가 될수도 있다. 즉, 트리에서 삭제되는 노드 기준으로 트리 balancing동작을 시키는 것이 아니라 후계자 노드 기준으로 balancing동작 수행한다.&lt;/p&gt;

&lt;h2 id=&quot;후계자-노드-처리&quot;&gt;후계자 노드 처리&lt;/h2&gt;

&lt;p&gt;후계 노드가 삭제되는 것으로 판단하면 된다. 후계 노드가 빨간색일 경우와 검은색일 경우에 따른 케이스로 구분하면 된다. 아래 형제,부모,조카는 대체될 후계 노드 기준으로 위치한 노드이다. 실제로는 대체될 후계노드의 자식노드기준으로 볼 수도 있는데. 그이유는 대체될 노드는 삭제노드 위치로 변경되고 대체될 노드의 자리에는 어차피 그 노드의 자식노드가 위치할 것이기 때문이다.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;- 후계노드가 빨간색 -&amp;gt; 문제 없음    
- 후계노드가 검은색     
	- 형제가 빨간색인 경우 delete_case2(n)    
	- 형제가 검은색인 경우    
		(3) 부모노드 검은색, 형제의 양쪽 자식이 모두 검은색 :  delete_case3(n)    
			-&amp;gt;형제노드만 빨간색으로    
		(4) 부모노드는 빨간색, 형제의 양쪽 자식이 모두 검은색 : delete_case4(n)    
			-&amp;gt;형제:빨간색 부모:검정색    
		(5) 삭제노드와 가까운 조카노드가 빨간색일때 : delete_case5(n)    
			-&amp;gt; 형제와 조카노드 색교환, 형제기준 조카노드를 올리는 방향의 회전    
			(아래 case6 조건으로 변경됨)    
		(6) 삭제노드와 먼 조카노드가 빨간색 (가까운조카색 관계없음) : delete_case6(n)    
			형제는 부모노드 색으로, 부모는 검은색으로     
			멀리있는 조카노드 검은색으로    
			부모노드 기준 형제를 올리는 방향의 회전     
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;삭제되는 후계자 노드 위치 기준으로 delete_one_child() 부터 시작한다.&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt; &lt;span class=&quot;s&quot;&gt;&quot;여기서 n은 실제 트리에서 제거될 후계 노드의 자리를 차지하게 될 노드임에 주의&quot;&lt;/span&gt;    
&lt;span class=&quot;n&quot;&gt;delete_one_child&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;     
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;    
	&lt;span class=&quot;n&quot;&gt;child&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;is_leaf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;n의 자식&quot;&lt;/span&gt;     
    
	&lt;span class=&quot;n&quot;&gt;child&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;의&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;자식&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;를&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;삭제될&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;후계노드&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;있던&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;자리로&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;변경&lt;/span&gt;    
	&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;블랙&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;    
		&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;child&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;레드&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;    
			&lt;span class=&quot;n&quot;&gt;child&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;블랙으로&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;변경&lt;/span&gt;    
		&lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;    
			&lt;span class=&quot;n&quot;&gt;delete_case1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;child&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;호출&lt;/span&gt; 
			&lt;span class=&quot;s&quot;&gt;&quot;n의 자식으로 case 1 부터 start!&quot;&lt;/span&gt;    
			&lt;span class=&quot;s&quot;&gt;&quot;여기서 child의 위치는 후계노드의 원래 위치와 동일함&quot;&lt;/span&gt;  
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;    
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt; &lt;span class=&quot;s&quot;&gt;&quot;여기서 n은 대체노드의 자식노드 child임에 주의&quot;&lt;/span&gt;    
&lt;span class=&quot;n&quot;&gt;delete_case1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;    
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;    
	&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;삭제노드의&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;부모가&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;NULL&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;이&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;아니면&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;    
		&lt;span class=&quot;n&quot;&gt;delete_case2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;호출&lt;/span&gt;    
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;    
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt; &lt;span class=&quot;s&quot;&gt;&quot;형제를 검은색, 부모를 빨간색으로 바꾸고 left/right회전!&quot;&lt;/span&gt;    
&lt;span class=&quot;n&quot;&gt;delete_case2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;    
	&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;형제&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;레드&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;     
		&lt;span class=&quot;err&quot;&gt;부모노드를&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;빨간색&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;형제노드를&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;검은색&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;변경&lt;/span&gt;    
		&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;부모의&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;왼쪽자식&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;    
			&lt;span class=&quot;n&quot;&gt;rotation_left&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;부모노드&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;    
		&lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;    
			&lt;span class=&quot;n&quot;&gt;rotation_right&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;부모노드&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;	    
			    
	&lt;span class=&quot;n&quot;&gt;delete_case3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;호출&lt;/span&gt;    
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;    
    
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;delete_case3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;    
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;    
	&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;형제&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;블랙&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;부모&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;블랙&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;형제&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;좌&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;우&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;자식&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;블랙&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;    
		&lt;span class=&quot;err&quot;&gt;형제를&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;빨간색&lt;/span&gt;    
		&lt;span class=&quot;n&quot;&gt;deletion_case1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;부모노드&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;호출&lt;/span&gt;    
	&lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;    
		&lt;span class=&quot;n&quot;&gt;deletion_case4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;호출&lt;/span&gt;    
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;    
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;delete_case4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;    
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;    
	&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;형제&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;블랙&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;부모&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;레드&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;형제&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;좌&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;우&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;자식&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;블랙&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;    
		&lt;span class=&quot;err&quot;&gt;형제를&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;빨간색&lt;/span&gt;    
		&lt;span class=&quot;err&quot;&gt;부모를&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;검정색으로&lt;/span&gt;     
	&lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;    
		&lt;span class=&quot;n&quot;&gt;deletion_case5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;호출&lt;/span&gt;    
	    
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;    
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;delete_case5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;	&lt;span class=&quot;c1&quot;&gt;//case6 를 수행할 구조로 만드는 작업    &lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;    
	&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;형제&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;블랙&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;    
		&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;이&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;부모노드의&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;왼쪽자식&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;형제&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;오른쪽자식&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;검정&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;형제&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;왼쪽자식&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;빨강&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;    
			&lt;span class=&quot;err&quot;&gt;형제노드&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;빨간색으로&lt;/span&gt;    
		 	&lt;span class=&quot;err&quot;&gt;형제&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;왼쪽&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;자식&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;검은색으로&lt;/span&gt;     
			&lt;span class=&quot;n&quot;&gt;rotation_right&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;형제노드&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;	    
		&lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;이&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;부모노드의&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;오른쪽&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;자식&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;형제&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;왼쪽자식&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;검정&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;형제&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;오른쪽자식&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;빨강&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;    
			&lt;span class=&quot;err&quot;&gt;형제노드&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;빨간색으로&lt;/span&gt;    
		 	&lt;span class=&quot;err&quot;&gt;형제&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;오른쪽&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;자식&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;검은색으로&lt;/span&gt;     
			&lt;span class=&quot;n&quot;&gt;rotation_left&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;형제노드&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;    
    
	&lt;span class=&quot;n&quot;&gt;deletion_case6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;호출&lt;/span&gt;    
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;    
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;delete_case6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;    
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;    
	&lt;span class=&quot;err&quot;&gt;형제색&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;부모의&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;색으로&lt;/span&gt;    
	&lt;span class=&quot;err&quot;&gt;부모색&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;검정색으로&lt;/span&gt;    
	&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;이&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;부모의&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;왼쪽&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;자식이면&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;    
		&lt;span class=&quot;err&quot;&gt;형제의&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;오른쪽자식&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;검정색&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;으로&lt;/span&gt;    
		&lt;span class=&quot;n&quot;&gt;rotation_left&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;부모노드&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;    
	&lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;n이 부모의 오른쪽 자식&quot;&lt;/span&gt;    
		&lt;span class=&quot;err&quot;&gt;형제의&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;왼쪽자식&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;검정색&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;으로&lt;/span&gt;    
		&lt;span class=&quot;n&quot;&gt;rotation_right&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;부모노드&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;    
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;    
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;references&quot;&gt;References&lt;/h1&gt;
&lt;hr /&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.cs.usfca.edu/~galles/visualization/RedBlack.html&quot;&gt;https://www.cs.usfca.edu/~galles/visualization/RedBlack.html&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Red-black_tree&quot;&gt;https://en.wikipedia.org/wiki/Red-black_tree&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://lwn.net/Articles/184495/&quot;&gt;https://lwn.net/Articles/184495/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
        <pubDate>Sun, 14 Nov 2021 13:00:00 +0000</pubDate>
        <link>https://soopsaram.com/documentudy/2021/11/14/rbtree-in-linux-kernel-part1/</link>
        <guid isPermaLink="true">https://soopsaram.com/documentudy/2021/11/14/rbtree-in-linux-kernel-part1/</guid>
        
        <category>Linux</category>
        
        <category>LinuxKernel</category>
        
        <category>Algorithm</category>
        
        
        <category>LinuxKernel</category>
        
      </item>
    
      <item>
        <title>If 없이 Shell Script 분기 처리하기</title>
        <description>&lt;ul id=&quot;markdown-toc&quot;&gt;
  &lt;li&gt;&lt;a href=&quot;#exit-status란-무엇인가&quot; id=&quot;markdown-toc-exit-status란-무엇인가&quot;&gt;Exit Status란 무엇인가&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#if없이-커맨드-분기-처리&quot; id=&quot;markdown-toc-if없이-커맨드-분기-처리&quot;&gt;IF없이 커맨드 분기 처리&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#대괄호의-정체&quot; id=&quot;markdown-toc-대괄호의-정체&quot;&gt;대괄호&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;[]&lt;/code&gt;의 정체&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#if-없이-조건-분기-처리&quot; id=&quot;markdown-toc-if-없이-조건-분기-처리&quot;&gt;IF 없이 조건 분기 처리&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#if-statement의-작동원리&quot; id=&quot;markdown-toc-if-statement의-작동원리&quot;&gt;If Statement의 작동원리&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#references&quot; id=&quot;markdown-toc-references&quot;&gt;References&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt; condition &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;then
    &lt;/span&gt;cmd
&lt;span class=&quot;k&quot;&gt;fi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;나는 쉘스크립트를 처음 배울때, 일반적으로 사용되는 이 If 구문이 다소 난해하게 느껴졌다. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;then&lt;/code&gt; 의 존재가 생소했고, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;[]&lt;/code&gt;의 대괄호가 정확히 무엇을 의미하는지 그리고 세미콜론이 왜 붙는지 등. 이해하지 않고 그냥 외웠다. 그래서 한때는 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;;&lt;/code&gt;를 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;then&lt;/code&gt;뒤에 붙여야하는지 앞에 붙여아하는지 햇갈려서 매번 구글 검색을 했다. 이것들의 정확한 의미는 무엇일까?&lt;/p&gt;

&lt;p&gt;한편 쉘스크립트를 작성할때, If Statement를 사용하지 않고도  분기 처리하는게 가능하다. 꽤 많은 경우에 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;if&lt;/code&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;else&lt;/code&gt; 대신 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;amp;&amp;amp;&lt;/code&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;||&lt;/code&gt;를 사용한다면 훨씬 깔끔하고 명료한 분기문을 작성 할 수 있다.  이 글에서는 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;if&lt;/code&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;else&lt;/code&gt; 대신 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;amp;&amp;amp;&lt;/code&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;||&lt;/code&gt;를 사용하는 분기에 대해 알아보고, 쉘스크립트의 IF Statement의 구조에 대해 조금더 명확하게 이해해 볼 것이다.&lt;/p&gt;

&lt;h1 id=&quot;exit-status란-무엇인가&quot;&gt;Exit Status란 무엇인가&lt;/h1&gt;
&lt;p&gt;우선 exit statue(혹은 exit code)에 대해 이해할 필요가 있다. UNIX운영체제 표준인 POSIX 표준에서 프로그램은 성공적으로 수행했을때 exit status 0을 리턴한다. 실패했을때는 1이상의 값을 리턴한다. 그래서 프로그램이나 쉘스크립트를 작성할때 exit status를 리턴하는것을 빼먹지 않도록 유의해야한다. 다른 프로그램과 스크립트에서 해당 프로그램이 정상적으로 수행되었는지 정확히 확인을 하기 위해서이다.&lt;/p&gt;

&lt;p&gt;참고로 bash에서 exit status를 만들기 위해서는 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;exit&lt;/code&gt; 과 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;return&lt;/code&gt; 유틸리티(명령어)를 이용한다. (둘다 아마도 shell built-in commnad일것이다.)&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;return &amp;lt;number&amp;gt;&lt;/code&gt;
해당 함수를 종료하고 exit status를 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;lt;number&amp;gt;&lt;/code&gt; 으로 만든다. 함수에서만 사용가능. &lt;strong&gt;함수 종료이후&lt;/strong&gt; echo $? 로 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;lt;number&amp;gt;&lt;/code&gt; 값이 무엇이었는지 확인가능하다. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;$?&lt;/code&gt;에는 이전 명령의 exit code값이 저장되어있다.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;exit &amp;lt;number&amp;gt;&lt;/code&gt;
전체 스크립트를 종료하고 exit status를 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;lt;number&amp;gt;&lt;/code&gt;으로 만든다. &lt;strong&gt;스크립트 종료 이후&lt;/strong&gt;, 마찬가지로 echo $? 로 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;lt;number&amp;gt;&lt;/code&gt; 값을 확인가능하다.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;if없이-커맨드-분기-처리&quot;&gt;IF없이 커맨드 분기 처리&lt;/h1&gt;

&lt;p&gt;cmd1이 정상적인 exit status를 리턴한다고 가정하고, 이전 명령의 성공/실패 여부에따라 cmd2를 수행해보자. 먼저 if/else를 사용한다면 다음과 같이 길고 다소 복잡해진다.&lt;/p&gt;

&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;cmd1
&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$?&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-eq&lt;/span&gt; 0 &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;then
    &lt;/span&gt;cmd2
&lt;span class=&quot;k&quot;&gt;fi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;하지만 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;amp;&amp;amp;&lt;/code&gt;와 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;||&lt;/code&gt;를 사용하면, 이를 한줄로 처리할수 있다. 코드가 훨신 간결해진다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;cmd1 성공시에만 cmd2 실행&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;cmd1 &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; cmd2
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;cmd1 실패시에만 cmd2 실행&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;cmd1 &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; cmd2
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;만약 cmd1이 성공했을때 cmd2를 실행하고, 실패할때 cmd3를 실행하고자 한다면 아래와 같이 한줄로 처리 가능하다.&lt;/p&gt;

&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;cmd1 &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; cmd2 &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; cmd3
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;명령어에 대한 exit status 처리는 가능하면 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;amp;&amp;amp;&lt;/code&gt; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;||&lt;/code&gt;를 사용하는게 코드를 훨씬 간결하게 만든다.&lt;/p&gt;

&lt;h1 id=&quot;대괄호의-정체&quot;&gt;대괄호&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;[]&lt;/code&gt;의 정체&lt;/h1&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;[ &lt;/code&gt; 는 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;test&lt;/code&gt; 와 동일한 커맨드이다. 따라서 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;[&lt;/code&gt; 도 하나의 shell 명령어이자 프로그램이다. 다만 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;[&lt;/code&gt; 는 반드시 마지막에 인자 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;]&lt;/code&gt; 를 전달해야한다는점이 다를 뿐이다. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;test&lt;/code&gt;는 전달된 인자를 평가(evaluate)하는 유틸리티이다. 이 명령의 결과는 exit status 인데 전달된 인자가 True 인경우는 0 이고 False인 경우는 1이된다. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;[ &lt;/code&gt; 와 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;test&lt;/code&gt;는 &lt;a href=&quot;https://pubs.opengroup.org/onlinepubs/9699919799/utilities/test.html&quot;&gt;POSIX 표준&lt;/a&gt;이기 때문에 대부분의 쉘에서 지원한다.&lt;/p&gt;

&lt;p&gt;참고로 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;[[&lt;/code&gt; 는 bash shell 에서 사용하는 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;[&lt;/code&gt;의 개선된 버전이다. bash가 아닌 shell에서 정상적으로 동작한다는 보장은 없지만, ksh, bash, zsh, yash, busybox sh에서는 지원한다고 한다.&lt;/p&gt;

&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;aa&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;aa&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;then 
    &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'yes'&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;fi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;if &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;test&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;aa&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;aa&quot;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;then 
    &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'yes'&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;fi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;따라서 위 두 구문은 동일한 동작을 한다.&lt;/p&gt;

&lt;h1 id=&quot;if-없이-조건-분기-처리&quot;&gt;IF 없이 조건 분기 처리&lt;/h1&gt;

&lt;p&gt;위에서 대괄호도 결국 test 커맨드임을 알게 되었다. 따라서 명시적인 If Statement없이도 분기처리가 가능하다. 기존의 If 조건에 따른 분기 대신에 &amp;amp;&amp;amp;를 사용하여 작성하면 다음과 같이 할 수 있다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;condition이 true일때만 cmd 수행&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt; condition &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; cmd
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;condition이 false 일때만 cmd가 수행.&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt; condition &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; cmd
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;condition에 따라 if/else 처리&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt; condition &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; cmd1 &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; cmd2
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;condition이 true이면 cmd1 false이면 cmd2가 수행된다. 아래와 동일한 동작이다.&lt;/p&gt;

&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt; condition &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;then
    &lt;/span&gt;cmd1
&lt;span class=&quot;k&quot;&gt;else
    &lt;/span&gt;cmd2
&lt;span class=&quot;k&quot;&gt;fi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;한가지 주의할 점은 shell에서는 무조건 왼쪽에서 오른쪽으로 순차적으로 명령과 연산자를 수행한다는 점이다. c언어처엄 논리 연산자 우선순위에 따라 명령을 처리하지 않는다. 가령 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;[ condition ] &amp;amp;&amp;amp; cmd1 &amp;amp;&amp;amp; cmd2 || cmd3&lt;/code&gt; 은 먼저 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;[ condition ]&lt;/code&gt; 명령이 성공하면 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cmd1&lt;/code&gt;명령을 실행하고 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cmd1&lt;/code&gt;이 성공하면 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cmd2&lt;/code&gt;가 실행된다. 그리고 만약 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cmd1&lt;/code&gt;이 실패하면 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cmd2&lt;/code&gt;는 실행되지 않고 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cmd3&lt;/code&gt;이 실행된다.&lt;/p&gt;

&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;#! /bin/bash&lt;/span&gt;

&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt; condition &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; cmd1
&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;hello&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;또 주의할 사항이 있다. 만약 위와 같이 스크립트를 작성한경우 condition이 False이면 exit 1이 리턴된다. 그 뜻은 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;echo &quot;hello&quot;&lt;/code&gt; 라인이 수행되기도 전에 이 스크립트 자체가 비정상 종료된다는 뜻이다. 만약 If Statement를 사용했다면 “hello”는 출력되지 않았겠지만 전체스크립트가 비정상 종료되지는 않았을것이다. 따라서 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;if/else&lt;/code&gt;대신 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;amp;&amp;amp;&lt;/code&gt; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;||&lt;/code&gt;를 사용한다면 exit status에 대한 처리에 주의해야할 것이다.&lt;/p&gt;

&lt;p&gt;그렇다면 위에서 condition이 False인경우 아무것도 하지 않고 다음 라인 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;echo &quot;hello&quot;&lt;/code&gt; 을 실행하기 위해서는 어떻게 하면 될까? 두가지 해결 방안이 있다.&lt;/p&gt;

&lt;p&gt;먼저 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;set -e&lt;/code&gt; 처리를 하면 exit 1이 발생하지 않는다. 참고로 set -e 는 POSIX 표준이다.&lt;/p&gt;

&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;#! /bin/bash&lt;/span&gt;

&lt;span class=&quot;nb&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-e&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt; condition &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; cmd1
&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;hello&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;두번째로는 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;|| true&lt;/code&gt; 로 false 인 경우도 추가하여 아무동작도 수행하지 않는것이다.&lt;/p&gt;

&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;#! /bin/bash&lt;/span&gt;

&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt; condition &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; cmd1 &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;true
echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;hello&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;이렇게 하면 condition이 false더라도 해당 스크립트가 비정상 종료 되지 않고 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;echo &quot;hello&quot;&lt;/code&gt;가 출력된다.&lt;/p&gt;

&lt;h1 id=&quot;if-statement의-작동원리&quot;&gt;If Statement의 작동원리&lt;/h1&gt;

&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;if
   &lt;/span&gt;cmd1
&lt;span class=&quot;k&quot;&gt;then
   &lt;/span&gt;cmd2
&lt;span class=&quot;k&quot;&gt;else
   &lt;/span&gt;cmd3
&lt;span class=&quot;k&quot;&gt;fi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;이제 쉘스크립트의 If Statement 를 정확히 알아보자. 중요한점은 If 바로 다음에는 명령어가 온다는것이다. 여기에는 보통 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;[]&lt;/code&gt;로 표현되는 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;test&lt;/code&gt;명령을 사용하지만 이전에 설명했드시 일반 명령어를 사용할수도 있다.  그렇다면 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;then&lt;/code&gt;이 하는 역할은 무엇인가? &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;then&lt;/code&gt;이 바로 이전명령의 exit status를 포착하는 역할이다. 이전 exit status가 0 인경우에 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;then&lt;/code&gt; state의 구문이 수행되는 것이다. 따라서 위의 예에서 cmd1 이 exit code 0을 리턴하면 cmd2 가 수행되고 1 이상의 값을 리턴하면 cmd3이 수행된다. 참고로 우리가 이미 알고있듯이 많은 쉘스크립트가 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;if cmd1; then&lt;/code&gt; 과 같이 한줄로 표기한다. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;;&lt;/code&gt;는 명령어 뒤에 붙으며, 다음명령까지 한줄에서 처리하게 만드는 역할을 한다.&lt;/p&gt;

&lt;h1 id=&quot;references&quot;&gt;References&lt;/h1&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.gnu.org/software/bash/manual/html_node/Conditional-Constructs.html&quot;&gt;https://www.gnu.org/software/bash/manual/html_node/Conditional-Constructs.html&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.gnu.org/savannah-checkouts/gnu/bash/manual/bash.html#Lists&quot;&gt;https://www.gnu.org/savannah-checkouts/gnu/bash/manual/bash.html#Lists&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://stackoverflow.com/questions/4419952/difference-between-return-and-exit-in-bash-functions&quot;&gt;https://stackoverflow.com/questions/4419952/difference-between-return-and-exit-in-bash-functions&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://unix.stackexchange.com/questions/609092/what-is-the-difference-between-square-brackets-and-test-command-on-bash&quot;&gt;https://unix.stackexchange.com/questions/609092/what-is-the-difference-between-square-brackets-and-test-command-on-bash&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://youtu.be/p0KKBmfiVl0&quot;&gt;YouTube: Never say “If” writing a Bash script!&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://unix.stackexchange.com/questions/306111/what-is-the-difference-between-the-bash-operators-vs-vs-vs&quot;&gt;https://unix.stackexchange.com/questions/306111/what-is-the-difference-between-the-bash-operators-vs-vs-vs&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
        <pubDate>Sun, 10 Oct 2021 13:00:00 +0000</pubDate>
        <link>https://soopsaram.com/documentudy/2021/10/10/shell-script-without-if-else/</link>
        <guid isPermaLink="true">https://soopsaram.com/documentudy/2021/10/10/shell-script-without-if-else/</guid>
        
        <category>UNIX</category>
        
        <category>ShellScript</category>
        
        <category>Bash</category>
        
        <category>Sh</category>
        
        <category>POSIX</category>
        
        
        <category>UNIX</category>
        
      </item>
    
      <item>
        <title>GNU autotools 로 UNIX스럽게 프로젝트 구성하기</title>
        <description>&lt;ul id=&quot;markdown-toc&quot;&gt;
  &lt;li&gt;&lt;a href=&quot;#빌드-시스템&quot; id=&quot;markdown-toc-빌드-시스템&quot;&gt;빌드 시스템&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#tldr&quot; id=&quot;markdown-toc-tldr&quot;&gt;TL;DR&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#소스코드-작성&quot; id=&quot;markdown-toc-소스코드-작성&quot;&gt;소스코드 작성&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#autoconf&quot; id=&quot;markdown-toc-autoconf&quot;&gt;autoconf&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#aclocal&quot; id=&quot;markdown-toc-aclocal&quot;&gt;aclocal&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#automake&quot; id=&quot;markdown-toc-automake&quot;&gt;automake&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#autoreconf&quot; id=&quot;markdown-toc-autoreconf&quot;&gt;autoreconf&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#프로젝트-배포하기&quot; id=&quot;markdown-toc-프로젝트-배포하기&quot;&gt;프로젝트 배포하기&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#생성한-프로젝트-빌드-및-설치-해보기&quot; id=&quot;markdown-toc-생성한-프로젝트-빌드-및-설치-해보기&quot;&gt;생성한 프로젝트 빌드 및 설치 해보기&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#실행파일-생성&quot; id=&quot;markdown-toc-실행파일-생성&quot;&gt;실행파일 생성!&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#요약&quot; id=&quot;markdown-toc-요약&quot;&gt;요약&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#references&quot; id=&quot;markdown-toc-references&quot;&gt;References&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;빌드-시스템&quot;&gt;빌드 시스템&lt;/h1&gt;
&lt;p&gt;프로젝트의 소스코드가 한두개가 아니라 수십 수만개가 되면 gcc 로 일일이 컴파일을하여 하나의 executable 실행파일로 생성하는것은 불가능하다. 이를 위해 make 빌드시스템이 고대에 도입되었다(It was originally created by Stuart Feldman in April 1976 at Bell Labs.). make는 Makefile이라는 파일을 이용해 소스코드를 컴파일하고 빌드한다. Makefile은 컴파일을 위한 쉘스크립트라고 보면 쉽다. 일반 쉘스크립트를 이용해 빌드환경을 만들수 도 있다. 그러나 보통 쉘스크립트는 빌드환경에 특화되어있지 않기 때문에 거의 사용하지 않는다. 참고로 쉘스크립트와 Makefile 스크립트의 다른점 중 하나는 Increamental Build인데, 기존에 빌드를  진행한적이 있다면, 그 뒤에는 make가 최근 수정된 소스코드만 컴파일하여 최종 executable에 링크하는 를 할 수 있다.&lt;/p&gt;

&lt;p&gt;또한 소스코드의 파일이 방대한경우 그리고 빌드하는 환경이 유저마다 서로 다른경우, 또한 여러가지 기능들을 사용자가 추가/제거 하고 싶은경우 Makefile에서 모든것을 처리하는게 쉬운일은 아니다. 그래서 대부분의 UNIX 유틸리티의 소스코드 패키지에는 autotools 로 생성한 configure파일 그리고 Mafefile.am파일이 존재해서 사용자가 직접 본인의 UNIX 환경에서 Makefile을 생성하게끔 한다.  GNU autotools는 이렇게 불편을 최소화하기 위해 소스코드 패키지를 여러 UNIX계열 시스템에 이식성(portable)가능하게 만들어주는 도구다. 다시말해 이식성 가능한 프로젝트 빌드를 가능하게 해주는 도구다.&lt;/p&gt;

&lt;p&gt;make는 거의 무려 50년전에 만들어진 소프트웨어이기 때문에 현대의 빠른 빌드를 요구하는 환경에는 적합하지 않을수도 있다. 그래서 여러가지 빌드시스템이 만들어졌고 사용되고 있다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Cmake&lt;/li&gt;
  &lt;li&gt;Ninja (Chromium, Andriod Soong빌드 등)&lt;/li&gt;
  &lt;li&gt;Meson (Systemd 등)&lt;/li&gt;
  &lt;li&gt;Cargo (Rust)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;거의 대부부분의 UNIX 유틸리티는 빌드할때 아래와 같은 과정을 거치도록 만들어졌다. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;./configure&lt;/code&gt;로 옵션으로 전달받은 Feature를 추가/제거하고 현재 호스트의 운영체제와 환경등을 고려하여 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Makefile&lt;/code&gt; 을 생성한다. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;make&lt;/code&gt; 로 실제 소스코드를 빌드하고. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;make install&lt;/code&gt;로 사용자의 환경에 install한다(실행파일과 라이브러리등을 적절한 path에 배치한다). 가령 grep-3.7 의경우 &lt;a href=&quot;https://www.linuxfromscratch.org/lfs/view/stable/chapter08/grep.html&quot;&gt;이렇게&lt;/a&gt; 빌드한다.&lt;/p&gt;

&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt; &lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;./configure
 &lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;make
 &lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;make &lt;span class=&quot;nb&quot;&gt;install&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;UNIX 유틸리티중 하나를 찾아서 소스코드를 다운로드 받아보자&lt;a href=&quot;https://ftp.gnu.org/gnu/grep/grep-3.7.tar.xz&quot;&gt;(Grep-3.7 다운로드)&lt;/a&gt;. 소스코드 압축을 풀면 configure 파일이 존재한다. 이는 Makefile을 생성하는 쉘스크립트이다. 나는 소스코드에서 configure 파일의 라인수를 보고 내 두 눈을 의심했다. 파일이 5만 라인이 넘었기 때문이다. 이걸 인간이 짤 수 있다는 말인가? 유틸리티 소스코드도 작성하기 힘든데 빌드시스템을 위해 이렇게 많은 스크립트를 작성해야 한다는 말인가? 하는 생각들에 아찔해졌다. 하지만 파일 상단 주석에 이렇게 쓰여있었다. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Generated by GNU Autoconf 2.71 for GNU grep 3.7.&lt;/code&gt; 다행히도 configure 스크립트는 자동생성 되는것이다. 바로 autoconf 라는 프로그램이 자동으로 생성해준다. autoconf가 얼마나 많은 라인을 만들어내는지 간단한 autoconf 스크립트를 작성해 실험해보자.&lt;/p&gt;

&lt;p&gt;먼저 디렉터리 하나를 생성하고 autoconf.ac 라는 파일을 생성하여 아래의 두 줄을 작성한다. autoconf.ac 이 configure 파일을 생성하기 위해 사용자가 작성해야할 파일이다. 자세한 내용은 아래에서 다시 설명할 것이다.&lt;/p&gt;

&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;AC_INIT&lt;span class=&quot;o&quot;&gt;([&lt;/span&gt;helloworld], &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;0.1]&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
AC_OUTPUT
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;그리고 Shell에서 autoconf 프로그램을 실행한다. 그러면 아래와 같이 configure 파일이 생성된것을 알 수 있다.&lt;/p&gt;

&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt; &lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;aclocal
 &lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;autoconf
 &lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;ls
&lt;/span&gt;autom4te.cache  configure  configure.ac
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;그리고 configure파일을 열어서 확인해 보자. 고작 두줄짜리로 부터 얼마나 많은 라인의 configure스크립트가 자동생성되었는지… (나는 2402라인이 생성되었다.).&lt;/p&gt;

&lt;h1 id=&quot;tldr&quot;&gt;TL;DR&lt;/h1&gt;

&lt;p&gt;이제 autotools 를 이용해 간단한 helloworld 프로그램의 소스코드 패키지 레이아웃을 UNIX스럽고 프로페셔널 해보이게(?) 구성해보자. 결론부터 이야기하면 GNU autotools 에서 사용하는 도구는 다음과같이 두가지다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;configure.ac 파일로 부터 configure 파일 생성 명령어
    &lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt; &lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;autoconf
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;Makefile.am 파일로 부터 Makefile.in 생성 명령어
    &lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt; &lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;automake &lt;span class=&quot;nt&quot;&gt;--add-missing&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;소스코드-작성&quot;&gt;소스코드 작성&lt;/h1&gt;

&lt;p&gt;먼저 소스코드를 작성해보자. 이 예제에서는 간단하게 helloworld.c 하나를 작성했다.&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cp&quot;&gt;#include &amp;lt;stdio.h&amp;gt;
&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;argc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;argv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[])&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;printf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;hello, world!&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;autoconf&quot;&gt;autoconf&lt;/h1&gt;
&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;autoconf&lt;/code&gt;는 configure 스크립트를 자동생성해주는 도구다. autotools 는 m4 매크로 패턴을 사용한다. 아래와 같이 매크로를 사용해 최소한의 정보를 입력해보자.&lt;/p&gt;

&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;AC_INIT&lt;span class=&quot;o&quot;&gt;([&lt;/span&gt;helloworld], &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;0.1], &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;jihuun.k@gmail.com]&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
AM_INIT_AUTOMAKE
AC_PROG_CC
AC_CONFIG_FILES&lt;span class=&quot;o&quot;&gt;([&lt;/span&gt;Makefile]&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
AC_OUTPUT
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AC_INIT&lt;/code&gt;
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;autoconf&lt;/code&gt; 에게 생성할 프로그램 이름, 그리고 버전정보, 그리고 누가 maintainer인지 알려준다.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AM_INIT_AUTOMAKE&lt;/code&gt;
automake도 사용할 예정이라면 추가한다.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AC_PROG_CC&lt;/code&gt;
사용자의 현재 환경의 C 컴파일러를 사용하도록 설정한다.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AC_CONFIG_FILES&lt;/code&gt;
AC_CONFIG_FILES([filename]) 은 filename.in 파일로부터 filename파일을 생성한다는 의미다.&lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AC_OUTPUT&lt;/code&gt;
최종 output을 생성한다는 의미 configure.ac 스크립트의 마지막에 위치한다.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;보다 자세한 autoconf 매크로 정보는 GNU autoconf manual에서 확인가능하다. &lt;a href=&quot;https://www.gnu.org/software/autoconf/manual/autoconf-2.66/autoconf.html&quot;&gt;https://www.gnu.org/software/autoconf/manual/autoconf-2.66/autoconf.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;그 뒤에 아래와 같이 autoconf 명령을 수행하면 configure파일이 생성된다.&lt;/p&gt;

&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt; &lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;aclocal
 &lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;autoconf
 &lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;ls
&lt;/span&gt;autom4te.cache  configure  configure.ac
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;aclocal&quot;&gt;aclocal&lt;/h1&gt;
&lt;p&gt;한편 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;autoconf&lt;/code&gt; 명령을 사용하기 전에 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;aclocal&lt;/code&gt; 명령어를 통해 사전에 환경을 설정해줘야한다. aclocal 명령을 수행하면 aclocal.m4 파일이 생성된다. 그 뒤 autoconf 수행하면 configure 파일을 생성할 수 있다. 참고로 aclocal을 하지 않으면 아래와 같은 에러가 발생한다.&lt;/p&gt;

&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt; &lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;autoconf
configure.ac:2: error: possibly undefined macro: AM_INIT_AUTOMAKE
      If this token and others are legitimate, please use m4_pattern_allow.
      See the Autoconf documentation.
 &lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;aclocal
 &lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;autoconf
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;automake&quot;&gt;automake&lt;/h1&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;automake&lt;/code&gt;는 Makefile.am 파일로부터 Makefile.in 파일을 생성하는 도구이다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Makefile.am 생성&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;AUTOMAKE_OPTIONS  &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; foreign
bin_PROGRAMS &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; helloworld
helloworld_SOURCES &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; helloworld.c

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AUTOMAKE_OPTIONS  = foreign&lt;/code&gt;
GNU 프로젝트의 Standard Layout을 따르지 않을거라면 추가한다.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bin_PROGRAMS = programname&lt;/code&gt;
생성할 실행파일(프로그램) 이름을 기입한다.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;programname_SOURCES = srcfilename.c&lt;/code&gt;
소스코드 파일명을 기입한다.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;이제 automake를 수행하면 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Makefile.in&lt;/code&gt; 이 생성된다.&lt;/p&gt;

&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt; &lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;automake &lt;span class=&quot;nt&quot;&gt;--add-missing&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;참고&lt;/code&gt;–add-missing 사용하는 이유:
automake 는 특정상황에 따라 여러가지 common파일들을 요구한다. 이 옵션을 사용하면 그파일들을 자동생성해준다.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;참고&lt;/code&gt; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AUTOMAKE_OPTIONS  = foreign&lt;/code&gt; 이 없을때 발생하는 에러
GNU 프로젝트의 standard Layout 을 추가하지 않아서 에러가 발생한다. 아래와 같은 파일들이 생성되어야 한다.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;automake &lt;span class=&quot;nt&quot;&gt;--add-missing&lt;/span&gt;
configure.ac:3: installing &lt;span class=&quot;s1&quot;&gt;'./compile'&lt;/span&gt;
configure.ac:2: installing &lt;span class=&quot;s1&quot;&gt;'./install-sh'&lt;/span&gt;
configure.ac:2: installing &lt;span class=&quot;s1&quot;&gt;'./missing'&lt;/span&gt;
Makefile.am: installing &lt;span class=&quot;s1&quot;&gt;'./INSTALL'&lt;/span&gt;
Makefile.am: error: required file &lt;span class=&quot;s1&quot;&gt;'./NEWS'&lt;/span&gt; not found
Makefile.am: error: required file &lt;span class=&quot;s1&quot;&gt;'./README'&lt;/span&gt; not found
Makefile.am: error: required file &lt;span class=&quot;s1&quot;&gt;'./AUTHORS'&lt;/span&gt; not found
Makefile.am: error: required file &lt;span class=&quot;s1&quot;&gt;'./ChangeLog'&lt;/span&gt; not found
Makefile.am: installing &lt;span class=&quot;s1&quot;&gt;'./COPYING'&lt;/span&gt; using GNU General Public License v3 file
Makefile.am:     Consider adding the COPYING file to the version control system
Makefile.am:     &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;your code, to avoid questions about which license your project uses
Makefile.am: installing &lt;span class=&quot;s1&quot;&gt;'./depcomp'&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;최종 생성된 파일들&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt; &lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;ls
&lt;/span&gt;aclocal.m4  autom4te.cache  compile  configure  configure.ac  COPYING  depcomp  helloworld.c  INSTALL  install-sh  Makefile.am  Makefile.in  missing

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;autoreconf&quot;&gt;autoreconf&lt;/h1&gt;
&lt;p&gt;참고로 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;autoreconf&lt;/code&gt;를 사용하면 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;aclocal&lt;/code&gt;,  &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;autoconf&lt;/code&gt; 및 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;automake&lt;/code&gt;를 직접 하나하나 수행할 필요없다. 알아서 한번에 수행해준다.&lt;/p&gt;

&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt; &lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;autoreconf &lt;span class=&quot;nt&quot;&gt;-i&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;프로젝트-배포하기&quot;&gt;프로젝트 배포하기&lt;/h1&gt;

&lt;p&gt;이제 드디어 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;configure&lt;/code&gt; 스크립트와 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Makefile.in&lt;/code&gt; 파일이 우리 프로젝트에 생성되었다. 이제 소스코드를 다운로드 받은 사용자는 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;configure&lt;/code&gt; 와 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;make&lt;/code&gt; 를 사용해 프로젝트를 빌드 할 수 있다. 프로젝트는 이상태에서 배포가능하다. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;make dist&lt;/code&gt;를 수행하면 배포가능한 tarball이 생성된다.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt; $ make dist
 $ ls
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;또한 다음과 같이 배포할 tarball이 여러 환경과 조건에서 정상적으로 install될 수 있을지 테스트해볼 수 있다.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt; $ make distcheck
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;생성한-프로젝트-빌드-및-설치-해보기&quot;&gt;생성한 프로젝트 빌드 및 설치 해보기&lt;/h1&gt;
&lt;p&gt;이제 아래의 UNIX 빌드 명령으로 프로젝트 빌드를 해보자. configure 실행하여 Makefile을 생성하고 make를통해 빌드해보자.&lt;/p&gt;

&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt; &lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;./configure
 &lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;make
 &lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;make &lt;span class=&quot;nb&quot;&gt;install&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt; &lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;./configure
checking &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;a BSD-compatible install... /usr/bin/install &lt;span class=&quot;nt&quot;&gt;-c&lt;/span&gt;
checking whether build environment is sane... &lt;span class=&quot;nb&quot;&gt;yes
&lt;/span&gt;checking &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;a thread-safe &lt;span class=&quot;nb&quot;&gt;mkdir&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-p&lt;/span&gt;... /bin/mkdir &lt;span class=&quot;nt&quot;&gt;-p&lt;/span&gt;
checking &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;gawk... gawk
checking whether make sets &lt;span class=&quot;si&quot;&gt;$(&lt;/span&gt;MAKE&lt;span class=&quot;si&quot;&gt;)&lt;/span&gt;... &lt;span class=&quot;nb&quot;&gt;yes
&lt;/span&gt;checking whether make supports nested variables... &lt;span class=&quot;nb&quot;&gt;yes
&lt;/span&gt;checking &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;gcc... gcc
checking whether the C compiler works... &lt;span class=&quot;nb&quot;&gt;yes
&lt;/span&gt;checking &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;C compiler default output file name... a.out
checking &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;suffix of executables...
checking whether we are cross compiling... no
checking &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;suffix of object files... o
checking whether we are using the GNU C compiler... &lt;span class=&quot;nb&quot;&gt;yes
&lt;/span&gt;checking whether gcc accepts &lt;span class=&quot;nt&quot;&gt;-g&lt;/span&gt;... &lt;span class=&quot;nb&quot;&gt;yes
&lt;/span&gt;checking &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;gcc option to accept ISO C89... none needed
checking whether gcc understands &lt;span class=&quot;nt&quot;&gt;-c&lt;/span&gt; and &lt;span class=&quot;nt&quot;&gt;-o&lt;/span&gt; together... &lt;span class=&quot;nb&quot;&gt;yes
&lt;/span&gt;checking &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;style of include used by make... GNU
checking dependency style of gcc... gcc3
checking that generated files are newer than configure... &lt;span class=&quot;k&quot;&gt;done
&lt;/span&gt;configure: creating ./config.status
config.status: creating Makefile
config.status: executing depfiles commands

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt; $ make
CDPATH=&quot;${ZSH_VERSION+.}:&quot; &amp;amp;&amp;amp; cd . &amp;amp;&amp;amp; /bin/sh /home/jihuun/project/c_language/autotools_test/missing autoconf
/bin/sh ./config.status --recheck
running CONFIG_SHELL=/bin/sh /bin/sh ./configure --no-create --no-recursion
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking for a thread-safe mkdir -p... /bin/mkdir -p
checking for gawk... gawk
checking whether make sets $(MAKE)... yes
checking whether make supports nested variables... yes
checking for gcc... gcc
checking whether the C compiler works... yes
checking for C compiler default output file name... a.out
checking for suffix of executables...
checking whether we are cross compiling... no
checking for suffix of object files... o
checking whether we are using the GNU C compiler... yes
checking whether gcc accepts -g... yes
checking for gcc option to accept ISO C89... none needed
checking whether gcc understands -c and -o together... yes
checking for style of include used by make... GNU
checking dependency style of gcc... gcc3
checking that generated files are newer than configure... done
configure: creating ./config.status
 /bin/sh ./config.status
config.status: creating Makefile
config.status: executing depfiles commands
gcc -DPACKAGE_NAME=\&quot;helloworld\&quot; -DPACKAGE_TARNAME=\&quot;helloworld\&quot; -DPACKAGE_VERSION=\&quot;0.1\&quot; -DPACKAGE_STRING=\&quot;helloworld\ 0.1\&quot; -DPACKAGE_BUGREPORT=\&quot;jihuun.k@gmail.com\&quot; -DPACKAGE_URL=\&quot;\&quot; -DPACKAGE=\&quot;helloworld\&quot; -DVERSION=\&quot;0.1\&quot; -I.     -g -O2 -MT helloworld.o -MD -MP -MF .deps/helloworld.Tpo -c -o helloworld.o helloworld.c
mv -f .deps/helloworld.Tpo .deps/helloworld.Po
gcc  -g -O2   -o helloworld helloworld.o

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;실행파일-생성&quot;&gt;실행파일 생성!&lt;/h1&gt;
&lt;p&gt;이제 helloworld 실행파일이 생성되었다.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt; $ ./helloworld
hello, world!
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;이제 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;make install&lt;/code&gt; 하면 현재 환경변수에 실행파일이 등록되어, 어느 위치에서든 helloworld 프로그램을 실행 시킬수 있다.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt; $ make install
 $ helloworld
hello, world!
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;참고로 최종 생성된 파일은 다음과 같다. 오지게 많다.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt; $ ls
aclocal.m4  autom4te.cache  compile  config.log  config.status  configure  configure.ac  COPYING  depcomp  helloworld  helloworld.c  helloworld.o  INSTALL  install-sh  Makefile  Makefile.am  Makefile.in  missing

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;요약&quot;&gt;요약&lt;/h1&gt;

&lt;p&gt;위의 내용을 정리하면 다음과 같다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;프로젝트 생성자 관점&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt; $ aclocal # m4 환경 생성
 $ autoconf # configure.ac 파일로 부터 configure 스크립트 생성
 $ automake --add-missing # Makefile.am 로부터 Makefile.in 생성
 $ make dist # 배포용 tarball생성
 $ make distcheck # 배포용 tarball 테스트
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;사용자 관점 빌드
해당 프로젝트 소스코드를 다운받고 본인의 환경에 설치하는 사람들은 다음의 절차를 수행할 것이다.&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt; $ ./configure # Makefile.in로부터 Makefile생성
 $ make # 전체 프로그램 빌드
 $ make install # 프로그램 설치, 실행 파일 및 라이브러리 등을 배치
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;references&quot;&gt;References&lt;/h1&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/GNU_Autotools&quot;&gt;https://en.wikipedia.org/wiki/GNU_Autotools&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.gnu.org/software/autoconf/manual/autoconf-2.66/autoconf.html&quot;&gt;https://www.gnu.org/software/autoconf/manual/autoconf-2.66/autoconf.html&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.gnu.org/software/automake/manual/automake.html#Public-Macros&quot;&gt;https://www.gnu.org/software/automake/manual/automake.html#Public-Macros&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://thoughtbot.com/blog/the-magic-behind-configure-make-make-install&quot;&gt;https://thoughtbot.com/blog/the-magic-behind-configure-make-make-install&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.geeksforgeeks.org/autoreconf-command-in-linux-with-examples/amp/&quot;&gt;https://www.geeksforgeeks.org/autoreconf-command-in-linux-with-examples/amp/&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://youtu.be/4q_inV9M_us&quot;&gt;https://youtu.be/4q_inV9M_us&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://earthly.dev/blog/autoconf/&quot;&gt;https://earthly.dev/blog/autoconf/&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://stackoverflow.com/questions/27285052/difference-between-autoconf-and-autoreconf#:~:text=1%20Answer&amp;amp;text=autoconf%20generates%20the%20configure%20script,like%20aclocal%20%2C%20automake%20%2C%20etc.&amp;amp;text=You'll%20usually%20just%20call,lower%20level%20tools%20&quot;&gt;https://stackoverflow.com/questions/27285052/difference-between-autoconf-and-autoreconf#:~:text=1%20Answer&amp;amp;text=autoconf%20generates%20the%20configure%20script,like%20aclocal%20%2C%20automake%20%2C%20etc.&amp;amp;text=You’ll%20usually%20just%20call,lower%20level%20tools%20&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Sat, 11 Sep 2021 13:00:00 +0000</pubDate>
        <link>https://soopsaram.com/documentudy/2021/09/11/gnu-autotools/</link>
        <guid isPermaLink="true">https://soopsaram.com/documentudy/2021/09/11/gnu-autotools/</guid>
        
        <category>UNIX</category>
        
        <category>Shell-Script</category>
        
        <category>GNU</category>
        
        <category>Autotools</category>
        
        <category>Make</category>
        
        
        <category>UNIX</category>
        
      </item>
    
      <item>
        <title>Publishing my project to Homebrew</title>
        <description>&lt;ul id=&quot;markdown-toc&quot;&gt;
  &lt;li&gt;&lt;a href=&quot;#1-개요&quot; id=&quot;markdown-toc-1-개요&quot;&gt;1. 개요&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#2-homebrew에-프로젝트-등록하기&quot; id=&quot;markdown-toc-2-homebrew에-프로젝트-등록하기&quot;&gt;2. Homebrew에 프로젝트 등록하기&lt;/a&gt;    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;#21--내-프로젝트-바이너리-생성-및-release&quot; id=&quot;markdown-toc-21--내-프로젝트-바이너리-생성-및-release&quot;&gt;2.1.  내 프로젝트 바이너리 생성 및 release&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#22-homebrew-rsdic-github-repo-생성&quot; id=&quot;markdown-toc-22-homebrew-rsdic-github-repo-생성&quot;&gt;2.2. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;homebrew-rsdic&lt;/code&gt; Github repo 생성&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#3-패키지-설치해보기&quot; id=&quot;markdown-toc-3-패키지-설치해보기&quot;&gt;3. 패키지 설치해보기&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#4-추후-릴리즈-자동화&quot; id=&quot;markdown-toc-4-추후-릴리즈-자동화&quot;&gt;4. 추후 릴리즈 자동화&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;1-개요&quot;&gt;1. 개요&lt;/h1&gt;
&lt;p&gt;UNIX 계열 운영체제는 각각 여러가지 Package Manager가 존재한다. 우분투 같은 Debian 계열의 리눅스 배포판은 &lt;a href=&quot;https://www.debian.org/doc/manuals/debian-reference/ch02.en.html&quot;&gt;APT-based&lt;/a&gt; package management 도구를 제공한다. Red Hat계열의 리눅스 배포판에서는 &lt;a href=&quot;https://rpm.org/&quot;&gt;RPM&lt;/a&gt;이라는 Package Manager를 제공한다. Package Manager 종류에 대한 자세한 내용은 &lt;a href=&quot;https://en.wikipedia.org/wiki/List_of_software_package_management_systems&quot;&gt;위키피디아 문서&lt;/a&gt;를 참고. MacOS 에서는 Homebrew라는Package Manager를 많이 사용하는데. Homebrew에 내가만든 소프트웨어를 Publish하여 사람들이 쉽게 내 소프트웨어를 다운받고 설치할수 있게 만들어보자. 내가 조사한 바로는 아래와 같이 두 가지 방법이 있다.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Homebrew-core 에 등록&lt;/strong&gt;&lt;br /&gt;
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;brew install &amp;lt;my-project&amp;gt;&lt;/code&gt; 로 설치가능하게 되는 공식적인 방법. &lt;a href=&quot;https://github.com/Homebrew/homebrew-core&quot;&gt;homebrew-core github repo&lt;/a&gt;에 &lt;a href=&quot;https://github.com/Homebrew/homebrew-core/pulls&quot;&gt;Pull Request&lt;/a&gt;를 보내면 되는듯 하다. 자세한 내용은 다음의 Documentation를 참고하면 된다. &lt;a href=&quot;https://docs.brew.sh/Adding-Software-to-Homebrew&quot;&gt;Adding-Software-to-Homebrew&lt;/a&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Brew tap 으로 설치&lt;/strong&gt;&lt;br /&gt;
homebrew 공식 릴리즈에 포함되지 않더라도 등록할 수 있는 방법이다. 결과는 brew tap 으로 repo를 추가할수 있게된다. 참고로 Tap 은 homebrew에서 제공하는 third-party 저장소를 등록하는 방법이다. 등록 이후에 아래와 같은 방법으로 해당 소프트웨어를 설치 할 수 있다. 참고 문서: &lt;a href=&quot;https://federicoterzi.com/blog/how-to-publish-your-rust-project-on-homebrew/&quot;&gt;https://federicoterzi.com/blog/how-to-publish-your-rust-project-on-homebrew/&lt;/a&gt;&lt;/p&gt;
    &lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;  &lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;brew tap jihuun/rsdic
  &lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;brew &lt;span class=&quot;nb&quot;&gt;install &lt;/span&gt;rsdic
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;이 문서에서는 2번 방법에대해 알아볼 것이다. 예제로 사용한 Publish 대상은 내가 만든 터미널용 영어사전인 &lt;a href=&quot;https://github.com/jihuun/rsdic&quot;&gt;rsdic&lt;/a&gt;이다. 이 프로젝트는 Rust로 작성되었으며 이 문서에는 Rust 관련 내용이 일부 포함될 수 있다.&lt;/p&gt;

&lt;h1 id=&quot;2-homebrew에-프로젝트-등록하기&quot;&gt;2. Homebrew에 프로젝트 등록하기&lt;/h1&gt;

&lt;h2 id=&quot;21--내-프로젝트-바이너리-생성-및-release&quot;&gt;2.1.  내 프로젝트 바이너리 생성 및 release&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;*.tar.gz&lt;/code&gt; 압축파일 생성&lt;/strong&gt;&lt;br /&gt;
조금 뒤에 살펴볼 homebrew &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Formula&lt;/code&gt;에서 *.tar.gz 로 압축된 바이너리를 필요로한다. 우선 프로젝트를 빌드하여 실행파일을 생성한 뒤에 *.tar.gz로 압축 하면된다. Rust에서는 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cargo build --release&lt;/code&gt; 하면 쉽게 릴리즈 바이너리를 빌드할 수 있다.&lt;/p&gt;

    &lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;  cargo build &lt;span class=&quot;nt&quot;&gt;--release&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;cd &lt;/span&gt;target/release
  &lt;span class=&quot;nb&quot;&gt;tar&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-zcvf&lt;/span&gt; rsdic.tar.gz rsdic
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;sha256 해시 생성&lt;/strong&gt; &lt;br /&gt;
생성한 압축파일에 대한 해시값도 추후 homebrew &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Formula&lt;/code&gt;에 추가해야 한다. 빠르게 검색하기 위한 용도인듯 하다.&lt;/p&gt;

    &lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;  &lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;shasum &lt;span class=&quot;nt&quot;&gt;-a&lt;/span&gt; 256 rsdic.tar.gz
  f65f3265654fd662fd37334122cd2f97f3b85de12969dae81d0484f30cebeceb  rsdic.tar.gz
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;바이너리 링크 생성&lt;/strong&gt;&lt;br /&gt;
Github Release에 &lt;my-project&gt;.tar.gz  바이너리 업로드 하고 아래와 같은 링크를 생성한다.
https://github.com/jihuun/rsdic/releases/download/v0.1.0/rsdic.tar.gz&lt;/my-project&gt;&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;22-homebrew-rsdic-github-repo-생성&quot;&gt;2.2. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;homebrew-rsdic&lt;/code&gt; Github repo 생성&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;homebrew-rsdic&lt;/code&gt; Github repo 생성&lt;/strong&gt; &lt;br /&gt;
Github repository를 하나 생성한다. 저장소 이름은 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;homebrew-&amp;lt;projectname&amp;gt;&lt;/code&gt; 와 같은 방식으로 해야한다. 자세한 이유는 &lt;a href=&quot;https://docs.brew.sh/Taps#repository-naming-conventions-and-assumptions&quot;&gt;Homebrew 네이밍 컨벤션&lt;/a&gt; 참고.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Formula&lt;/code&gt; 작성&lt;/strong&gt; &lt;br /&gt;
Formula는 Ruby 파일인데 딱히 Ruby지식을 필요로 하지는 않는다(나도 모름). 생성한 repository는 아래와 같은 디렉터리 구조를 필요로 한다.&lt;/p&gt;

    &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;  - Formula/
      - &amp;lt;projectname&amp;gt;.rb
  - README.md
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Formula/rsdic.rb 생성&lt;/strong&gt;&lt;br /&gt;
Formula/rsdic.rb 파일을 생성하고 아래의 내용을 추가한다.&lt;/p&gt;

    &lt;div class=&quot;language-rb highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;  &lt;span class=&quot;c1&quot;&gt;# Documentation: https://docs.brew.sh/Formula-Cookbook&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;#                https://rubydoc.brew.sh/Formula&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;# PLEASE REMOVE ALL GENERATED COMMENTS BEFORE SUBMITTING YOUR PULL REQUEST!&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Rsdic&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Formula&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;desc&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;A eng-kor dictionary for the terminal users&quot;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;homepage&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;https://github.com/jihuun/rsdic&quot;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;url&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;https://github.com/jihuun/rsdic/releases/download/v0.1.0/rsdic.tar.gz&quot;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;sha256&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;f65f3265654fd662fd37334122cd2f97f3b85de12969dae81d0484f30cebeceb&quot;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;version&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;0.1.0&quot;&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;install&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;bin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;install&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;rsdic&quot;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;commit  생성하고 push&lt;/strong&gt;&lt;br /&gt;
여기까지 하면 Homebrew를 통해 내 프로젝트를 다운로드 받을 수 있다. 실제 커밋 참고. &lt;a href=&quot;https://github.com/jihuun/homebrew-rsdic/commit/a02f6db3f50a5111ade52e2f31f3c963f97db844&quot;&gt;https://github.com/jihuun/homebrew-rsdic/commit/a02f6db3f50a5111ade52e2f31f3c963f97db844&lt;/a&gt;&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;3-패키지-설치해보기&quot;&gt;3. 패키지 설치해보기&lt;/h1&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;brew tap&lt;/code&gt; 으로 third party repo등록&lt;/strong&gt;&lt;/p&gt;

    &lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;   &lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;brew tap jihuun/rsdic

  &lt;span class=&quot;o&quot;&gt;==&amp;gt;&lt;/span&gt; Tapping jihuun/rsdic
  Cloning into &lt;span class=&quot;s1&quot;&gt;'/usr/local/Homebrew/Library/Taps/jihuun/homebrew-rsdic'&lt;/span&gt;...
  remote: Enumerating objects: 5, &lt;span class=&quot;k&quot;&gt;done&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;.&lt;/span&gt;
  remote: Counting objects: 100% &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;5/5&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;, &lt;span class=&quot;k&quot;&gt;done&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;.&lt;/span&gt;
  remote: Compressing objects: 100% &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;4/4&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;, &lt;span class=&quot;k&quot;&gt;done&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;.&lt;/span&gt;
  remote: Total 5 &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;delta 0&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;, reused 5 &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;delta 0&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;, pack-reused 0
  Unpacking objects: 100% &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;5/5&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;, &lt;span class=&quot;k&quot;&gt;done&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;.&lt;/span&gt;
  Tapped 1 formula &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;29 files, 24.2KB&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Package install&lt;/strong&gt;&lt;/p&gt;

    &lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;   &lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;brew &lt;span class=&quot;nb&quot;&gt;install &lt;/span&gt;rsdic

  &lt;span class=&quot;o&quot;&gt;==&amp;gt;&lt;/span&gt; Installing rsdic from jihuun/rsdic
  &lt;span class=&quot;o&quot;&gt;==&amp;gt;&lt;/span&gt; Downloading https://github.com/jihuun/rsdic/releases/download/v0.1.0/rsdic.tar.gz
  &lt;span class=&quot;o&quot;&gt;==&amp;gt;&lt;/span&gt; Downloading from https://github-releases.githubusercontent.com/364442112/3c316f00-adc4-11eb-88cd-b249eab44c28?X-Amz-Algorithm&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;AWS4-HMAC-SHA256&amp;amp;X-Amz-Crede
&lt;span class=&quot;c&quot;&gt;######################################################################## 100.0%&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;4-추후-릴리즈-자동화&quot;&gt;4. 추후 릴리즈 자동화&lt;/h1&gt;
&lt;p&gt;이제 새 버전 릴리즈시 homebrew-rsdic repo에서 rsdic.rb 파일에 내용을 업데이트 하여 반영하면 된다. Travis 같은 CI/CD 툴로 버전 릴리즈후 brew에 바이너리 업데이트 과정을 자동화 하면 좋을 것 같다.&lt;/p&gt;

</description>
        <pubDate>Sun, 05 Sep 2021 13:00:00 +0000</pubDate>
        <link>https://soopsaram.com/documentudy/2021/09/05/publishing-myproject-to-homebrew/</link>
        <guid isPermaLink="true">https://soopsaram.com/documentudy/2021/09/05/publishing-myproject-to-homebrew/</guid>
        
        <category>UNIX</category>
        
        <category>Shell</category>
        
        <category>Package_Magager</category>
        
        
        <category>UNIX</category>
        
      </item>
    
      <item>
        <title>Bash Auto Completion</title>
        <description>&lt;ul id=&quot;markdown-toc&quot;&gt;
  &lt;li&gt;&lt;a href=&quot;#개요&quot; id=&quot;markdown-toc-개요&quot;&gt;개요&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#목표&quot; id=&quot;markdown-toc-목표&quot;&gt;목표&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#기초&quot; id=&quot;markdown-toc-기초&quot;&gt;기초&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#complete-명령-사용법&quot; id=&quot;markdown-toc-complete-명령-사용법&quot;&gt;complete 명령 사용법&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#comp_cword-와-comp_words로--인자-다루기&quot; id=&quot;markdown-toc-comp_cword-와-comp_words로--인자-다루기&quot;&gt;COMP_CWORD 와 COMP_WORDS로  인자 다루기&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#compreply-전역변수-사용하기&quot; id=&quot;markdown-toc-compreply-전역변수-사용하기&quot;&gt;COMPREPLY 전역변수 사용하기&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#compgen-사용하기&quot; id=&quot;markdown-toc-compgen-사용하기&quot;&gt;compgen 사용하기&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#최종-완성&quot; id=&quot;markdown-toc-최종-완성&quot;&gt;최종 완성&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#references&quot; id=&quot;markdown-toc-references&quot;&gt;References&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;개요&quot;&gt;개요&lt;/h1&gt;
&lt;p&gt;bash 쉘에서 본인이 작성한 스크립트나 프로그램 명령에 argument를 입력할때, TAB으로 자동완성 시켜주는 기능을 만들어보자&lt;/p&gt;

&lt;h1 id=&quot;목표&quot;&gt;목표&lt;/h1&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;cdd 전달인자인 경로 자동완성기능 추가하기&lt;br /&gt;
cdd는 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cd ../../../../&lt;/code&gt; 를 입력하는 대신 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cdd 4&lt;/code&gt;로 손쉽게 뒤로이동 하는 내가 만든 명령도구다.&lt;br /&gt;
&lt;a href=&quot;https://github.com/scriptworld/cdd&quot;&gt;cdd 바로가기: https://github.com/scriptworld/cdd&lt;/a&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cdd 3&lt;/code&gt; + &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;TAB&lt;/code&gt; 을 쳤을때
../../../ 경로의 디렉터리 이름 출력 및 prefix로 디렉터리 자동완성&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;기초&quot;&gt;기초&lt;/h1&gt;
&lt;p&gt;bash completion 을 만들때, 기본적으로 이 두가지 외부 툴(명령)이 함께 사용된다. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;complete&lt;/code&gt; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;compgen&lt;/code&gt;&lt;br /&gt;
그리고 내부 변수 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;COMPREPLY&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;COMP_CWORD&lt;/code&gt;,  &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;COMP_WORDS&lt;/code&gt; 를 활용한다. 이들을 잘 조합한 bash스크립트로 자동완성 기능을 만들 수 있다.&lt;/p&gt;
&lt;blockquote&gt;
  &lt;p&gt;강추 문서 https://mug896.github.io/bash-shell/command_completion.html&lt;/p&gt;
&lt;/blockquote&gt;

&lt;hr /&gt;

&lt;h1 id=&quot;complete-명령-사용법&quot;&gt;complete 명령 사용법&lt;/h1&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;complete -F &amp;lt;함수&amp;gt; &amp;lt;명령&amp;gt;&lt;/code&gt; : 쉘에서&lt;명령&gt; 작성 후 한칸 띄고 `TAB`치면 &lt;함수&gt; 호출된다. 엔터가 아니라 탭을 쳤을때 사용되는 추가 명령 이라고 보면 될것같다.&lt;/함수&gt;&lt;/명령&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;cdd/completion/bash_cdd 생성&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;#!/bin/bash&lt;/span&gt;

_cdd&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'auto completion test'&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;complete&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-F&lt;/span&gt; _cdd cdd 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;심볼릭링크 생성 (MacOS: /usr/local/etc/bash_completion.d)&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt; &lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;ln&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-s&lt;/span&gt; ~/project/cdd/completions/bash_cdd /usr/local/etc/bash_completion.d/cdd
 &lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;source&lt;/span&gt; /usr/local/etc/bash_completion.d/cdd
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;ul&gt;
  &lt;li&gt;그 뒤 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cdd 3&lt;/code&gt; + &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;TAB&lt;/code&gt;하면 작성한 _cdd 함수가 동작하는것을 알 수 있다. 따라서 앞으로 _cdd() 함수에 원하는 동작을 작성하면 된다.&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ cdd 3 auto completion test

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;blockquote&gt;
  &lt;p&gt;그 뒤 엔터를 치면 실제 cdd명령 수행됨 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;go to ./../../../ &lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
  &lt;li&gt;complete &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-o dirnames&lt;/code&gt; 옵션&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;TAB 하면 디렉터리 이름을 자동완성 한다.&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ complete -o dirnames hello 
$ hello [TAB]
aa/ bb/ cc/
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-W &lt;/code&gt; 옵션
자동완성 되기 원하는 옵션이나 문구등을 지정할 수 있다. 띄어쓰기로 구분되고 출력은 자동정렬되어 나온다.&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ complete -W '-a -b -c' hello
$ hello [TAB]
-a -b -c
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-o nospace&lt;/code&gt; 옵션
이름을 자동완성하고 나면 다음 이름을 위해 공백을 띄우게 되는데, 이 옵션은 그걸 방지.&lt;br /&gt;
가령 아래 예시에서 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;hello a&lt;/code&gt;까지 입력하고 TAB을 치면 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;hello aaa=&lt;/code&gt;가 자동완성 되고 커서가 마지막 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;=&lt;/code&gt; 바로뒤에 멈춘다.&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ complete -o nospace -W 'aaa= bbb= ccc=' hello
$ hello aaa=
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;hr /&gt;

&lt;h1 id=&quot;comp_cword-와-comp_words로--인자-다루기&quot;&gt;COMP_CWORD 와 COMP_WORDS로  인자 다루기&lt;/h1&gt;
&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;int main(int argc, char *argv[])&lt;/code&gt; 의 인자와 동일한 역할&lt;/p&gt;
&lt;blockquote&gt;
  &lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;$COMP_CWORD&lt;/code&gt; -&amp;gt; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;int argc&lt;/code&gt;  argument 갯수
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;$COMP_WORDS&lt;/code&gt; -&amp;gt; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;char *argv[]&lt;/code&gt;  모든 argument 문자열 리스트&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;TAB&lt;/code&gt; 을 칠때, cdd명령으로 전달되는 인자 확인&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;#!/bin/bash&lt;/span&gt;

_cdd&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;''&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'argument count : '&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$COMP_CWORD&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'argument words0 : '&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;COMP_WORDS&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[0]&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'argument words1 : '&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;COMP_WORDS&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[1]&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'argument words2 : '&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;COMP_WORDS&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[2]&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;complete&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-F&lt;/span&gt; _cdd cdd 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;cdd 3 
argument count : 2
argument words0 : cdd
argument words1 : 3
argument words2 : 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;blockquote&gt;
  &lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cdd 3 &lt;/code&gt; space를 치고 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;TAB&lt;/code&gt;을 친 경우임. 만약 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cdd 3&lt;/code&gt; 뒤에 space를 치지 않고 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;TAB&lt;/code&gt;을 치면 argument count : 1 이 된다.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;hr /&gt;

&lt;h1 id=&quot;compreply-전역변수-사용하기&quot;&gt;COMPREPLY 전역변수 사용하기&lt;/h1&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;TAB&lt;/code&gt;을 쳤을때 COMPREPLY에 저장된 문자열로 대체된다. 우리가 최종에 값을 저장해야할 변수. bash_completion의 내장 변수.&lt;/p&gt;

&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;#!/bin/bash&lt;/span&gt;

_cdd&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nv&quot;&gt;COMPREPLY&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'aabbcc'&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;complete&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-F&lt;/span&gt; _cdd cdd 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;blockquote&gt;
  &lt;p&gt;그 뒤 cdd + &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;TAB&lt;/code&gt;을 하면 aabbcc가 자동으로 대체된다. 
아무문자를 입력하고 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;TAB&lt;/code&gt;해도 바뀐다. 가령 $ cdd ef&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;TAB&lt;/code&gt; 하면 -&amp;gt; $ cdd aabbcc 로 바뀜&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;따라서 cdd 뒤에 오는 인자에 따라 COMPREPLY 값을 바꿔주면 될듯!&lt;/p&gt;

&lt;p&gt;가령 cdd 3 하고 (스페이스를 치지 않고 바로) &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;TAB&lt;/code&gt;을 치면, 아직 인자를  전달한것이 아니기 때문에 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;$COMP_CWORD&lt;/code&gt; 이 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;2&lt;/code&gt;가 아니라 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;1&lt;/code&gt;이다. 하지만 작성중인 인자 3은 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;${COMP_WORDS[1]}&lt;/code&gt; 에 저장되어 있다.&lt;/p&gt;
&lt;blockquote&gt;
  &lt;p&gt;argument count : 1
argument words0 : cdd
argument words1 : 3&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;이를 이용하면 ${COMP_WORDS[1]가 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;3&lt;/code&gt;인 경우에, COMPREPLY에 “../../../”을 저장하면, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;$ cdd ../../../&lt;/code&gt; 로 대체되게 만들수 있다! 그리고 내부적으로 ../../../ 경로의 실제 디렉터리를 자동완성으로 출력하거나 변환하면 된다. (하지만 현재 cdd 로는 이 기능 수행못함, cdd명령 추가구현 필요)&lt;/p&gt;
&lt;blockquote&gt;
  &lt;p&gt;cdd 내부 동작 수정해야할 내용&lt;/p&gt;
  &lt;ol&gt;
    &lt;li&gt;cdd 인자로 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;숫자&lt;/code&gt;들어오는 경우 -&amp;gt; 기존 cdd내용 수행&lt;/li&gt;
    &lt;li&gt;cdd 인자로 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;경로&lt;/code&gt;들어오는 경우 -&amp;gt; 일반 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cd 경로&lt;/code&gt; 수행
참고: 숫자 문자 구분 방법: https://stackoverflow.com/questions/806906/how-do-i-test-if-a-variable-is-a-number-in-bash/806923
숫자/문자로 구분하는게 아니라 전달받은 인자가 exist한 directory인지 아닌지로 구분이 더 나을듯?&lt;/li&gt;
  &lt;/ol&gt;
&lt;/blockquote&gt;

&lt;h1 id=&quot;compgen-사용하기&quot;&gt;compgen 사용하기&lt;/h1&gt;

&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;compgen&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-W&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'단어1 단어2 ... 단어N'&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;--&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&amp;lt;Prefix&amp;gt;&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;blockquote&gt;
  &lt;p&gt;단어 중에서 &lt;Prefix&gt;가 포함 되어있는 단어만 출력한다.&lt;/Prefix&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;compgen&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-W&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'soopsaram soopnorm great man'&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;--&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'soop'&lt;/span&gt;
soopsaram
soopnorm

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;ls
&lt;/span&gt;complate/   &lt;span class=&quot;nb&quot;&gt;test&lt;/span&gt;/   aa   bb
&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;compgen&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-W&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'$(find . -mindepth 1 -maxdepth 1 -type d)'&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;--&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;./co&quot;&lt;/span&gt;
complate/ 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;blockquote&gt;
  &lt;p&gt;compgen을 find와 조합해서 디렉터리에 존재하는 경로명을 추출할 수 있다.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1 id=&quot;최종-완성&quot;&gt;최종 완성&lt;/h1&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;_cdd&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;o&quot;&gt;[[&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;COMP_CWORD&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-eq&lt;/span&gt; 1 &lt;span class=&quot;o&quot;&gt;]]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return &lt;/span&gt;0
	&lt;span class=&quot;o&quot;&gt;[[&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-z&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;COMP_WORDS&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[1]&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;]]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;COMPREPLY&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;$(&lt;/span&gt;__cdd_prev_path 1&lt;span class=&quot;si&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
	&lt;span class=&quot;o&quot;&gt;[[&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;COMP_WORDS&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[1]&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;~ ^[0-9]+&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]]&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
		&lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;COMPREPLY&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;$(&lt;/span&gt;__cdd_prev_path &lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;COMP_WORDS&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[1]&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;complete&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-o&lt;/span&gt; dirnames &lt;span class=&quot;nt&quot;&gt;-o&lt;/span&gt; nospace &lt;span class=&quot;nt&quot;&gt;-F&lt;/span&gt; _cdd cdd
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/scriptworld/cdd&quot;&gt;cdd 바로가기: https://github.com/scriptworld/cdd&lt;/a&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;h1 id=&quot;references&quot;&gt;References&lt;/h1&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://z-wony.tistory.com/3&quot;&gt;끄적끄적 프로그래밍&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.tuwlab.com/ece/29643&quot;&gt;https://www.tuwlab.com/ece/29643&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.gnu.org/software/bash/manual/html_node/Programmable-Completion-Builtins.html&quot;&gt;https://www.gnu.org/software/bash/manual/html_node/Programmable-Completion-Builtins.html&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;complete 명령 안내(KOR)
    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;https://mug896.github.io/bash-shell/command_completion.html&quot;&gt;https://mug896.github.io/bash-shell/command_completion.html&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Thu, 02 Sep 2021 13:00:00 +0000</pubDate>
        <link>https://soopsaram.com/documentudy/2021/09/02/bash-completion/</link>
        <guid isPermaLink="true">https://soopsaram.com/documentudy/2021/09/02/bash-completion/</guid>
        
        <category>UNIX</category>
        
        <category>Bash</category>
        
        <category>Shell</category>
        
        
        <category>Shell</category>
        
      </item>
    
      <item>
        <title>All That Stream</title>
        <description>&lt;ul id=&quot;markdown-toc&quot;&gt;
  &lt;li&gt;&lt;a href=&quot;#1-what-is-stream&quot; id=&quot;markdown-toc-1-what-is-stream&quot;&gt;1. What is Stream&lt;/a&gt;    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;#11-stream-과-file&quot; id=&quot;markdown-toc-11-stream-과-file&quot;&gt;1.1. Stream 과 File&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#2-standard-stream-표준-스트림&quot; id=&quot;markdown-toc-2-standard-stream-표준-스트림&quot;&gt;2. Standard Stream (표준 스트림)&lt;/a&gt;    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;#21-standard-streams-stdin--stdout-stderr&quot; id=&quot;markdown-toc-21-standard-streams-stdin--stdout-stderr&quot;&gt;2.1. Standard Streams: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;stdin&lt;/code&gt; , &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;stdout&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;stderr&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#22-shell-io-redirect-와-pipe-의-차이&quot; id=&quot;markdown-toc-22-shell-io-redirect-와-pipe-의-차이&quot;&gt;2.2. Shell I/O Redirect 와 PIPE 의 차이&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#23--21-이해하기&quot; id=&quot;markdown-toc-23--21-이해하기&quot;&gt;2.3.  &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;2&amp;gt;&amp;amp;1&lt;/code&gt; 이해하기&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#3-stream-with-c-language&quot; id=&quot;markdown-toc-3-stream-with-c-language&quot;&gt;3. Stream with C language&lt;/a&gt;    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;#fopen-open-의-차이&quot; id=&quot;markdown-toc-fopen-open-의-차이&quot;&gt;fopen(), open() 의 차이&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#file-pointer-vs-file-descripter&quot; id=&quot;markdown-toc-file-pointer-vs-file-descripter&quot;&gt;File Pointer vs File Descripter&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#c-프로그램에서-외부-입출력&quot; id=&quot;markdown-toc-c-프로그램에서-외부-입출력&quot;&gt;C 프로그램에서 외부 입출력&lt;/a&gt;        &lt;ul&gt;
          &lt;li&gt;&lt;a href=&quot;#file-stream에-쓰기-파일&quot; id=&quot;markdown-toc-file-stream에-쓰기-파일&quot;&gt;File Stream에 쓰기 (파일)&lt;/a&gt;&lt;/li&gt;
          &lt;li&gt;&lt;a href=&quot;#file-stream에-쓰기-stdout&quot; id=&quot;markdown-toc-file-stream에-쓰기-stdout&quot;&gt;File Stream에 쓰기 (STDOUT)&lt;/a&gt;&lt;/li&gt;
          &lt;li&gt;&lt;a href=&quot;#file-stream-으로부터-입력받기-stdin&quot; id=&quot;markdown-toc-file-stream-으로부터-입력받기-stdin&quot;&gt;File Stream 으로부터 입력받기 (STDIN)&lt;/a&gt;&lt;/li&gt;
          &lt;li&gt;&lt;a href=&quot;#argument-로부터-입력받기&quot; id=&quot;markdown-toc-argument-로부터-입력받기&quot;&gt;Argument 로부터 입력받기&lt;/a&gt;&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;1-what-is-stream&quot;&gt;1. What is Stream&lt;/h1&gt;

&lt;p&gt;UNIX에서는 모든것이 file이다. Stream을 사용하는것은 UNIX 응용프로그램에서 파일을 읽고 쓰기 위한 일반적인 방법이기 때문에 UNIX 에서 Stream에 대한 이해하는것은 중요하다.&lt;/p&gt;

&lt;h2 id=&quot;11-stream-과-file&quot;&gt;1.1. Stream 과 File&lt;/h2&gt;

&lt;p&gt;우선 file과 stream의 차이에 대해 알아보자. file은 바이트의 연속적인 모음이다(sequences of bytes). stream은 이 bytes를 입출력하기 위한 인터페이스이자 도구이다. stream은 file뿐만 아니라 socket, keyboard, USB port, printer등 sequential data 로 이루어진 데이터를 다루기 위한 common 인터페이스인데, 이 하나의 인터페이스로 모든 소스를 다룰 수 있다. 모든 소스를 단일한 인터페이스로 다룰 수 있기 때문에 동일한 코드로 위에 나열된 장치들을 모두 file로 여기고 읽고 쓸수 있게 된다. 다시말하지만 UNIX에서는 모든것이 file이다.&lt;/p&gt;

&lt;p&gt;stream은 모든 입력 출력을 바이트의 흐름으로 생각하는것이다. 입출력 장치, 하드웨어, 단말에 상관없이 프로그램을 작성할수 있는 독립성을 갖는다. 이를 장치독립성이라고 한다.  그리고 입출력장치와 CPU의 속도차이를 보완하기 위해서 버퍼를 갖는다.&lt;/p&gt;

&lt;p&gt;아직 Stream의 정체가 무엇인지 매우 추상적이고 모호하다. 그렇다면 물리적으로 Stream은 어떻게 표현될까?  C언어에서 Standard Library 함수인 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fopen()&lt;/code&gt; 을 사용해 file을 열어보면, 해당 함수는 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;FILE *&lt;/code&gt; 이라는 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;struct FILE&lt;/code&gt;의 포인터 타입을 리턴한다. 이것이 Stream이다(file stream). &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;FILE *&lt;/code&gt; 포인터는 실제 파일을 가리키는 포인터가 아니다. 파일의 스트림을 가리키는 포인터이다. 그리고 그 스트림에는 파일에 대한 여러가지 정보가 담겨있다.&lt;/p&gt;

&lt;p&gt;stream에는 standard stream이 있는데 이것도 결국 file 에 대한 stream이다.  모두 file descriptor 번호를 가지고 있다. standard stream은 프로그램이 실행되면 OS에서 자동으로 생성한다 (stdin/stdout/stderr). stdin 은 FILE * 타입으로 stdio.h 에 정의되어있다. 자세한 내용은 챕터 2에서 다시 설명한다.&lt;/p&gt;

&lt;p&gt;vi나 nano같은 에디터로 파일을 열면 에디터 프로그램은 해당 파일의 스트림을 생성하고 읽고 쓴다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;references
    &lt;blockquote&gt;
      &lt;p&gt;&lt;a href=&quot;https://stackoverflow.com/questions/38652953/what-does-stream-mean-in-c&quot;&gt;stackoverflow: what-does-stream-mean-in-c&lt;/a&gt;
&lt;a href=&quot;https://youtu.be/iuEdJ9wg8wU&quot;&gt;youtube: 스트림 (널널한 교수의 기초 C언어) ft. C 코딩&lt;/a&gt;&lt;/p&gt;
    &lt;/blockquote&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;2-standard-stream-표준-스트림&quot;&gt;2. Standard Stream (표준 스트림)&lt;/h1&gt;

&lt;h2 id=&quot;21-standard-streams-stdin--stdout-stderr&quot;&gt;2.1. Standard Streams: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;stdin&lt;/code&gt; , &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;stdout&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;stderr&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;프로그래머가 생성하지 않아도 자동으로 생성되는 스트림. 모든 Process에 각각 생성된다. 프로그램이 실행되면 운영체제는 실행되는 프로그램(프로세스)에게 3개의 기본 file descripter 를 할당해준다. 번호는 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;stdin&lt;/code&gt;:0 , &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;stdout&lt;/code&gt;:1 , &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;stderr&lt;/code&gt;:2. 그리고 만약 프로그램이 내부에서 다른 파일을 open() 하게 되면 운영체제는 해당 프로세스에게 3번 file descripter를 할당한다.   &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;stdin&lt;/code&gt; , &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;stdout&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;stderr&lt;/code&gt; 모두 FILE * 타입으로 stdio.h 에 정의되어있다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;the OS gives the address to the standard stream made for a process to it automatically.&lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Standard stream 은 Unix C runtime environment 에서 환경을 제공한다.
Since Unix provided standard streams, the &lt;strong&gt;Unix C runtime environment&lt;/strong&gt; was obliged to support it as well. As a result, most C runtime environments (and C’s descendants), regardless of the operating system, provide equivalent functionality.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;references
    &lt;blockquote&gt;
      &lt;p&gt;&lt;a href=&quot;https://stackoverflow.com/questions/38652953/what-does-stream-mean-in-c&quot;&gt;https://stackoverflow.com/questions/38652953/what-does-stream-mean-in-c&lt;/a&gt;
&lt;a href=&quot;https://blogger.pe.kr/369&quot;&gt;https://blogger.pe.kr/369&lt;/a&gt;&lt;/p&gt;
    &lt;/blockquote&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;22-shell-io-redirect-와-pipe-의-차이&quot;&gt;2.2. Shell I/O Redirect 와 PIPE 의 차이&lt;/h2&gt;

&lt;p&gt;일반적으로 UNIX shell은 stdout으로 전달된 것을 console로 출력해준다. 그런데 shell 에서 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;gt;&lt;/code&gt; 를 사용하면 stdout을 console이 아닌 파일에 출력할 수 있다(stdout to the file). 가령 아래와 같이 ` echo “a b c d”`의 stdout 이 console로 출력되지 않고 tmp.txt 파일로 출력된다. 즉 tmp.txt 파일에 써진다.&lt;/p&gt;

&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt; &lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;a b c d&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; tmp.txt
 &lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;cat &lt;/span&gt;tmp.txt 
a b c d
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;1&amp;gt;&lt;/code&gt; 기본적으로 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;gt;&lt;/code&gt; 와 동일 fd 1번인 stdout 을 stdout으로 redirect. 문법은 file_descriptor &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;gt;&lt;/code&gt; file_name&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;2&amp;gt;&lt;/code&gt; fd 2번인 2번 stream. 즉 stderr를 stdout으로 redirect.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;amp;&amp;gt;&lt;/code&gt; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;amp;&amp;gt;name&lt;/code&gt; 은 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;1&amp;gt;name 2&amp;gt;name&lt;/code&gt; 와 같다. 하지만 name을 두번 open하기 때문에 좋지 않다.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;2&amp;gt;&amp;amp;1&lt;/code&gt; 아래 에서 따로 설명한다. 결론적으로 stderr를 stdout으로 지정하는의미.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;반면 pipe &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;|&lt;/code&gt; 는 stdout을 다른 프로그램의 stdin으로 사용할 수 있다. pipe는 
아래와 같이 실행하면 ` cat tmp.txt&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt; 의 stdout 출력결과가 &lt;/code&gt;wc -w&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt; 의 stdin으로 입력된다. tmp.txt에 a b c d 즉 4개의 word가 있기때문에 &lt;/code&gt;wc -w`하면 4가 출력된다.&lt;/p&gt;

&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt; &lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;cat &lt;/span&gt;tmp.txt | &lt;span class=&quot;nb&quot;&gt;wc&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-w&lt;/span&gt;
4
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;한편 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;lt;&lt;/code&gt; 를 사용하면 keyboard가 아닌 &amp;lt; 다음 입력된 파일로 부터 stdin 입력된다.  순서는 딱히 상관 없음.&lt;/p&gt;

&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt; &lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;wc&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-w&lt;/span&gt; &amp;lt; tmp.txt
4
 &lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt; &amp;lt; tmp.txt &lt;span class=&quot;nb&quot;&gt;wc&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-w&lt;/span&gt;
4
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt; &lt;/th&gt;
      &lt;th&gt;요약&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;gt;&lt;/code&gt; file&lt;/td&gt;
      &lt;td&gt;stdout을 console 이 아닌 file에 출력&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;lt;&lt;/code&gt; file&lt;/td&gt;
      &lt;td&gt;keyboard가 아닌 file로 부터 stdin 입력&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;cmd1 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;|&lt;/code&gt; cmd2&lt;/td&gt;
      &lt;td&gt;한 프로그램(cmd1)의 stdout출력을 다음 프로그램(cmd2)의 stdin 으로 사용&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;ul&gt;
  &lt;li&gt;references
    &lt;blockquote&gt;
      &lt;p&gt;&lt;a href=&quot;https://thoughtbot.com/blog/input-output-redirection-in-the-shell&quot;&gt;https://thoughtbot.com/blog/input-output-redirection-in-the-shell&lt;/a&gt;
&lt;a href=&quot;https://github.com/kennyyu/bootcamp-unix/wiki/stdin,-stdout,-stderr,-and-pipes&quot;&gt;https://github.com/kennyyu/bootcamp-unix/wiki/stdin,-stdout,-stderr,-and-pipes&lt;/a&gt;&lt;/p&gt;
    &lt;/blockquote&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;23--21-이해하기&quot;&gt;2.3.  &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;2&amp;gt;&amp;amp;1&lt;/code&gt; 이해하기&lt;/h2&gt;
&lt;p&gt;Shell 에서 error 메시지를 없앨때 빈번히 사용하는 표현이다. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;2&amp;gt;&lt;/code&gt; 는 stderr을 stdout으로 redirect. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;amp;1&lt;/code&gt; 는 이전에 지정한 stdout이 출력하는 파일을 의미한다고 생각하면 쉽다. 엄밀히 말하면 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;gt;&lt;/code&gt;연산자 대신에 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;gt;&amp;amp;&lt;/code&gt; 를 사용한것이다.  &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;2&amp;gt;&amp;amp;1&lt;/code&gt; 이전에 fd번호 1을 다른 파일로 재지정 했다면, fd번호 2는 재지정한 stdout으로  redirect 한다는 의미.&lt;/p&gt;

&lt;p&gt;예를들어, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cat asdf.txt&lt;/code&gt; 이 아래와 같이 에러메시지를 출력한다고 해보자.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ cat asdf.txt
cat: asdf.txt: No such file or directory
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cat asdf.txt &amp;gt; /dev/null 2&amp;gt;&amp;amp;1&lt;/code&gt; 을 수행하면 먼저 stdout은 /dev/null 로 redirect되고, 그 뒤 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;2&amp;gt;&amp;amp;1&lt;/code&gt;을 통해 stderr는 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;amp;1&lt;/code&gt;로 redirect된다. 즉 stderr도 /dev/null로 redirect되는것이다. 따라서 console에는 아무것도 출력되지 않는다.&lt;/p&gt;

&lt;p&gt;그런데 만약 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cat asdf.txt 2&amp;gt;&amp;amp;1&lt;/code&gt;을 하면 어떻게 될까? stdout 을 따로 지정하지 않았기 때문에 &amp;amp;1 는 default인 console이다. 따라서 2&amp;gt; 즉 stderr 는 그대로 console에 출력된다.&lt;/p&gt;

&lt;p&gt;관련해서 구체적인 문법은 아래와 같다. 두번째 항목을 보면된다. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;gt;&amp;amp;&lt;/code&gt; 연산자의 우측에는 file descriptor 번호가 오는것.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;gt;&lt;/code&gt;
file_descriptor &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;gt;&lt;/code&gt; file_name&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;gt;&amp;amp;&lt;/code&gt; 
file_descriptor &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;gt;&amp;amp;&lt;/code&gt; file_descriptor&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;amp;&amp;gt;&lt;/code&gt;
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;amp;&amp;gt;&lt;/code&gt; file_name&lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;3-stream-with-c-language&quot;&gt;3. Stream with C language&lt;/h1&gt;

&lt;h2 id=&quot;fopen-open-의-차이&quot;&gt;fopen(), open() 의 차이&lt;/h2&gt;
&lt;p&gt;가장 큰 차이는 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fopen()&lt;/code&gt; 은 Standard Library이고, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;open()&lt;/code&gt;은  UNIX System Call이라는 점이다.
 fopen은 내부적으로 open을 사용한다. fopen은 버퍼를 사용하기 때문에 빈번한 system call 을 방지해준다. 잦은 system call은 성능 저하를 발생시킬 수 있다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;struct FILE 구조체&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nl&quot;&gt;c:&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;linenumbers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;wraptext&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;typedef&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;strut&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_iobuf&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cnt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;        &lt;span class=&quot;cm&quot;&gt;/* characters left */&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ptr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;      &lt;span class=&quot;cm&quot;&gt;/* next character position */&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;base&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;     &lt;span class=&quot;cm&quot;&gt;/* location of buffer */&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;       &lt;span class=&quot;cm&quot;&gt;/* mode of file access */&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;         &lt;span class=&quot;cm&quot;&gt;/* file descriptor */&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;FILE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;blockquote&gt;
  &lt;p&gt;from K&amp;amp;R (C Programming Language,  ANSI C, p.176)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2 id=&quot;file-pointer-vs-file-descripter&quot;&gt;File Pointer vs File Descripter&lt;/h2&gt;
&lt;p&gt;file pointer는 파일 스트림 포인터 즉 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;FILE *&lt;/code&gt;를 의미한다. file descripter는 OS레벨에서 해당 파일스트림을 구분하기 위한 번호이다. OS가 생성한다.&lt;/p&gt;

&lt;h2 id=&quot;c-프로그램에서-외부-입출력&quot;&gt;C 프로그램에서 외부 입출력&lt;/h2&gt;

&lt;p&gt;stdin/stdout으로 입출력하거나, argument로 입력받는 방법들 비교.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;fopen()
c프로그램 내에서 파일로부터 파일 스트림 생성.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;file-stream에-쓰기-파일&quot;&gt;File Stream에 쓰기 (파일)&lt;/h3&gt;

&lt;p&gt;fopen을 통해 file.txt 파일의 파일 스트림 포인터 fw를 얻고, fprintf를 통해 write.&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;        &lt;span class=&quot;kt&quot;&gt;FILE&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fp&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fopen&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;file.txt&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;w&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;fprintf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;%s %d&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;hello&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;23&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;fclose&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;컴파일하고 실행하면, file.txt파일내에 값이 쓰여있다.&lt;/p&gt;

&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;cat &lt;/span&gt;file.txt
hello 23
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;file-stream에-쓰기-stdout&quot;&gt;File Stream에 쓰기 (STDOUT)&lt;/h3&gt;

&lt;p&gt;반면 아래와 같이 stdout에 write하면&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;        &lt;span class=&quot;kt&quot;&gt;FILE&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fp&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;stdout&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;fprintf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;%s %d&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;hello stdin&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;혹은&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;        &lt;span class=&quot;n&quot;&gt;fprintf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stdout&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;%s %d&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;hello stdin&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;(사실 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;printf&lt;/code&gt;는 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fprintf(stdout&lt;/code&gt; 과 동일하다. )&lt;/p&gt;

&lt;p&gt;컴파일 후 실행시 stdout, 즉 콘솔화면에 출력된다. 참고로 stdout은 stdio.h에 정의되어있으며, stdout 스트림은 fclose()로 종료하면 안된다.&lt;/p&gt;

&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;./run
hello stdin 100
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;file-stream-으로부터-입력받기-stdin&quot;&gt;File Stream 으로부터 입력받기 (STDIN)&lt;/h3&gt;
&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;        &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;num&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;kt&quot;&gt;FILE&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fp&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;stdin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;fscanf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;%s %d&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;num&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;printf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&amp;gt; %s %d&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;num&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;ol&gt;
      &lt;li&gt;pipe 통해서
        &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt; $ echo &quot;test_string 99&quot; | ./run
&amp;gt; test_string 99
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;        &lt;/div&gt;
      &lt;/li&gt;
    &lt;/ol&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;ol&gt;
      &lt;li&gt;redirect 를 통해 파일로부터
        &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt; $ cat file.txt
hello 23
 $ ./run &amp;lt; file.txt
&amp;gt; hello 23
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;        &lt;/div&gt;
      &lt;/li&gt;
    &lt;/ol&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;argument-로부터-입력받기&quot;&gt;Argument 로부터 입력받기&lt;/h3&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;argc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;argv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[])&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;argc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;printf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;argument [%d]: %s&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;argv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;....&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;컴파일후 생성된 executable파일 run을 실행하면&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ ./run --option hello world
argument [0]: ./run
argument [1]: --option
argument [2]: hello
argument [3]: world
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
</description>
        <pubDate>Tue, 31 Aug 2021 13:00:00 +0000</pubDate>
        <link>https://soopsaram.com/documentudy/2021/08/31/UNIX-understanding-file-stream/</link>
        <guid isPermaLink="true">https://soopsaram.com/documentudy/2021/08/31/UNIX-understanding-file-stream/</guid>
        
        <category>UNIX</category>
        
        <category>C</category>
        
        <category>Shell</category>
        
        
        <category>UNIX</category>
        
      </item>
    
  </channel>
</rss>
