Saya merancang objek database dalam-memori untuk kasus penggunaan yang sangat spesifik. Ini adalah penulis tunggal, tetapi harus mendukung pembacaan berbarengan yang efisien. Bacaan harus diisolasi. Tidak ada bahasa permintaan, database hanya mendukung:
- dapatkan objek / -s dengan atribut / set atribut (mungkin ada dukungan untuk ekspresi, misalnya
x.count < 5
) - dapatkan atribut objek
Kueri adalah skrip imperatif yang terdiri dari angka arbitrer dari operasi di atas. Ukuran data akan menjadi << memori, jadi semua objek dan indeks pada sebagian besar atribut harus sesuai dengan nyaman tanpa bertukar.
Yang saya butuhkan adalah struktur data untuk indeks atribut objek, yang dapat berupa O (n) pada tulis, tidak mendukung konkurensi tulis, tetapi harus mendukung idealnya O (1) foto (mungkin salin saat menulis) dan akses O (logN). Idealnya itu akan memungkinkan konkurensi tinggi pada bacaan dengan pembagian struktural maksimal antara versi.
Saya sedang melihat CTries , BST bersamaan dan Pohon Rentang bersamaan tapi saya tidak yakin apakah saya benar-benar melihat ke arah yang benar di sini. Struktur di atas memberi banyak perhatian pada kompleksitas sisipan yang tidak saya pedulikan.
Pertanyaannya : apakah ada struktur data yang diketahui yang cocok untuk kasus penggunaan saya di luar kotak?
EDIT : setelah memikirkan beberapa hal lagi, sepertinya pohon BST / Splay yang persisten akan berfungsi. Penulis akan memperbarui salinan 'master' dan pertanyaan akan mendapatkan pohon pada awal eksekusi dan membuangnya setelah selesai. Namun, saya masih tertarik jika ada solusi yang lebih baik.
Jawaban:
Gunakan segala jenis struktur data berbasis pohon yang persisten / tidak berubah (yaitu fungsional). Kuncinya adalah mendapatkan penguncian yang benar, seperti @Raphael tunjukkan dalam komentar.
Yang menyenangkan tentang struktur data berbasis pohon fungsional / persisten, adalah Anda mendapatkan "snapshots" secara gratis. Misalkan Anda menggunakan treap (pohon pencarian biner acak) untuk struktur data Anda. Berikut ini contoh dari salah satu yang ditulis dalam Go: https://github.com/steveyen/gtreap . Penulis menggambarkannya sebagai berikut:
Pada setiap titik waktu, "saat ini" keadaan pohon diwakili oleh pointer ke akar pohon. Insersi tidak bermutasi. Alih-alih sebuah penyisipan membuat versi pohon sebelumnya tetap utuh, membuat node baru untuk path dari root ke titik penyisipan yang benar, dengan pointer kembali ke node dari versi sebelumnya yang dapat dibagikan.O(logn)
Anda menggunakan kunci untuk melindungi pointer ke root. Karena struktur data tidak dapat diubah, pembacaan dapat dilakukan secara bersamaan, dan Anda dapat menyimpan pointer ke snapshot lama. Bacaan adalah:
Meskipun pencarian mungkin memakan waktu cukup lama, Anda hanya memegang kunci saat menyalin pointer, sehingga pencarian dapat terjadi secara bersamaan.
Tulisan adalah:
Dalam versi ini, menulis perlu memegang kunci selama seluruh proses pembuatan versi baru dari pohon. Anda dapat meningkatkan kinerja baca (dengan biaya kadang-kadang gagal menulis transaksi) dengan mengubah penulisan menjadi seperti ini:
Anda mungkin dapat melakukan sedikit lebih baik (menjadikannya "bebas kunci") jika bahasa pemrograman Anda memiliki variabel atom dengan operasi perbandingan-dan-swap atom. (Misalnya dengan menggunakan C ++ 11's
atomic<T*>
.)sumber
Microsoft telah menerbitkan perincian tentang baru mereka di basis data memori, ia memiliki indeks yang tidak memblokir baca saat penulisan sedang dilakukan.
Sebagai contoh:
Lihat http://research.microsoft.com/en-us/projects/main-memory_dbs/ untuk daftar publikasi mereka.
sumber