ETS

Tabel ETS dalam memori: tipe set, opsi konkurensi, dan match spec.

Daftar isi

Topik ini memperkenalkan ETS (Erlang Term Storage), fasilitas tabel dalam memori yang disediakan VM: tipe tabelnya, operasi baca-tulisnya, pencarian lewat pola, dan opsi konkurensi yang menentukan siapa yang boleh mengakses. Setelah membaca, tabel suhu kota dapat dibuat, diisi, diperiksa, dan dirapikan dari shell.

Mengapa ETS dibutuhkan#

Data Erlang tidak berubah, sehingga memperbarui satu nilai di dalam struktur besar berarti membangun struktur baru, dan berbagi data antar proses hanya bisa lewat pesan. Untuk data yang dibaca banyak proses sekaligus, penyalinan lewat pesan menjadi mahal, dan di sinilah ETS masuk: tabel ETS hidup di dalam VM, terpisah dari proses mana pun, dan proses lain membacanya langsung tanpa pesan. Tabel itu punya satu batas penting: bila pemilik proses mati, tabel ikut hilang, sehingga ETS adalah cache atau indeks dalam memori, bukan penyimpanan tetap. Akses ETS juga tidak gratis: setiap operasi menyalin nilai dari dan ke heap proses pemanggil, sehingga struktur raksasa sebaiknya tetap diproses dekat pemiliknya.

Tipe tabel dan pembuatan#

Fungsi ets:new/2 membuat tabel dengan dua pilihan utama: tipe isinya dan opsi tambahan. Tipe set bawaan menuntut kunci unik, ordered_set menjaga urutan kunci, bag mengizinkan beberapa baris per kunci, dan duplicate_bag mengizinkan baris identik berulang. Sesi berikut membangun tabel suhu kota:

erlang Membuat, mengisi, dan membaca tabel ETS
Erlang/OTP 29 [erts-17.1.1] [source] [64-bit] [smp:2:2] [ds:2:2:10] [async-threads:1] [jit:ns]

Eshell V17.1.1 (press Ctrl+G to abort, type help(). for help)
1> T = ets:new(suhu, []).
#Ref<0.3653188932.3975282689.227380>
2> ets:insert(T, {surabaya, 31}).
true
3> ets:insert(T, {bandung, 24}).
true
4> ets:lookup(T, bandung).
[{bandung,24}]
5> ets:lookup(T, medan).
[]
6> ets:tab2list(T).
[{surabaya,31},{bandung,24}]

Baris ETS adalah tuple, dan elemen pertamanya adalah kunci. Fungsi lookup/2 mengembalikan list semua baris yang cocok, kosong bila tidak ada, sedangkan tab2list/1 mengambil seluruh isi. Pemilik tabel adalah proses yang memanggil ets:new/2, dan bila proses itu mati, tabel beserta isinya ikut dibersihkan oleh VM.

ordered_set dan kunjungan berurutan#

Tipe ordered_set meletakkan baris menurut urutan kunci, bukan urutan penyisipan, dan menyediakan kunjungan yang berurutan lewat next/2:

erlang Tabel berurut dan kunjungan kunci
1> O = ets:new(urut, [ordered_set]).
#Ref<0.1250643435.2633891842.56790>
2> ets:insert(O, {b, 2}).
true
3> ets:insert(O, {a, 1}).
true
4> ets:insert(O, {c, 3}).
true
5> ets:tab2list(O).
[{a,1},{b,2},{c,3}]
6> ets:next(O, a).
b

Penyisipan dilakukan dalam urutan b, a, c, tetapi tab2list/1 mengembalikannya terurut, dan next/2 membaca kunci berikutnya sehingga penelusuran seluruh tabel dapat dilakukan tanpa menyapu tabel dengan match/2. Urutan kuncinya mengikuti urutan total tipe Erlang, sehingga kunci campuran tetap punya urutan yang pasti. Di balik perbedaan perilaku itu ada biaya: ordered_set menyimpan baris dalam struktur pohon, sementara set memakai tabel hash yang langsung menuju kunci.

Pencarian lewat pola#

Fungsi match/2 mencari baris dengan pola: variabel khusus $1, $2, dan seterusnya mengikat nilai, sedangkan nilai literal wajib sama persis. Nilai kembaliannya adalah list hasil ikatan:

erlang Pencarian berpola dan tabel bernama
7> T = ets:new(suhu, []).
#Ref<0.1250643435.2633891842.56790>
8> ets:insert(T, {bandung, 24}).
true
9> ets:match(T, {'$1', 24}).
[[bandung]]
10> ets:delete(T).
true
11> ets:new(suhu, [named_table, set, public]).
suhu
12> ets:insert(suhu, {malang, 27}).
true
13> ets:lookup(suhu, malang).
[{malang,27}]

Opsi named_table membuat tabel dapat dialamatkan dengan atomnya langsung, sehingga API tidak perlu membawa referensi tabel, sedangkan opsi public membuka akses bagi semua proses. Secara bawaan tabel bersifat protected: hanya pemiliknya yang menulis, tetapi semua proses dalam node boleh membaca, dan kombinasi inilah yang paling sering dipakai karena aman terhadap tabrakan penulisan. Opsi read_concurrency dan write_concurrency menyetel tata letak internal untuk beban yang jelas arahnya, misalnya indeks yang dibaca ratusan proses sekaligus.

Batas dan kesalahan umum#

  • Membaca ETS dari proses yang membutuhkan mutasi bersama. ETS bukan pengganti state proses: pembaruan atomik yang melibatkan beberapa baris tetap lebih aman hidup di dalam gen_server, sedangkan ETS unggul untuk kasus indeks yang dibaca ramai.
  • Memakai ets:match/2 pada tabel besar sebagai query rutin. Pencarian berpola menyapu seluruh tabel, berbeda dengan lookup/2 yang melompat langsung ke kunci. Query yang sering dipakai membutuhkan indeks sekunder berupa tabel kedua.
  • Menganggap tabel bertahan lama. Tabel mengikuti umur proses pembuatnya. Menyimpan data yang harus hidup lebih lama adalah pekerjaan DETS atau Mnesia pada topik DETS dan persistensi.

Ringkasan#

  • ETS adalah tabel dalam memori yang hidup di VM dan dibaca proses lain tanpa pesan, dengan umur mengikuti proses pembuatnya.
  • Tipe set, ordered_set, bag, dan duplicate_bag menentukan aturan kunci dan duplikasi barisnya.
  • lookup/2 melompat langsung ke kunci, sedangkan match/2 menyapu tabel dengan pola dan mengembalikan list ikatan variabel.
  • Opsi named_table, public, dan protected menentukan cara akses, dan read_concurrency dengan write_concurrency menyetel beban yang jelas arahnya.

Referensi#