-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
『Goならわかるシステムプログラミング 第2版』を読んだ を書いた #166
Conversation
# 第2章 低レベルアクセスへの入口1:io.Writer | ||
- `io.Writer`はOSが持つファイルのシステムコールの相似形 | ||
- OSでは、システムコールを**ファイルディスクリプタ**と呼ばれるものに対して呼ぶ。 | ||
- ファイルディスクリプタ(file descriptor)は一種の識別子(数値)で、この数値を指定してシステムコールを呼び出すと、数値に対応するモノにアクセスできる。 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🚫 [textlint] <eslint.rules.ja-technical-writing/no-doubled-joshi> reported by reviewdog 🐶
一文に二回以上利用されている助詞 "に" がみつかりました。
次の助詞が連続しているため、文を読みにくくしています。
- "に"
- "に"
同じ助詞を連続して利用しない、文の中で順番を入れ替える、文を分割するなどを検討してください。
(ja-technical-writing/no-doubled-joshi)
- `0`が標準入力、`1`が標準出力、`2`が標準エラー出力。 | ||
- 以降はそのプロセスでファイルをオープンしたりソケットをオープンしたりするたびに1ずつ大きな数値が割り当てられていく。 | ||
|
||
複数のファイル`f1`, `f2`を`os.Create()`する処理をデバッガーで追ってみたところ、それぞれファイルディスクリプタの値が`3`, `4`[^2]となっておりファイルディスクリプタの値が`3`からインクリメントされる様子を確認できた。 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🚫 [textlint] <eslint.rules.ja-technical-writing/sentence-length> reported by reviewdog 🐶
Line 33 sentence length(109) exceeds the maximum sentence length of 100.
Over 9 characters. (ja-technical-writing/sentence-length)
|
||
# 第3章 低レベルアクセスへの入口1:io.Reader | ||
## エンディアン変換 | ||
- リトルエンディアンでは、10000という数値(`0x2710`)をメモリに格納するときに下位バイトから順に格納する。 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🚫 [textlint] <eslint.rules.ja-technical-writing/no-doubled-joshi> reported by reviewdog 🐶
一文に二回以上利用されている助詞 "に" がみつかりました。
次の助詞が連続しているため、文を読みにくくしています。
- "に"
- "に"
同じ助詞を連続して利用しない、文の中で順番を入れ替える、文を分割するなどを検討してください。
(ja-technical-writing/no-doubled-joshi)
## CPUの動作モード | ||
- OSの仕事は以下の2つ | ||
- 各種資源(メモリ、CPU時間、ストレージなど)の管理 | ||
- 外部入出力機能の提供(ネットワーク、ファイル読み書き、プロセス間通信) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🚫 [textlint] <eslint.rules.ja-technical-writing/max-kanji-continuous-len> reported by reviewdog 🐶
漢字が7つ以上連続しています: 外部入出力機能 (ja-technical-writing/max-kanji-continuous-len)
+++ exited with 0 +++ | ||
``` | ||
|
||
- `openat(AT_FDCWD, "test_file.txt", O_RDWR|O_CREAT|O_TRUNC|O_CLOEXEC, 0666) = 3`の部分でファイルが作成され、ファイルディスクリプタに`3`が割り当ている |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🚫 [textlint] <eslint.rules.ja-technical-writing/sentence-length> reported by reviewdog 🐶
Line 123 sentence length(111) exceeds the maximum sentence length of 100.
Over 11 characters. (ja-technical-writing/sentence-length)
- どんなソケット通信も基本となる構成は次のような形態 | ||
- サーバー:ソケットを開いて待ち受ける | ||
- クライアント:開いているソケットに接続し、通信を行う | ||
- GoではTCP通信が確立されると、送信側、受信側の両方に相手との通信を行う`net.Conn`インタフェースを満たすオブジェクトが渡ってくる |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🚫 [textlint] <eslint.rules.ja-technical-writing/ja-no-redundant-expression> reported by reviewdog 🐶
【dict5】 "通信を行う"は冗長な表現です。"通信する"など簡潔な表現にすると文章が明瞭になります。
解説: https://github.com/textlint-ja/textlint-rule-ja-no-redundant-expression#dict5 (ja-technical-writing/ja-no-redundant-expression)
|
||
## Goに組み込まれているTCPの機能(`net.Conn`)だけを使ってHTTPによる通信を実現する | ||
- `net.Conn`だけを使ってTCPソケットの初期化や通信の確立などの普段なら`net/http`がやってくれている部分を実装した。 | ||
- `http.ListenAndServe()`のコードを読んでみたら、[golang/go/src/net/http/server.go#L3258](https://github.com/golang/go/blob/c83b1a7013784098c2061ae7be832b2ab7241424/src/net/http/server.go#L3258)で本書のハンズオンと同じようにTCPソケットの初期化を行っていることを確認できた。 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🚫 [textlint] <eslint.rules.ja-technical-writing/sentence-length> reported by reviewdog 🐶
Line 147 sentence length(112) exceeds the maximum sentence length of 100.
Over 12 characters. (ja-technical-writing/sentence-length)
### フロー処理 | ||
- 受信側がリソースを用意できていない状態で送信リクエストが集中して通信内容が失われるのを防ぐための仕組みを**ウィンドウ制御**という。 | ||
- 具体的には、受信用のバッファ(ウィンドウ)をあらかじめ決めておき送信側ではそのサイズまでは受信側からの受信確認を待たずにデータを送信できる。 | ||
- 受信側のデータの読み込みが間に合わない場合には、受信できるウィンドウサイズを受信側から送信側に伝えて通信量を制御することができる。これを**フロー制御**という。 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🚫 [textlint] <eslint.rules.ja-technical-writing/ja-no-redundant-expression> reported by reviewdog 🐶
【dict2】 "することができる。"は冗長な表現です。"することが"を省き簡潔な表現にすると文章が明瞭になります。
解説: https://github.com/textlint-ja/textlint-rule-ja-no-redundant-expression#dict2 (ja-technical-writing/ja-no-redundant-expression)
- UDPではデータの分割などはアプリケーションで面倒を見る必要がある。 | ||
|
||
### 輻輳制御とフェアネス | ||
- **輻輳制御**とは、ネットワークの輻輳(渋滞)を避けるように流量を調整し、そのネットワークの最大効率で通信できるようにするとともに、複数の通信をお互いに**フェアに行う**ための仕組み。 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🚫 [textlint] <eslint.rules.ja-technical-writing/no-doubled-joshi> reported by reviewdog 🐶
一文に二回以上利用されている助詞 "に" がみつかりました。
次の助詞が連続しているため、文を読みにくくしています。
- "に"
- "に"
同じ助詞を連続して利用しない、文の中で順番を入れ替える、文を分割するなどを検討してください。
(ja-technical-writing/no-doubled-joshi)
### 輻輳制御とフェアネス | ||
- **輻輳制御**とは、ネットワークの輻輳(渋滞)を避けるように流量を調整し、そのネットワークの最大効率で通信できるようにするとともに、複数の通信をお互いに**フェアに行う**ための仕組み。 | ||
- TCPには輻輳制御が備わっており、そのアルゴリズムにはさまざまな種類がある。 | ||
- UDPにはTCPのような輻輳制御の仕組みはなく、流量の制御はUDPを利用する各プログラムに委ねられている。そのため、UDPとTCPを利用するアプリケーションがそれぞれあって、UDPを利用するアプリケーションでフェアネスが考慮されていない場合には、**両方の通信が重なった時に遠慮する機能が組み込まれたTCPの通信速度だけが極端に落ち込む**こともある。 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🚫 [textlint] <eslint.rules.ja-technical-writing/sentence-length> reported by reviewdog 🐶
Line 196 sentence length(119) exceeds the maximum sentence length of 100.
Over 19 characters. (ja-technical-writing/sentence-length)
### フロー処理 | ||
- 受信側がリソースを用意できていない状態で送信リクエストが集中して通信内容が失われるのを防ぐための仕組みを**ウィンドウ制御**という。 | ||
- 具体的には、受信用のバッファ(ウィンドウ)をあらかじめ決めておき送信側ではそのサイズまでは受信側からの受信確認を待たずにデータを送信できる。 | ||
- 受信側のデータの読み込みが間に合わない場合には、受信できるウィンドウサイズを受信側から送信側に伝えて通信量を制御することができる。これを**フロー制御**という。 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[textlint-fix] reported by reviewdog 🐶
- 受信側のデータの読み込みが間に合わない場合には、受信できるウィンドウサイズを受信側から送信側に伝えて通信量を制御することができる。これを**フロー制御**という。 | |
- 受信側のデータの読み込みが間に合わない場合には、受信できるウィンドウサイズを受信側から送信側に伝えて通信量を制御できる。これを**フロー制御**という。 |
6735e2d
to
4cbb204
Compare
- Unixドメインソケットには、TCP型(ストリーム型)とUDP型(データグラム型)の両方の使い方ができる。 | ||
|
||
## Unixドメインソケットの基本 | ||
- TCPとUDPによるソケット通信が外部のネットワークにつながるインターフェースに接続するのに対し、Unixドメインソケットはカーネル内部で完結する高速なネットワークインターフェースを作成する。 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🚫 [textlint] <eslint.rules.ja-technical-writing/no-doubled-joshi> reported by reviewdog 🐶
一文に二回以上利用されている助詞 "に" がみつかりました。
次の助詞が連続しているため、文を読みにくくしています。
- "に"
- "に"
同じ助詞を連続して利用しない、文の中で順番を入れ替える、文を分割するなどを検討してください。
(ja-technical-writing/no-doubled-joshi)
- Unixドメインソケットを開くには、ファイルシステムのパスを指定する。サーバープロセスを起動するとファイルシステム上の指定したパスにソケットファイルが作成される。 | ||
- Unixドメインソケットで作成されるのはソケットファイルと呼ばれる特殊なファイルであり、通常のファイルのような実体を持たない。あくまでもプロセス間の高速な通信としてファイルというインターフェースを利用するだけ。 | ||
|
||
以下はソケットファイルが作成されている様子。ソケットファイルは先頭がsで始まる。 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🚫 [textlint] <eslint.rules.ja-technical-writing/ja-unnatural-alphabet> reported by reviewdog 🐶
不自然なアルファベットがあります: s (ja-technical-writing/ja-unnatural-alphabet)
4cbb204
to
01ec1af
Compare
## ファイルのメモリへのマッピング(`syscall.Mmap()`) | ||
`syscall.Mmap()`を使うことでファイルの中身をそのままメモリ上に展開したり、メモリ上で書き換えた内容をそのままファイルに書き込むことができる。 | ||
|
||
[edsrzf/mmap-go](https://github.com/edsrzf/mmap-go)では`mmap.Map()`を使うことでファイルをメモリに展開することができる。`mmap.Map()`は次のようなシグネチャを持つ。 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🚫 [textlint] <eslint.rules.ja-technical-writing/ja-no-redundant-expression> reported by reviewdog 🐶
【dict2】 "することができる。"は冗長な表現です。"することが"を省き簡潔な表現にすると文章が明瞭になります。
解説: https://github.com/textlint-ja/textlint-rule-ja-no-redundant-expression#dict2 (ja-technical-writing/ja-no-redundant-expression)
func Map(f *os.File, prot, flags int) (MMap, error) | ||
``` | ||
|
||
二つ目の引数に次のような値を指定することでメモリ領域に対して許可する操作を設定することができる。 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🚫 [textlint] <eslint.rules.ja-technical-writing/arabic-kanji-numbers> reported by reviewdog 🐶
二つ => 2つ
数量を表現し、数を数えられるものは算用数字を使用します。任意の数に置き換えても通用する語句がこれに該当します。 (ja-technical-writing/arabic-kanji-numbers)
func Map(f *os.File, prot, flags int) (MMap, error) | ||
``` | ||
|
||
二つ目の引数に次のような値を指定することでメモリ領域に対して許可する操作を設定することができる。 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🚫 [textlint] <eslint.rules.ja-technical-writing/ja-no-redundant-expression> reported by reviewdog 🐶
【dict2】 "することができる。"は冗長な表現です。"することが"を省き簡潔な表現にすると文章が明瞭になります。
解説: https://github.com/textlint-ja/textlint-rule-ja-no-redundant-expression#dict2 (ja-technical-writing/ja-no-redundant-expression)
- `mmap.EXEC`: 実行可能にする | ||
- `mmap.COPY`: コピーオンライト | ||
|
||
コピーオンライトが指定されると、複数のプロセスが同じファイルをマッピングしているときに、カーネル上は一つ分のみメモリ領域が使用され、それ以上のメモリを消費しない。 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🚫 [textlint] <eslint.rules.ja-technical-writing/arabic-kanji-numbers> reported by reviewdog 🐶
一つ => 1つ
数量を表現し、数を数えられるものは算用数字を使用します。任意の数に置き換えても通用する語句がこれに該当します。 (ja-technical-writing/arabic-kanji-numbers)
|
||
コピーオンライトが指定されると、複数のプロセスが同じファイルをマッピングしているときに、カーネル上は一つ分のみメモリ領域が使用され、それ以上のメモリを消費しない。 | ||
|
||
しかし、その領域内でメモリ書き換えが発生すると、その領域がまるごとコピーされる。このようにすることでメモリ消費量をうまく節約することができる。 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🚫 [textlint] <eslint.rules.ja-technical-writing/ja-no-redundant-expression> reported by reviewdog 🐶
【dict2】 "することができる。"は冗長な表現です。"することが"を省き簡潔な表現にすると文章が明瞭になります。
解説: https://github.com/textlint-ja/textlint-rule-ja-no-redundant-expression#dict2 (ja-technical-writing/ja-no-redundant-expression)
## ファイルのメモリへのマッピング(`syscall.Mmap()`) | ||
`syscall.Mmap()`を使うことでファイルの中身をそのままメモリ上に展開したり、メモリ上で書き換えた内容をそのままファイルに書き込むことができる。 | ||
|
||
[edsrzf/mmap-go](https://github.com/edsrzf/mmap-go)では`mmap.Map()`を使うことでファイルをメモリに展開することができる。`mmap.Map()`は次のようなシグネチャを持つ。 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[textlint-fix] reported by reviewdog 🐶
[edsrzf/mmap-go](https://github.com/edsrzf/mmap-go)では`mmap.Map()`を使うことでファイルをメモリに展開することができる。`mmap.Map()`は次のようなシグネチャを持つ。 | |
[edsrzf/mmap-go](https://github.com/edsrzf/mmap-go)では`mmap.Map()`を使うことでファイルをメモリに展開できる。`mmap.Map()`は次のようなシグネチャを持つ。 |
func Map(f *os.File, prot, flags int) (MMap, error) | ||
``` | ||
|
||
二つ目の引数に次のような値を指定することでメモリ領域に対して許可する操作を設定することができる。 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[textlint-fix] reported by reviewdog 🐶
二つ目の引数に次のような値を指定することでメモリ領域に対して許可する操作を設定することができる。 | |
2つ目の引数に次のような値を指定することでメモリ領域に対して許可する操作を設定できる。 |
- `mmap.EXEC`: 実行可能にする | ||
- `mmap.COPY`: コピーオンライト | ||
|
||
コピーオンライトが指定されると、複数のプロセスが同じファイルをマッピングしているときに、カーネル上は一つ分のみメモリ領域が使用され、それ以上のメモリを消費しない。 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[textlint-fix] reported by reviewdog 🐶
コピーオンライトが指定されると、複数のプロセスが同じファイルをマッピングしているときに、カーネル上は一つ分のみメモリ領域が使用され、それ以上のメモリを消費しない。 | |
コピーオンライトが指定されると、複数のプロセスが同じファイルをマッピングしているときに、カーネル上は1つ分のみメモリ領域が使用され、それ以上のメモリを消費しない。 |
|
||
コピーオンライトが指定されると、複数のプロセスが同じファイルをマッピングしているときに、カーネル上は一つ分のみメモリ領域が使用され、それ以上のメモリを消費しない。 | ||
|
||
しかし、その領域内でメモリ書き換えが発生すると、その領域がまるごとコピーされる。このようにすることでメモリ消費量をうまく節約することができる。 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[textlint-fix] reported by reviewdog 🐶
しかし、その領域内でメモリ書き換えが発生すると、その領域がまるごとコピーされる。このようにすることでメモリ消費量をうまく節約することができる。 | |
しかし、その領域内でメモリ書き換えが発生すると、その領域がまるごとコピーされる。このようにすることでメモリ消費量をうまく節約できる。 |
1. プロセスの起動 | ||
|
||
|
||
「11.5.3 コマンドと引数の前処理」で紹介されていたが、`$(which nvim)`と同様に`` `which nvim` ``でもコマンドの実行結果を変数に代入することができるのは知らなかった。 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🚫 [textlint] <eslint.rules.ja-spacing/ja-space-between-half-and-full-width> reported by reviewdog 🐶
原則として、全角文字と半角文字の間にスペースを入れません。 (ja-spacing/ja-space-between-half-and-full-width)
1. プロセスの起動 | ||
|
||
|
||
「11.5.3 コマンドと引数の前処理」で紹介されていたが、`$(which nvim)`と同様に`` `which nvim` ``でもコマンドの実行結果を変数に代入することができるのは知らなかった。 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🚫 [textlint] <eslint.rules.ja-technical-writing/ja-no-redundant-expression> reported by reviewdog 🐶
【dict2】 "することができるの"は冗長な表現です。"することが"を省き簡潔な表現にすると文章が明瞭になります。
解説: https://github.com/textlint-ja/textlint-rule-ja-no-redundant-expression#dict2 (ja-technical-writing/ja-no-redundant-expression)
1. プロセスの起動 | ||
|
||
|
||
「11.5.3 コマンドと引数の前処理」で紹介されていたが、`$(which nvim)`と同様に`` `which nvim` ``でもコマンドの実行結果を変数に代入することができるのは知らなかった。 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[textlint-fix] reported by reviewdog 🐶
「11.5.3 コマンドと引数の前処理」で紹介されていたが、`$(which nvim)`と同様に`` `which nvim` ``でもコマンドの実行結果を変数に代入することができるのは知らなかった。 | |
「11.5.3コマンドと引数の前処理」で紹介されていたが、`$(which nvim)`と同様に`` `which nvim` ``でもコマンドの実行結果を変数に代入できるのは知らなかった。 |
8803fa8
to
74f732f
Compare
test |
9ecf556
to
5079d16
Compare
5079d16
to
5a117ce
Compare
次はこのあたりの書籍を読んでみようとおもう。 | ||
- コンピュータシステムの理論と実装 | ||
- Go言語による並行処理 | ||
- つくって、壊して、直して学ぶ Kubernetes入門 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🚫 [textlint] <eslint.rules.ja-spacing/ja-space-between-half-and-full-width> reported by reviewdog 🐶
原則として、全角文字と半角文字の間にスペースを入れません。 (ja-spacing/ja-space-between-half-and-full-width)
- Go言語による並行処理 | ||
- つくって、壊して、直して学ぶ Kubernetes入門 | ||
- Linuxで動かしながら学ぶTCP/IPネットワーク入門 | ||
- 体系的に学ぶ 安全なWebアプリケーションの作り方 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🚫 [textlint] <eslint.rules.ja-spacing/ja-no-space-between-full-width> reported by reviewdog 🐶
原則として、全角文字どうしの間にスペースを入れません。 (ja-spacing/ja-no-space-between-full-width)
- Linuxで動かしながら学ぶTCP/IPネットワーク入門 | ||
- 体系的に学ぶ 安全なWebアプリケーションの作り方 | ||
|
||
あるいは、 [Webサーバーアーキテクチャ進化論2023 - blog.ojisan.io](https://blog.ojisan.io/server-architecture-2023/#%E3%83%97%E3%83%AD%E3%82%BB%E3%82%B9-vs-%E3%82%B9%E3%83%AC%E3%83%83%E3%83%89)を参考に学習ロードマップを立ててみるのもいいかもしれない。 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🚫 [textlint] <eslint.rules.ja-technical-writing/ja-no-weak-phrase> reported by reviewdog 🐶
弱い表現: "かも" が使われています。 (ja-technical-writing/ja-no-weak-phrase)
次はこのあたりの書籍を読んでみようとおもう。 | ||
- コンピュータシステムの理論と実装 | ||
- Go言語による並行処理 | ||
- つくって、壊して、直して学ぶ Kubernetes入門 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[textlint-fix] reported by reviewdog 🐶
- つくって、壊して、直して学ぶ Kubernetes入門 | |
- つくって、壊して、直して学ぶKubernetes入門 |
- Go言語による並行処理 | ||
- つくって、壊して、直して学ぶ Kubernetes入門 | ||
- Linuxで動かしながら学ぶTCP/IPネットワーク入門 | ||
- 体系的に学ぶ 安全なWebアプリケーションの作り方 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[textlint-fix] reported by reviewdog 🐶
- 体系的に学ぶ 安全なWebアプリケーションの作り方 | |
- 体系的に学ぶ安全なWebアプリケーションの作り方 |
TODO