Saya percaya sesetengah pelajar tidak pernah mendengar tentang koleksi integer, kerana redis hanya menyediakan lima objek berkapsul kepada dunia luar! Sebelum ini, kami menganalisis tiga struktur data redis: Senarai, Hash dan Zset daripada struktur dalaman redis. Hari ini kita akan menganalisis bagaimana struktur data yang ditetapkan disimpan secara dalaman.
Dalam src/t_set.c kami menemui sekeping kod sedemikian
Daripada ini kita boleh tahu bahawa dalam set Terdiri daripada dua struktur data: inset jadual hash. Mengenai struktur dalaman redis yang lain, saya secara khusus memperkenalkannya dalam [lajur redis]. Hashtable bukan protagonis kami hari ini, kami mula-mula menganalisis intset, biasanya dikenali sebagai set integer.
Seperti yang dapat kita lihat daripada gambar di atas, saya membina dua koleksi set yang dipanggil [commonset] dan [cs]. Yang pertama menyimpan rentetan dan yang terakhir menyimpan nombor.
Kami melihat struktur data asas kedua-dua koleksi melalui kunci pengekodan objek dan mendapati bahawa satu adalah jadual cincang dan satu lagi adalah inset. Ini juga mengesahkan penerangan kami tentang struktur asas set di atas.
Lima jenis utama yang disediakan secara luaran dalam redis sebenarnya merupakan objek abstrak redis yang dipanggil redisobject. Struktur data dalaman redis kami dipetakan secara dalaman
Struktur data dalaman kumpulan commonset dan cs boleh difahami seperti ini
anda hanya boleh berfikir bahawa selagi ia adalah nombor, ia akan disimpan menggunakan struktur intset. . Ini sebenarnya tidak berlaku.
perlu memenuhi dua syarat berikut pada masa yang sama:
Gambar menunjukkannya dengan sangat jelas Pengekodan dalam inset mempunyai tiga nilai, masing-masing mewakili jenis data storan kandungan. Seseorang di sini mungkin mempunyai soalan. Bukankah jenis kandungan hanya int8_t? Mengapa anda memerlukan pengekodan? Penjejakan kod sumber di sini tidak ada kaitan dengan int8_t. Dan jenis data lalai ialah int16_t. Tidak perlu menerangkan terlalu banyak tentang panjang di sini. Ingat bahawa bilangan elemen kandungan tidak mewakili panjang tatasusunan kandungan!
Pelajar yang mengetahui intset semua tahu bahawa tiga julat nilai pengekodan melibatkan operasi naik taraf! Sebelum bercakap tentang peningkatan, mari kita fahami dahulu cara julat nilai int dalam C dan C ditakrifkan
Julat nilai int8_t ialah [-128,127]. Sama seperti bait dalam Java, 1 bait ialah 8 bit. Julat nilainya ialah
[-2^{7} sim 2^{7}-1 \
, iaitu \
-128 sim 127
]
sadd juejin -123 sadd juejin -6 sadd juejin 12 sadd juejin 56 sadd juejin 321
juejin Kunci di dalam adalah inset.
Di atas kami menambah 5 elemen dan panjang lima elemen ini semuanya dalam lingkungan 16! Jadi pengekodan intset semasa=INTSET_ENC_INT16. -123 menduduki 16 kedudukan teratas dalam kandungan.
Jadi panjang lima elemen semasa dalam kandungan ialah 16*5=80;
Perhatikan bahawa apabila set menyimpan data jenis int, ia disimpan secara dalaman mengikut tertib dari kecil ke besar.
Saya tidak tahu sama ada anda telah mempertimbangkan masalah di atas, atau jika anda pernah menghadapinya! Intset lalai kepada int16 bit, sama seperti lima elemen yang kami tambahkan di atas. Pada masa ini, elemen keenam yang kami tambah ialah 65535 (32 bit). Kemudian apakah yang akan dilakukan intset pada masa ini apabila panjang 16 bit tidak mencukupi untuk penyimpanan?
Selain itu, apabila kita menambah elemen ke-6 dan memadamkan 65535, adakah strukturnya akan sama seperti sebelum menambahkannya? Mari kita lihat dua soalan ini di bawah! ! !
Mula-mula, mari kita lihat soalan pertama. Ternyata semua lima elemen adalah 16 bit, dan 65535 yang ditambahkan pada masa ini adalah 32 bit panjangnya. Jadi bolehkah kita menambah 32 bit terus ke 65535?
Jawapannya pastinya tidak Pertama sekali, penambahan secara langsung tidak dapat menjamin susunan elemen tatasusunan! Kedua, jika lima yang pertama ialah 16 bit setiap satu dan yang keenam ialah 32 bit, maka tiada medan tambahan dalam struktur inset untuk ditanda. Dalam erti kata lain, adalah mustahil untuk menilai sama ada 16-bit atau 32-bit harus dihuraikan semasa penghuraian
Untuk memudahkan penghuraian, redis akan menaik taraf keseluruhan kandungan apabila panjang tinggi ditambah. Ia bermaksud untuk mengembangkan keseluruhan kandungan dahulu, dan kemudian mengisi semula data
dan menambah 65535
Mula-mula, pengembangan boleh ditentukan berdasarkan panjang Bilangan elemen ialah 6, dan setiap penghunian ialah 32, jadi panjang kandungan ialah 32*6=192. Pada masa ini, 80 bit kandungan pertama kekal tidak berubah
Data lama dialihkan
Selepas ruang yang mencukupi dibuka ke atas, kita boleh Data lama dialihkan Di sini kita mula bergerak dari hujung tatasusunan asal Sebelum bergerak, kita perlu menjelaskan kedudukan pengisihan dalam tatasusunan baharu.
Pada masa ini, kami mula-mula membandingkan 321 untuk menentukan kedudukannya berada di tempat kelima dalam tatasusunan baharu, kemudian ia akan menduduki julat 128~159 dalam kandungan baharu.
Akhirnya 5 elemen pertama akan dialihkan.
Akhir sekali isi elemen yang baru ditambah. Apabila peningkatan berlaku, ia mestilah kerana panjang elemen baharu lebih besar daripada panjang asal. Maka nilainya mestilah pada kedua-dua hujung tatasusunan baharu. Nombor negatif berada di hujung kiri, nombor positif berada di hujung kanan
Kemudian terdapat masalah kedua apabila 65535 yang baru ditambah dipadamkan . Apakah yang perlu dilakukan oleh redis pada masa ini, panjang elemen sebenar ialah 16 bit, tetapi pengekodan ialah 32 bit. Pada pendapat saya, ia harus diturunkan!
Tetapi malangnya redis tidak wujud, jadi sila fikirkan mengapa ia tidak wujud? Jika anda diminta untuk melaksanakannya, bagaimana anda akan melaksanakannya
Apabila elemen tambahan melebihi panjang semasa, kita boleh mengetahui dengan mudah bahawa operasi naik taraf diperlukan di kali ini, tetapi apabila kami memadamkan sekeping data, kami Bagaimana untuk menilai sama ada penurunan taraf diperlukan adalah sangat sukar. . Ini adalah salah satu sebab mengapa penurunan taraf tidak dilakukan
Anda mungkin mengatakan bahawa melintasinya semula akan berada dalam ingatan dengan cepat, jadi pernahkah anda terfikir untuk menaik taraf dan menurunkan taraf bolak-balik jika anda menghadapi situasi peningkatan selepas menurunkan taraf? Ini mengurangkan prestasi program kami. Kami tahu bahawa peningkatan adalah perlu, jadi strategi menurunkan redis di sini adalah untuk mengabaikannya
Cadangan tutorial yang berkaitan: Tutorial redis
Atas ialah kandungan terperinci Set integer redis tidak boleh diturunkan taraf? kenapa?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!