2019 අගභාගයේදී, Mail.ru Cloud iOS කණ්ඩායම තුළ දීර්-කාලයක් තිස්සේ බලා සිටි සිදුවීමක් සිදු විය. යෙදුම් තත්ත්වය අඛණ්ඩව ගබඩා කිරීම සඳහා වන ප්රධාන දත්ත සමුදාය ජංගම ලෝකය සඳහා ඉතා ආගන්තුක වී ඇත
අන්තර්ගතය
ක්රියාත්මක කිරීම සඳහා පෙළඹවීම LMDB ස්ථානගත කිරීම LMDB කුළුණු තුනක්
3.1.තල්මසා #1. මතක සිතියම්ගත ගොනු
3.2.තල්මසා #2. B+-ගස
3.3.තල්මසා #3. පිටපත-මත-ලියන්න යතුරු අගය API මත දත්ත සැලැස්මක් සැලසුම් කිරීම
4.1.මූලික වියුක්තයන්
4.2.මේස ආකෘති නිර්මාණය
4.3.වගු අතර ආකෘති සම්බන්ධතා
1. ක්රියාත්මක කිරීම සඳහා අභිප්රේරණය
2015 වසරේ එක් වසරක, අපගේ යෙදුමේ අතුරු මුහුණත කොපමණ වාරයක් ප්රමාද වේද යන්න මැනීමට අපි ගැටලුවක් ගත්තෙමු. අපි මෙය කළේ හේතුවක් ඇතුවයි. සමහර විට යෙදුම පරිශීලක ක්රියාවන්ට ප්රතිචාර දැක්වීම නවත්වන බවට අපට නිතර නිතර පැමිණිලි ලැබී ඇත: බොත්තම් එබිය නොහැක, ලැයිස්තු අනුචලනය නොකරයි, යනාදිය. මිනුම් යාන්ත්ර විද්යාව ගැන
මිනුම් ප්රතිඵල අපට සීතල වැස්සක් බවට පත් විය. වෙනත් ඕනෑම දෙයකට වඩා කැටි කිරීම නිසා ඇති වන ගැටළු බොහොමයක් ඇති බව පෙනී ගියේය. මෙම කාරණය අවබෝධ කර ගැනීමට පෙර ගුණාත්මක බවේ ප්රධාන තාක්ෂණික දර්ශකය බිඳ වැටීමෙන් තොර නම්, පසුව අවධානය යොමු කිරීමෙන් පසුව
ඉදි කර ඇත
පද්ධති සංවිධානයේ නළු ආකෘතිය උපකල්පනය කරන්නේ බහු නූල් කිරීම එහි දෙවන සාරය බවට පත්වන බවයි. එහි ඇති ආදර්ශ වස්තූන් ප්රවාහ සීමා තරණය කිරීමට කැමතියි. ඔවුන් මෙය කරන්නේ සමහර විට සහ එහෙන් මෙහෙන් නොවේ, නමුත් නිරන්තරයෙන් හා සෑම තැනකම පාහේ
දත්ත සමුදාය ඉදිරිපත් කරන ලද රූප සටහනේ මූලික අංගයන්ගෙන් එකකි. එහි ප්රධාන කාර්යය වන්නේ macropattern ක්රියාත්මක කිරීමයි
දත්ත සමුදාය තෝරාගැනීමට බලපෑ දෙවන වැදගත් සාධකය වූයේ අපගේ Cloud API ය. එය git විසින් අනුගමනය කරන ලද සමමුහුර්තකරණ ප්රවේශයෙන් ආභාෂය ලැබීය. ඔහු වගේම අපිත් ඉලක්ක කළා
එබැවින්, ඔබ පුල් විධානයක් ක්රියාත්මක කරන විට, දේශීය ස්නැප්ෂොට් එකකට පැච් යොදනවා වෙනුවට, එහි සම්පූර්ණ තත්ත්වය සම්පූර්ණ සේවාදායක තත්ත්වය සමඟ සංසන්දනය කරන බව ඔබ සිතන්නේ නම්, එවිට ඔබට වලාකුළු තුළ සමමුහුර්තකරණය සිදුවන්නේ කෙසේද යන්න පිළිබඳ තරමක් නිවැරදි අදහසක් ලැබෙනු ඇත. ගනුදෙනුකරුවන්. එය ක්රියාත්මක කිරීම සඳහා, ඔබ සියලු සේවාදායකයන් සහ දේශීය ගොනු පිළිබඳ මෙටා-තොරතුරු සමඟ මතකයේ DOM ගස් දෙකක් වෙන් කිරීමට අවශ්ය බව අනුමාන කිරීම පහසුය. පරිශීලකයෙකු වලාකුළු තුළ ලිපිගොනු 500 ක් ගබඩා කරන්නේ නම්, එය සමමුහුර්ත කිරීම සඳහා නෝඩ් මිලියනයක් සහිත ගස් දෙකක් ප්රතිනිර්මාණය කර විනාශ කිරීම අවශ්ය බව පෙනේ. නමුත් සෑම නෝඩයක්ම උප වස්තු ප්රස්ථාරයක් අඩංගු සමස්ථයකි. මෙම ආලෝකය තුළ, පැතිකඩ කිරීමේ ප්රතිඵල අපේක්ෂා කරන ලදී. ඒකාබද්ධ කිරීමේ ඇල්ගොරිතම සැලකිල්ලට නොගෙන වුවද, කුඩා වස්තූන් විශාල ප්රමාණයක් නිර්මාණය කිරීමේ හා පසුව විනාශ කිරීමේ ක්රියා පටිපාටියට සෑහෙන සතයක් වැය වන බව පෙනී ගියේය.මූලික සමමුහුර්ත කිරීමේ මෙහෙයුම විශාල සංඛ්යාවකට ඇතුළත් කර තිබීම නිසා තත්වය තවත් උග්ර වේ. පරිශීලක ස්ක්රිප්ට් වලින්. ප්රතිඵලයක් වශයෙන්, දත්ත සමුදායක් තෝරාගැනීමේදී අපි දෙවන වැදගත් නිර්ණායකය සවි කරමු - වස්තූන් ගතික වෙන් කිරීමකින් තොරව CRUD මෙහෙයුම් ක්රියාත්මක කිරීමේ හැකියාව.
අනෙකුත් අවශ්යතා වඩාත් සාම්ප්රදායික වන අතර ඒවායේ සම්පූර්ණ ලැයිස්තුව පහත පරිදි වේ.
- නූල් ආරක්ෂාව.
- බහු සැකසුම්. නූල් අතර පමණක් නොව, ප්රධාන යෙදුම සහ iOS දිගු අතර ද සමමුහුර්ත කිරීමට එකම දත්ත සමුදා අවස්ථාව භාවිතා කිරීමට ඇති ආශාව මගින් නියම කරනු ලැබේ.
- විකෘති නොවන වස්තු ලෙස ගබඩා කර ඇති ආයතන නිරූපණය කිරීමේ හැකියාව
- CRUD මෙහෙයුම් තුළ ගතික ප්රතිපාදන නොමැත.
- මූලික දේපල සඳහා ගනුදෙනු සහාය
අම්ලය : පරමාණුකත්වය, අනුකූලතාව, හුදකලාව සහ විශ්වසනීයත්වය. - වඩාත් ජනප්රිය අවස්ථා වල වේගය.
මෙම අවශ්යතා සමූහය සමඟ, SQLite හොඳ තේරීමක් විය. කෙසේ වෙතත්, විකල්ප අධ්යයනයේ කොටසක් ලෙස මට පොතක් හමු විය
2. LMDB ස්ථානගත කිරීම
LMDB යනු ඉතා කුඩා පුස්තකාලයකි (පේළි 10K පමණි) එය දත්ත සමුදායේ අවම මූලික ස්ථරය - ගබඩාව ක්රියාත්මක කරයි.
ඉහත රූප සටහනෙන් පෙන්නුම් කරන්නේ ඉහළ මට්ටම් ක්රියාත්මක කරන SQLite සමඟ LMDB සංසන්දනය කිරීම සාමාන්යයෙන් මූලික දත්ත සහිත SQLite වලට වඩා නිවැරදි නොවන බවයි. BerkeleyDB, LevelDB, Sophia, RocksDB යනාදී සමාන තරඟකරුවන් ලෙස එකම ගබඩා එන්ජින් උපුටා දැක්වීම වඩාත් සාධාරණ වනු ඇත. LMDB SQLite සඳහා ගබඩා එන්ජින් සංරචකයක් ලෙස ක්රියා කරන වර්ධනයන් පවා තිබේ. එවැනි පළමු අත්හදා බැලීම 2012 දී සිදු විය
LMDB ප්රධාන වශයෙන් යෙදුම් දත්ත සමුදායන් සඳහා එන්ජිමක් ලෙස භාවිතා කරයි. පුස්තකාලය එහි පෙනුම සංවර්ධකයින්ට ණයගැතියි
LMDB බොහෝ විට ගබඩාවක් ලෙස භාවිතා කරයි. උදාහරණයක් ලෙස, Mozilla Firefox බ්රව්සරය
එන්ජිම ජංගම සංවර්ධන ලෝකයේ ද එහි සලකුණ තබා ඇත. එහි භාවිතයේ සලකුණු විය හැකිය
ඔරකල් පාලනයට නතු වූ පසු බර්ක්ලි ඩීබී විසින් ඉතිරි කරන ලද නිකේතනයේ හිරු එළියේ ස්ථානයක් සඳහා LMDB සාර්ථකව සටන් කරයි. පුස්තකාලය එහි වේගය සහ විශ්වසනීයත්වය සඳහා එහි මිතුරන් හා සසඳන විට පවා ආදරය කරයි. ඔබ දන්නා පරිදි, නොමිලේ දිවා භෝජන සංග්රහයක් නොමැති අතර, LMDB සහ SQLite අතර තෝරා ගැනීමේදී ඔබට මුහුණ දීමට සිදුවන වෙළඳාම පිළිබඳව මම අවධාරණය කිරීමට කැමැත්තෙමි. ඉහත රූප සටහනෙන් පැහැදිලිව පෙන්නුම් කරන්නේ වේගය වැඩි කරන ආකාරයයි. පළමුව, අපි තැටි ආචයනය මත අතිරේක වියුක්ත ස්ථර සඳහා ගෙවන්නේ නැත. හොඳ ගෘහ නිර්මාණ ශිල්පයක් තවමත් ඔවුන් නොමැතිව කළ නොහැකි බව පැහැදිලිය, ඒවා අනිවාර්යයෙන්ම යෙදුම් කේතයේ දිස්වනු ඇත, නමුත් ඒවා වඩා සියුම් වනු ඇත. විශේෂිත යෙදුමකට අවශ්ය නොවන විශේෂාංග ඒවායේ අඩංගු නොවනු ඇත, උදාහරණයක් ලෙස, SQL භාෂාවෙන් විමසුම් සඳහා සහාය. දෙවනුව, තැටි ගබඩා කිරීම සඳහා වන ඉල්ලීම් මත යෙදුම් මෙහෙයුම් සිතියම්ගත කිරීම ප්රශස්ත ලෙස ක්රියාත්මක කිරීමට හැකි වේ. SQLite නම්
3. LMDB කුළුණු තුනක්
කුරුලු ඇසකින් LMDB දෙස බැලූ විට, ගැඹුරට යාමට කාලයයි. මීළඟ කොටස් තුන ගබඩා ගෘහනිර්මාණ ශිල්පය රැඳෙන ප්රධාන කුළුණු පිළිබඳ විශ්ලේෂණයක් සඳහා කැප කෙරේ.
- තැටිය සමඟ වැඩ කිරීම සහ අභ්යන්තර දත්ත ව්යුහයන් සමමුහුර්ත කිරීම සඳහා යාන්ත්රණයක් ලෙස මතක සිතියම්ගත ගොනු.
- ගබඩා කළ දත්තවල ව්යුහයේ සංවිධානයක් ලෙස B+-tree.
- ACID ගනුදෙනු ගුණාංග සහ බහුඅනුවර්තනය සැපයීම සඳහා ප්රවේශයක් ලෙස පිටපත්-මත-ලියන්න.
3.1 තල්මසා #1. මතක සිතියම්ගත ගොනු
මතක සිතියම්ගත ලිපිගොනු එතරම් වැදගත් වාස්තු විද්යාත්මක අංගයක් වන අතර ඒවා ගබඩාවේ නාමයෙන් පවා දිස්වේ. ගබඩා කර ඇති තොරතුරු සඳහා ප්රවේශය හැඹිලිගත කිරීම සහ සමමුහුර්ත කිරීම පිළිබඳ ගැටළු සම්පූර්ණයෙන්ම මෙහෙයුම් පද්ධතියට ඉතිරි වේ. LMDB හි කිසිදු හැඹිලි අඩංගු නොවේ. සිතියම්ගත කළ ලිපිගොනු වලින් දත්ත කෙලින්ම කියවීමෙන් එන්ජිම ක්රියාත්මක කිරීමේදී බොහෝ කොන් කපා ගැනීමට ඔබට ඉඩ සලසන බැවින් මෙය කතුවරයාගේ දැනුවත් තීරණයකි. පහත දැක්වෙන්නේ ඒවායින් සමහරක් සම්පූර්ණ ලැයිස්තුවෙන් බොහෝ දුරස් ය.
- ක්රියාවලි කිහිපයකින් එය සමඟ වැඩ කරන විට ගබඩාවේ දත්තවල අනුකූලතාව පවත්වා ගැනීම මෙහෙයුම් පද්ධතියේ වගකීම වේ. ඊළඟ කොටසේදී, මෙම යාන්ත්ර විද්යාව විස්තරාත්මකව සහ පින්තූර සමඟ සාකච්ඡා කෙරේ.
- හැඹිලි නොමැති වීම ගතික ප්රතිපාදන හා සම්බන්ධ පොදු කාර්ය වලින් LMDB සම්පූර්ණයෙන්ම ඉවත් කරයි. ප්රායෝගිකව දත්ත කියවීම යනු අථත්ය මතකයේ නිවැරදි ලිපිනයට පොයින්ටරයක් සැකසීම මිස තවත් කිසිවක් නොවේ. එය විද්යා ප්රබන්ධයක් සේ පෙනේ, නමුත් ගබඩා ප්රභව කේතයේ calloc වෙත ලැබෙන සියලුම ඇමතුම් ගබඩා වින්යාස ශ්රිතය තුළ සංකේන්ද්රණය වී ඇත.
- හැඹිලි නොමැති වීමෙන් අදහස් වන්නේ ඒවායේ ප්රවේශය සමමුහුර්ත කිරීම හා සම්බන්ධ අගුලු නොමැති වීමයි. එකවිට අත්තනෝමතික පාඨකයින් සංඛ්යාවක් සිටිය හැකි පාඨකයන්ට දත්ත වෙත යන ගමනේදී එක මුටෙක්ස් එකක්වත් හමු නොවේ. මේ නිසා, කියවීමේ වේගය CPU ගණන මත පදනම්ව කදිම රේඛීය පරිමාණයක් ඇත. LMDB හි, වෙනස් කිරීමේ මෙහෙයුම් පමණක් සමමුහුර්ත කර ඇත. වරකට සිටිය හැක්කේ එක් ලේඛකයෙකු පමණි.
- අවම වශයෙන් හැඹිලිගත කිරීම සහ සමමුහුර්ත කිරීමේ තර්කනය බහු-නූල් පරිසරයක වැඩ කිරීම හා සම්බන්ධ අතිශය සංකීර්ණ ආකාරයේ දෝෂ ඉවත් කරයි. Usenix OSDI 2014 සම්මන්ත්රණයේදී රසවත් දත්ත සමුදා අධ්යයනයන් දෙකක් විය:
"සියලු ගොනු පද්ධති සමානව නිර්මාණය කර නැත: බිඳ වැටීම්-අනුකූල යෙදුම් සැකසීමේ සංකීර්ණත්වය මත" и"විනෝදය සහ ලාභය සඳහා වධහිංසා දත්ත සමුදායන්" . ඔවුන්ගෙන් ඔබට LMDB හි පෙර නොවූ විරූ විශ්වසනීයත්වය සහ SQLite වලට වඩා උසස් වන ACID ගනුදෙනු ගුණාංගවල දෝෂ රහිතව ක්රියාත්මක කිරීම යන දෙකම පිළිබඳ තොරතුරු ලබා ගත හැකිය. - LMDB හි අවමවාදය මඟින් එහි කේතයේ යන්ත්ර නිරූපණය සම්පූර්ණයෙන්ම ප්රොසෙසරයේ L1 හැඹිලිය තුළ ඇති වේග ලක්ෂණ සමඟ ස්ථානගත කිරීමට ඉඩ සලසයි.
අවාසනාවකට, iOS හි, මතක සිතියම්ගත ගොනු සමඟ, සෑම දෙයක්ම අප කැමති පරිදි වලාකුළු රහිත නොවේ. ඔවුන් සමඟ සම්බන්ධ වූ අඩුපාඩු ගැන වඩාත් සවිඥානකව කතා කිරීම සඳහා, මෙහෙයුම් පද්ධතිවල මෙම යාන්ත්රණය ක්රියාත්මක කිරීමේ පොදු මූලධර්ම මතක තබා ගැනීම අවශ්ය වේ.
මතක සිතියම්ගත ගොනු පිළිබඳ සාමාන්ය තොරතුරු
ක්රියාත්මක වන සෑම යෙදුමක් සමඟම, මෙහෙයුම් පද්ධතිය ක්රියාවලියක් ලෙස හඳුන්වන ආයතනයක් සම්බන්ධ කරයි. සෑම ක්රියාවලියකටම එය ක්රියා කිරීමට අවශ්ය සියල්ල ස්ථානගත කරන ලිපින මාලාවක් වෙන් කර ඇත. අඩුම ලිපිනවල කේත සහිත කොටස් සහ දෘඪ-කේතගත දත්ත සහ සම්පත් ඇත. මීළඟට එන්නේ ගොඩ යන නම යටතේ අප හොඳින් දන්නා ගතික ලිපින අවකාශයේ වැඩෙන කොටසකි. වැඩසටහනේ ක්රියාකාරිත්වය අතරතුර දිස්වන ආයතනවල ලිපිනයන් එහි අඩංගු වේ. ඉහළින් ඇත්තේ යෙදුම් තොගය භාවිතා කරන මතක ප්රදේශයයි. එය වර්ධනය වේ හෝ හැකිලී යයි; වෙනත් වචන වලින් කිවහොත්, එහි විශාලත්වය ද ගතික ස්වභාවයක් ඇත. අට්ටිය සහ ගොඩවල් එකිනෙක තෙරපීම සහ බාධා කිරීම වැලැක්වීම සඳහා, ඒවා ලිපින අවකාශයේ විවිධ කෙළවරේ පිහිටා ඇත. ඉහළ සහ පහළ යන ගතික කොටස් දෙක අතර සිදුරක් ඇත. ක්රියාවලිය සමඟ විවිධ ආයතන සම්බන්ධ කිරීමට මෙහෙයුම් පද්ධතිය මෙම මැද කොටසේ ලිපින භාවිතා කරයි. විශේෂයෙන්, එය තැටියේ ඇති ගොනුවක් සමඟ නිශ්චිත අඛණ්ඩ ලිපින කට්ටලයක් සම්බන්ධ කළ හැකිය. එවැනි ගොනුවක් මතක සිතියම්කරණය ලෙස හැඳින්වේ
ක්රියාවලියට වෙන් කර ඇති ලිපින අවකාශය අති විශාලය. න්යායාත්මකව, ලිපින ගණන සීමා වන්නේ දර්ශකයේ ප්රමාණයෙන් පමණක් වන අතර එය පද්ධතියේ බිට් ධාරිතාව අනුව තීරණය වේ. භෞතික මතකය එයට 1 සිට 1 දක්වා සිතියම්ගත කළහොත්, පළමු ක්රියාවලිය මුළු RAMයම ගිල දමනු ඇති අතර බහුකාර්යයක් ගැන කතා කිරීමක් නැත.
කෙසේ වෙතත්, අපගේ අත්දැකීම් අනුව නවීන මෙහෙයුම් පද්ධතිවලට එකවර අවශ්ය තරම් ක්රියාවලීන් ක්රියාත්මක කළ හැකි බව අපි දනිමු. මෙය කළ හැක්කේ ඔවුන් විශාල මතකයක් කඩදාසි මත ක්රියාවලි සඳහා පමණක් වෙන් කරන නමුත් යථාර්ථයේ දී ඔවුන් ප්රධාන භෞතික මතකයට පටවන්නේ මෙහි සහ දැන් ඉල්ලුමේ ඇති එම කොටස පමණි. එබැවින් ක්රියාවලියක් හා සම්බන්ධ මතකය අථත්ය ලෙස හැඳින්වේ.
මෙහෙයුම් පද්ධතිය අථත්ය සහ භෞතික මතකය යම් ප්රමාණයක පිටු වලට සංවිධානය කරයි. අතථ්ය මතකයේ යම් පිටුවක් ඉල්ලුමක් ඇති වූ වහාම, මෙහෙයුම් පද්ධතිය එය භෞතික මතකයට පටවා විශේෂ වගුවකට ගැලපේ. නොමිලේ තව් නොමැති නම්, කලින් පටවන ලද පිටු වලින් එකක් තැටියට පිටපත් කර ඇති අතර ඉල්ලුමේ ඇති එක එහි ස්ථානයට පත්වේ. අපි ඉක්මනින් නැවත පැමිණෙන මෙම ක්රියා පටිපාටිය හුවමාරු කිරීම ලෙස හැඳින්වේ. පහත රූපයේ දැක්වෙන්නේ විස්තර කර ඇති ක්රියාවලියයි. එහි, ලිපිනය 0 සහිත A පිටුව පූරණය කර, ලිපිනය 4 සහිත ප්රධාන මතක පිටුවේ තබා ඇත. මෙම කරුණ කොටුව අංක 0 හි ලිපි හුවමාරු වගුවේ පිළිබිඹු විය.
මතකයට සිතියම්ගත කළ ගොනු සමඟ කතාව හරියටම සමාන වේ. තාර්කිකව, ඒවා අඛණ්ඩව සහ සම්පූර්ණයෙන්ම අථත්ය ලිපින අවකාශයේ පිහිටා ඇත. කෙසේ වෙතත්, ඔවුන් භෞතික මතක පිටුව පිටුවෙන් ඇතුල් කරන අතර ඉල්ලීම මත පමණි. එවැනි පිටු වෙනස් කිරීම තැටියේ ඇති ගොනුව සමඟ සමමුහුර්ත කර ඇත. මේ ආකාරයට, ඔබට මතකයේ ඇති බයිට් සමඟ සරලව ක්රියා කිරීමෙන් ගොනු I/O ක්රියාත්මක කළ හැක - සියලුම වෙනස්කම් මෙහෙයුම් පද්ධති කර්නලය මඟින් මූලාශ්ර ගොනුව වෙත ස්වයංක්රීයව මාරු කරනු ලැබේ.
විවිධ ක්රියාවලි වලින් දත්ත සමුදාය සමඟ වැඩ කිරීමේදී LMDB එහි තත්වය සමමුහුර්ත කරන ආකාරය පහත රූපයෙන් පෙන්නුම් කරයි. විවිධ ක්රියාවලි වල අථත්ය මතකය එකම ගොනුවකට සිතියම්ගත කිරීමෙන්, LMDB පෙනෙන පරිදි ඒවායේ ලිපින අවකාශයේ ඇතැම් කොටස් එකිනෙක සංක්රාන්ති ලෙස සමමුහුර්ත කිරීමට අපි මෙහෙයුම් පද්ධතියට බැඳී සිටිමු.
වැදගත් සූක්ෂ්මතාවයක් නම්, LMDB, පෙරනිමියෙන්, ලිවීමේ පද්ධති ඇමතුම් යාන්ත්රණය හරහා දත්ත ගොනුව වෙනස් කරයි, සහ ගොනුව කියවීමට පමණක් ප්රදර්ශණය කරයි. මෙම ප්රවේශය වැදගත් ප්රතිවිපාක දෙකක් ඇත.
පළමු ප්රතිවිපාකය සියලු මෙහෙයුම් පද්ධති සඳහා පොදු වේ. එහි සාරය වන්නේ වැරදි කේතය මගින් දත්ත සමුදායට නොදැනුවත්වම හානි වීමෙන් ආරක්ෂාව එකතු කිරීමයි. ඔබ දන්නා පරිදි, ක්රියාවලියක ක්රියාත්මක කළ හැකි උපදෙස් එහි ලිපින අවකාශයේ ඕනෑම තැනක සිට දත්ත වෙත ප්රවේශ වීමට නොමිලේ. ඒ අතරම, අපට දැන් මතක ඇති පරිදි, කියවීමේ-ලිවීමේ මාදිලියේ ගොනුවක් පෙන්වීම යනු ඕනෑම උපදෙස් වලට එය වෙනස් කළ හැකි බවයි. ඇය මෙය වැරදීමකින් කරන්නේ නම්, උදාහරණයක් ලෙස, නොපවතින දර්ශකයක අරා මූලද්රව්ය නැවත ලිවීමට උත්සාහ කරයි නම්, ඇයට මෙම ලිපිනයට සිතියම් කර ඇති ගොනුව අහම්බෙන් වෙනස් කළ හැකි අතර එය දත්ත සමුදාය දූෂණයට තුඩු දෙනු ඇත. ගොනුව කියවීමට පමණක් ප්රකාරයේදී ප්රදර්ශනය කරන්නේ නම්, අනුරූප ලිපින අවකාශය වෙනස් කිරීමට උත්සාහ කිරීම සංඥාවක් සමඟ වැඩසටහන හදිසියේ අවසන් කිරීමට හේතු වේ. SIGSEGV
, සහ ගොනුව නොවෙනස්ව පවතිනු ඇත.
දෙවන ප්රතිවිපාකය දැනටමත් iOS සඳහා විශේෂිත වේ. කතුවරයා හෝ වෙනත් කිසිදු මූලාශ්රයක් එය පැහැදිලිව සඳහන් කර නැත, නමුත් එය නොමැතිව LMDB මෙම ජංගම මෙහෙයුම් පද්ධතිය මත ධාවනය කිරීමට සුදුසු නොවේ. ඊළඟ කොටස එහි සලකා බැලීම සඳහා කැප කර ඇත.
iOS හි මතක සිතියම්ගත ගොනු වල විශේෂතා
2018 WWDC හි අපූරු වාර්තාවක් තිබුණා
පිරිසිදු මතකය යනු භෞතික මතකයෙන් වේදනා රහිතව ඉවත් කළ හැකි පිටු එකතුවකි. ඒවායේ අඩංගු දත්ත එහි මුල් මූලාශ්රවලින් අවශ්ය පරිදි නැවත පූරණය කළ හැක. කියවීමට පමණක් මතක සිතියම්ගත ගොනු මෙම වර්ගයට අයත් වේ. තැටියේ ඇති ගොනුව සමඟ සමමුහුර්ත කිරීම සහතික කර ඇති බැවින්, ඕනෑම වේලාවක මතකයෙන් ගොනුවකට සිතියම්ගත කළ පිටු බාගැනීමට iOS බිය නැත.
නවීකරණය කරන ලද සියලුම පිටු ඒවා මුලින් පිහිටා තිබුණේ කොතැනක වුවත් අපිරිසිදු මතකයෙන් අවසන් වේ. විශේෂයෙන්ම, මතක සිතියම්ගත ගොනු ඒවාට සම්බන්ධ අථත්ය මතකයට ලිවීමෙන් වෙනස් කරන ලද ගොනු මේ ආකාරයෙන් වර්ගීකරණය කරනු ලැබේ. ධජය සමඟ LMDB විවෘත කිරීම MDB_WRITEMAP
, එය වෙනස් කිරීමෙන් පසු, ඔබට මෙය පුද්ගලිකව සත්යාපනය කළ හැක
යෙදුමක් අධික භෞතික මතකයක් ලබා ගැනීමට පටන් ගත් වහාම, iOS එය අපිරිසිදු පිටු සම්පීඩනයකට යටත් කරයි. අපිරිසිදු සහ සම්පීඩිත පිටු විසින් අල්ලාගෙන සිටින සම්පූර්ණ මතකය යෙදුමේ ඊනියා මතක පියසටහන සාදයි. එය නිශ්චිත සීමාවකට ළඟා වූ පසු, OOM ඝාතක පද්ධති ඩීමන් ක්රියාවලියෙන් පසුව පැමිණ එය බලහත්කාරයෙන් අවසන් කරයි. ඩෙස්ක්ටොප් මෙහෙයුම් පද්ධති හා සසඳන විට iOS හි විශේෂත්වය මෙයයි. ඊට ප්රතිවිරුද්ධව, භෞතික මතකයේ සිට තැටියට පිටු මාරු කිරීමෙන් මතක පියසටහන අඩු කිරීම iOS හි සපයා නැත.හේතු අනුමාන කළ හැක්කේ එය පමණි. සමහර විට පිටු තැටියට සහ පසුපසට තීව්ර ලෙස ගෙනයාමේ ක්රියා පටිපාටිය ජංගම උපාංග සඳහා බලශක්ති පරිභෝජනය වැඩි කරයි, නැතහොත් iOS SSD ධාවකවල සෛල නැවත ලිවීමේ සම්පත සුරකියි, නැතහොත් සමහර විට නිර්මාණකරුවන් සියල්ල පවතින පද්ධතියේ සමස්ත ක්රියාකාරිත්වය ගැන සෑහීමකට පත් නොවීය. නිරන්තරයෙන් හුවමාරු කර ඇත. එය එසේ වුවද, කාරණය සත්යයක් ලෙස පවතී.
ශුභාරංචිය, කලින් සඳහන් කර ඇත, පෙරනිමියෙන් LMDB ගොනු යාවත්කාලීන කිරීමට mmap යාන්ත්රණය භාවිතා නොකරයි. මෙයින් අදහස් කරන්නේ ප්රදර්ශනය කරන ලද දත්ත iOS විසින් පිරිසිදු මතකය ලෙස වර්ග කර ඇති අතර මතක පියසටහනට දායක නොවන බවයි. VM Tracker නම් Xcode මෙවලම භාවිතයෙන් ඔබට මෙය සත්යාපනය කළ හැක. පහත තිර රුවක් ක්රියාත්මක වන විට Cloud යෙදුමේ iOS අතථ්ය මතකයේ තත්වය පෙන්වයි. ආරම්භයේදී, LMDB අවස්ථා 2 ක් එහි ආරම්භ කරන ලදී. පළමුවැන්නාට ඔහුගේ ගොනුව 1GiB අථත්ය මතකයේ ප්රදර්ශනය කිරීමට අවසර දී ඇත, දෙවැන්න - 512MiB. ගබඩා දෙකම යම් නේවාසික මතක ප්රමාණයක් අත්පත් කරගෙන ඇතත්, ඒ දෙකෙන් එකක්වත් අපිරිසිදු ප්රමාණයට දායක නොවේ.
දැන් එය නරක ආරංචියක් සඳහා කාලයයි. 64-bit ඩෙස්ක්ටොප් මෙහෙයුම් පද්ධතිවල ඇති swap යාන්ත්රණයට ස්තූතිවන්ත වන අතර, සෑම ක්රියාවලියකටම එහි විභව swap සඳහා නිදහස් දෘඪ තැටි ඉඩ ප්රමාණය ලබා ගත හැක. IOS හි සම්පීඩනය සමඟ swap ප්රතිස්ථාපනය කිරීම න්යායික උපරිමය රැඩිකල් ලෙස අඩු කරයි. දැන් සියලුම ජීව ක්රියාවලීන් ප්රධාන (RAM කියවන්න) මතකයට ගැළපිය යුතු අතර නොගැලපෙන සියල්ල අවසන් කිරීමට බල කළ යුතුය. ඉහත සඳහන් කළ පරිදි මෙය සඳහන් වේ
Cloud හි අත්හදා බැලීම්වල ප්රතිඵල මත පදනම්ව, අපි LMDB විසින් වෙන් කරන ලද මතකය සඳහා පහත සම්මුති අගයන් වෙත පැමිණියෙමු: 384-bit උපාංග සඳහා මෙගාබයිට් 32 සහ 768-bit උපාංග සඳහා 64. මෙම පරිමාව භාවිතා කිරීමෙන් පසු, ඕනෑම වෙනස් කිරීමේ මෙහෙයුම් කේතය සමඟ අවසන් වීමට පටන් ගනී MDB_MAP_FULL
. අපගේ නිරීක්ෂණයේදී එවැනි දෝෂයන් අපි නිරීක්ෂණය කරමු, නමුත් මෙම අදියරේදී ඒවා නොසලකා හැරිය හැකි තරම් කුඩා ඒවා වේ.
ගබඩාව මගින් අධික මතක පරිභෝජනය සඳහා පැහැදිලි නොවන හේතුවක් දිගුකාලීන ගනුදෙනු විය හැකිය. මෙම සංසිද්ධි දෙක සම්බන්ධ වන්නේ කෙසේද යන්න තේරුම් ගැනීමට, LMDB හි ඉතිරි කුළුණු දෙක සලකා බැලීමෙන් අපට උපකාර වනු ඇත.
3.2 තල්මසා #2. B+-ගස
යතුරු අගය ගබඩාවක් මත වගු අනුකරණය කිරීමට, පහත සඳහන් මෙහෙයුම් එහි API හි තිබිය යුතුය:
- නව අංගයක් ඇතුල් කිරීම.
- දී ඇති යතුරක් සහිත මූලද්රව්යයක් සොයන්න.
- මූලද්රව්යයක් ඉවත් කිරීම.
- යතුරු වර්ග කර ඇති අනුපිළිවෙලෙහි කාල පරතරයන් මත පුනරාවර්තනය කරන්න.
මෙහෙයුම් හතරම පහසුවෙන් ක්රියාත්මක කළ හැකි සරලම දත්ත ව්යුහය ද්විමය සෙවුම් ගසකි. එහි සෑම නෝඩයක්ම ළමා යතුරුවල සමස්ත උප කුලකයම උප ගස් දෙකකට බෙදන යතුරක් නියෝජනය කරයි. වම් එකේ දෙමාපියන්ට වඩා කුඩා ඒවා අඩංගු වන අතර දකුණු පැත්තේ විශාල ඒවා අඩංගු වේ. ඇණවුම් කරන ලද යතුරු කට්ටලයක් ලබා ගැනීම සම්භාව්ය ගස් ගමන් වලින් එකක් හරහා සාක්ෂාත් කරගනු ලැබේ
ද්විමය ගස්වල මූලික දෝෂ දෙකක් ඇති අතර ඒවා තැටි මත පදනම් වූ දත්ත ව්යුහයක් ලෙස ඵලදායී වීම වළක්වයි. පළමුව, ඔවුන්ගේ ශේෂයේ තරම අනපේක්ෂිත ය. විවිධ ශාඛා වල උස විශාල ලෙස වෙනස් විය හැකි ගස් ලබා ගැනීමේ සැලකිය යුතු අවදානමක් ඇත, එය අපේක්ෂිත දේට සාපේක්ෂව සෙවීමේ ඇල්ගොරිතම සංකීර්ණත්වය සැලකිය යුතු ලෙස නරක අතට හැරේ. දෙවනුව, නෝඩ් අතර ඇති හරස්-සම්බන්ධතා බහුලත්වය ද්විමය ගස්වලට මතකයේ ප්රදේශය අහිමි කරයි, වසා නෝඩ් (ඒවා අතර සම්බන්ධතා අනුව) අථත්ය මතකයේ සම්පූර්ණයෙන්ම වෙනස් පිටු මත ස්ථානගත කළ හැක. එහි ප්රතිඵලයක් වශයෙන්, ගසක අසල්වැසි නෝඩ් කිහිපයක සරල ගමනක් සඳහා පවා සැසඳිය හැකි පිටු සංඛ්යාවක් නැරඹීමට අවශ්ය විය හැකිය. ප්රොසෙසර හැඹිලියේ පිටු නිරන්තරයෙන් භ්රමණය වීම ලාභදායී සතුටක් නොවන බැවින් මතකයේ දත්ත ව්යුහයක් ලෙස ද්විමය ගස්වල සඵලතාවය ගැන කතා කරන විට පවා මෙය ගැටළුවකි. තැටියෙන් නෝඩ් සමඟ සම්බන්ධ පිටු නිතර නැවත ලබා ගැනීමේදී, තත්වය සම්පූර්ණයෙන්ම සිදු වේ
B-trees, ද්විමය ගස්වල පරිණාමය වීම, පෙර ඡේදයේ හඳුනාගත් ගැටළු විසඳයි. පළමුව, ඔවුන් ස්වයං-සමතුලිත වේ. දෙවනුව, ඔවුන්ගේ සෑම නෝඩයක්ම ළමා යතුරු කට්ටලය 2 ට නොව M ඇණවුම් කරන ලද උප කුලකවලට බෙදී ඇති අතර M අංකය සිය ගණනක හෝ දහස් ගණනක අනුපිළිවෙලින් තරමක් විශාල විය හැකිය.
එමගින්:
- සෑම නෝඩයක්ම දැනටමත් ඇණවුම් කරන ලද යතුරු විශාල සංඛ්යාවක් අඩංගු වන අතර ගස් ඉතා කෙටි වේ.
- වටිනාකමින් ආසන්න යතුරු ස්වාභාවිකවම එකම හෝ අසල්වැසි නෝඩ් වල එකිනෙකට යාබදව පිහිටා ඇති බැවින් ගස මතකයේ පිහිටීමෙහි දේපල ලබා ගනී.
- සෙවුම් මෙහෙයුමකදී ගසකින් බැස යන විට සංක්රමණ නෝඩ් ගණන අඩු වේ.
- පරාස විමසුම් අතරතුර කියවන ඉලක්ක නෝඩ් ගණන අඩු වේ, මන්ද ඒ සෑම එකක්ම දැනටමත් ඇණවුම් කරන ලද යතුරු විශාල ප්රමාණයක් අඩංගු වේ.
LMDB දත්ත ගබඩා කිරීම සඳහා B+ ගසක් ලෙස හඳුන්වන B-ගසේ විචලනය භාවිතා කරයි. ඉහත රූප සටහන එහි පවතින නෝඩ් වර්ග තුන පෙන්වයි:
- මුදුනේ ඇත්තේ මූලයයි. එය ගබඩාවක් තුළ ඇති දත්ත ගබඩාවක් යන සංකල්පයට වඩා වැඩි යමක් සිදු නොවේ. එක් LMDB අවස්ථාවක් තුළ, ඔබට සිතියම්ගත කළ අතථ්ය ලිපින ඉඩක් බෙදා ගන්නා දත්ත සමුදායන් කිහිපයක් සෑදිය හැක. ඒ සෑම එකක්ම තමන්ගේම මූලයෙන් ආරම්භ වේ.
- පහළම මට්ටමේ කොළ ඇත. දත්ත ගබඩාවේ ගබඩා කර ඇති ප්රධාන අගය යුගල අඩංගු වන්නේ ඒවා සහ ඒවා පමණි. මාර්ගය වන විට, මෙය B+-ගස් වල සුවිශේෂත්වයයි. සාමාන්ය B-ගසක් සියලු මට්ටම්වල නෝඩ් වල වටිනාකම් කොටස් ගබඩා කරන්නේ නම්, B+ විචලනය වන්නේ අඩුම එකෙහි පමණි. මෙම කරුණ නිවැරදි කිරීමෙන් පසුව, අපි තවදුරටත් LMDB හි භාවිතා කරන ගසේ උප වර්ගය සරලව B-tree ලෙස හඳුන්වමු.
- මූල සහ කොළ අතර නාවික (ශාඛා) නෝඩ් සහිත තාක්ෂණික මට්ටම් 0 ක් හෝ වැඩි ගණනක් ඇත. ඔවුන්ගේ කර්තව්යය වන්නේ කොළ අතර වර්ග කළ යතුරු කට්ටලය බෙදීමයි.
භෞතිකව, නෝඩ් යනු කලින් තීරණය කළ දිග මතක කොටස් වේ. ඒවායේ ප්රමාණය අප ඉහත සාකච්ඡා කළ මෙහෙයුම් පද්ධතියේ මතක පිටු ප්රමාණයෙන් ගුණාකාරයකි. නෝඩ් ව්යුහය පහත දැක්වේ. ශීර්ෂයේ මෙටා තොරතුරු අඩංගු වේ, වඩාත්ම පැහැදිලි වන්නේ උදාහරණයක් ලෙස චෙක්සම් ය. ඊළඟට දත්ත සහිත සෛල පිහිටා ඇති ඕෆ්සෙට් පිළිබඳ තොරතුරු පැමිණේ. අපි සංචාලන නෝඩ් ගැන කතා කරන්නේ නම්, දත්ත එක්කෝ යතුරු විය හැකිය, නැතහොත් කොළ සම්බන්ධයෙන් සම්පූර්ණ යතුරු-අගය යුගල විය හැකිය. ඔබට කාර්යයේ පිටු ව්යුහය ගැන වැඩිදුර කියවිය හැකිය.
පිටු නෝඩ් වල අභ්යන්තර අන්තර්ගතය සමඟ කටයුතු කිරීමෙන් පසු, අපි තවදුරටත් LMDB B-tree සරළ ආකාරයෙන් පහත ආකාරයෙන් නියෝජනය කරන්නෙමු.
නෝඩ් සහිත පිටු අනුපිළිවෙලින් තැටියේ පිහිටා ඇත. ඉහළ අංක සහිත පිටු ගොනුවේ අවසානයට පිහිටා ඇත. ඊනියා මෙටා පිටුවෙහි සියලුම ගස්වල මුල් සොයා ගත හැකි ඕෆ්සෙට් පිළිබඳ තොරතුරු අඩංගු වේ. ගොනුවක් විවෘත කරන විට, වලංගු මෙටා පිටුවක් සෙවීම සඳහා LMDB ගොනුව පිටුවෙන් පිටුව අග සිට මුලට පරිලෝකනය කර එය හරහා පවතින දත්ත සමුදායන් සොයා ගනී.
දැන්, දත්ත සංවිධානයේ තාර්කික හා භෞතික ව්යුහය පිළිබඳ අදහසක් ඇති අපට LMDB හි තුන්වන කුළුණ සලකා බැලීමට ඉදිරියට යා හැකිය. සියලුම ගබඩා වෙනස් කිරීම් ගණුදෙණුවකින් සහ එකිනෙකින් හුදකලාව සිදු වන අතර, දත්ත සමුදායට සමස්තයක් ලෙස බහුඅවර්ෂයේ දේපල ලබා දෙයි.
3.3 තල්මසා #3. පිටපත-මත-ලියන්න
සමහර B-tree මෙහෙයුම් එහි නෝඩ් වල වෙනස්කම් මාලාවක් සිදු කිරීම ඇතුළත් වේ. එක් උදාහරණයක් නම් දැනටමත් එහි උපරිම ධාරිතාවට ළඟා වී ඇති නෝඩයකට නව යතුරක් එකතු කිරීමයි. මෙම අවස්ථාවෙහිදී, පළමුව, නෝඩය දෙකට බෙදීම අවශ්ය වන අතර, දෙවනුව, එහි මාපිය තුළ ඇති නව අංකුර ළමා නෝඩයට සබැඳියක් එක් කිරීම අවශ්ය වේ. මෙම ක්රියා පටිපාටිය ඉතා භයානක විය හැකිය. කිසියම් හේතුවක් නිසා (කඩාවැටීම, විදුලිය ඇනහිටීම, ආදිය) මාලාවේ වෙනස්කම් වලින් කොටසක් පමණක් සිදු වුවහොත්, ගස නොගැලපෙන තත්වයක පවතිනු ඇත.
දත්ත සමුදායේ දෝෂ-ඉවසීම සඳහා එක් සම්ප්රදායික විසඳුමක් වන්නේ B-tree අසල අමතර තැටි දත්ත ව්යුහයක් එකතු කිරීමයි - ගනුදෙනු ලොගයක්, එය ලිවීමට-ඉදිරි ලඝු-සටහන (WAL) ලෙසද හැඳින්වේ. එය B-tree ම වෙනස් කිරීමට පෙර අපේක්ෂිත මෙහෙයුම තදින් ලියා ඇති ගොනුවකි. මේ අනුව, ස්වයං-රෝග විනිශ්චය අතරතුර දත්ත දූෂණය අනාවරණය වුවහොත්, දත්ත සමුදාය පිළිවෙළට තැබීමට ලොගය විමසයි.
LMDB දෝෂ ඉවසීමේ යාන්ත්රණයක් ලෙස වෙනස් ක්රමයක් තෝරාගෙන ඇත, එය පිටපත් කිරීම මත ලිවීම ලෙස හැඳින්වේ. එහි සාරය නම්, පවතින පිටුවක දත්ත යාවත්කාලීන කිරීම වෙනුවට, එය මුලින්ම එය සම්පූර්ණයෙන්ම පිටපත් කර පිටපතෙහි සියලු වෙනස් කිරීම් සිදු කිරීමයි.
ඊළඟට, යාවත්කාලීන දත්ත ලබා ගැනීම සඳහා, එහි මව් නෝඩයේ වත්මන් බවට පත් වී ඇති නෝඩයට සබැඳිය වෙනස් කිරීම අවශ්ය වේ. ඒකත් මේකට මොඩිෆයි කරන්න ඕන නිසා ඒකත් කලින් කොපි කරනවා. ක්රියාවලිය ප්රත්යාවර්තීව මුල දක්වාම සිදුවේ. වෙනස් කළ යුතු අවසාන දෙය මෙටා පිටුවේ දත්ත වේ
යාවත්කාලීන ක්රියා පටිපාටිය අතරතුර හදිසියේම ක්රියාවලිය බිඳ වැටුණහොත්, එක්කෝ නව මෙටා පිටුවක් නිර්මාණය නොවනු ඇත, නැතහොත් එය සම්පූර්ණයෙන්ම තැටියට නොලියනු ඇත, සහ එහි චෙක්සම් වැරදි වනු ඇත. මෙම අවස්ථා දෙකෙන් එකකදී, නව පිටු වෙත ළඟා විය නොහැකි වනු ඇත, නමුත් පැරණි ඒවාට බලපාන්නේ නැත. දත්ත අනුකූලතාව පවත්වා ගැනීම සඳහා LMDB හි ඉදිරි සටහන ලිවීමේ අවශ්යතාවය මෙය ඉවත් කරයි. ඇත්ත වශයෙන්ම, ඉහත විස්තර කර ඇති තැටියේ දත්ත ගබඩා කිරීමේ ව්යුහය එකවරම එහි ක්රියාකාරිත්වය ගනී. පැහැදිලි ගනුදෙනු ලොගයක් නොමැති වීම ඉහළ දත්ත කියවීමේ වේගයක් සපයන LMDB හි එක් ලක්ෂණයකි.
එහි ප්රතිඵලයක් ලෙස උපග්රන්ථයට පමණක් B-tree ලෙස හැඳින්වෙන නිර්මාණය, ස්වාභාවිකවම ගනුදෙනු හුදකලා කිරීම සහ බහු අනුවාදනය සපයයි. LMDB හි, සෑම විවෘත ගනුදෙනුවක්ම දැනට අදාළ ගස් මුල සමඟ සම්බන්ධ වේ. ගණුදෙණුව අවසන් වන තුරු, ඒ හා බැඳුනු ගසේ පිටු කිසිවිටෙක වෙනස් කිරීම හෝ නව දත්ත අනුවාද සඳහා නැවත භාවිතා කිරීම සිදු නොවේ.මේ අනුව, ඔබට අවශ්ය තාක් දුරට හරියටම අදාළ වූ දත්ත කට්ටලය සමඟ වැඩ කළ හැක. මෙම අවස්ථාවේදී ගබඩාව දිගටම සක්රියව යාවත්කාලීන වුවද, ගනුදෙනුව විවෘත විය. LMDB අපගේ ආදරණීයයන් සඳහා කදිම දත්ත මූලාශ්රයක් බවට පත් කරමින් බහුඅවර්ථනයේ සාරය මෙයයි UICollectionView
. ගනුදෙනුවක් විවෘත කිරීමෙන් පසු, කිසිවක් ඉතිරි නොවේ යැයි බියෙන්, කිසියම් මතකයේ ව්යුහයකට වත්මන් දත්ත කඩිමුඩියේ පොම්ප කිරීමෙන් යෙදුමේ මතක පියසටහන වැඩි කිරීමට අවශ්ය නොවේ. මෙම විශේෂාංගය LMDB එකම SQLite වෙතින් වෙන්කර හඳුනා ගනී, එවැනි සම්පූර්ණ හුදකලාව ගැන පුරසාරම් දෙඩීමට නොහැකිය. දෙවැන්නෙහි ගනුදෙනු දෙකක් විවෘත කර ඒවායින් එකක් තුළ යම් වාර්තාවක් මකා දැමීමෙන්, ඉතිරි දෙවන වාර්තාව තුළ එම වාර්තාවම ලබා ගැනීමට තවදුරටත් නොහැකි වනු ඇත.
කාසියේ අනෙක් පැත්ත යනු අතථ්ය මතකයේ සැලකිය යුතු ඉහළ පරිභෝජනයකි. දත්ත සමුදායේ විවිධ අනුවාද දෙස බලා විවෘත කියවීම් ගනුදෙනු 3ක් සමඟ එකවර වෙනස් කළහොත් දත්ත සමුදා ව්යුහය කෙබඳු වනු ඇත්දැයි විනිවිදකය පෙන්වයි. LMDB හට වත්මන් ගනුදෙනු හා සම්බන්ධ මූලයන් වෙත ළඟා විය හැකි නෝඩ් නැවත භාවිත කළ නොහැකි බැවින්, ගබඩාවට තවත් සිව්වන මූලයක් මතකයේ වෙන් කර නැවත වරක් ඒ යටතේ ඇති වෙනස් කළ පිටු ක්ලෝන කිරීම හැර වෙනත් විකල්පයක් නොමැත.
මෙහිදී මතක සිතියම්ගත ගොනු පිළිබඳ කොටස සිහිපත් කිරීම ප්රයෝජනවත් වනු ඇත. එය යෙදුමේ මතක පියසටහනට දායක නොවන බැවින්, අතථ්ය මතකයේ අතිරේක පරිභෝජනය අපව එතරම් කරදර නොවිය යුතු බව පෙනේ. කෙසේ වෙතත්, ඒ සමඟම, iOS එය වෙන් කිරීමේදී ඉතා මසුරු බව සටහන් වූ අතර, අපට සේවාදායකයක හෝ ඩෙස්ක්ටොප් එකක මෙන්, ටෙරාබයිට් 1 ක LMDB කලාපයක් ලබා දිය නොහැකි අතර මෙම විශේෂාංගය ගැන කිසිසේත් නොසිතන්න. හැකි නම්, ඔබ ගනුදෙනු වල ආයු කාලය හැකි තරම් කෙටි කිරීමට උත්සාහ කළ යුතුය.
4. Key-value API මත දත්ත යෝජනා ක්රමයක් සැලසුම් කිරීම
LMDB විසින් සපයනු ලබන මූලික වියුක්තයන් දෙස බැලීමෙන් අපගේ API විශ්ලේෂණය ආරම්භ කරමු: පරිසරය සහ දත්ත සමුදායන්, යතුරු සහ අගයන්, ගනුදෙනු සහ කර්සර.
කේත ලැයිස්තුගත කිරීම් පිළිබඳ සටහනක්
පොදු LMDB API හි සියලුම ශ්රිතයන් ඔවුන්ගේ කාර්යයේ ප්රතිඵලය දෝෂ කේතයක ආකාරයෙන් ලබා දෙයි, නමුත් පසුකාලීන සියලුම ලැයිස්තුගත කිරීම් වලදී එහි සත්යාපනය කෙටිකතාව සඳහා මඟ හැර ඇත. ප්රායෝගිකව, අපි ගබඩාව සමඟ අන්තර් ක්රියා කිරීමට පවා අපගේම භාවිතා කළෙමු.
IOS හෝ macOS සඳහා වන ව්යාපෘතියකට LMDB සම්බන්ධ කිරීමට වේගවත්ම ක්රමය ලෙස, මම මගේ CocoaPod යෝජනා කරමි
4.1 මූලික වියුක්ත කිරීම්
පරිසරය
ව්යුහය MDB_env
LMDB හි අභ්යන්තර තත්වයේ ගබඩාව වේ. උපසර්ග කාර්ය පවුල mdb_env
එහි සමහර ගුණාංග සැකසීමට ඔබට ඉඩ සලසයි. සරලම අවස්ථාවෙහිදී, එන්ජිම ආරම්භ කිරීම මේ ආකාරයෙන් පෙනේ.
mdb_env_create(env);
mdb_env_set_map_size(*env, 1024 * 1024 * 512)
mdb_env_open(*env, path.UTF8String, MDB_NOTLS, 0664);
Mail.ru Cloud යෙදුමේදී, අපි පරාමිති දෙකක පමණක් පෙරනිමි අගයන් වෙනස් කළෙමු.
පළමු එක වන්නේ ගබඩා ගොනුව සිතියම්ගත කර ඇති අතථ්ය ලිපින ඉඩ ප්රමාණයයි. අවාසනාවකට, එකම උපාංගයේ පවා, නිශ්චිත අගය ධාවනයෙන් ධාවනයට සැලකිය යුතු ලෙස වෙනස් විය හැක. IOS හි මෙම විශේෂාංගය සැලකිල්ලට ගැනීම සඳහා, උපරිම ගබඩා පරිමාව ගතිකව තෝරා ඇත. නිශ්චිත අගයකින් පටන් ගෙන එය ශ්රිතය දක්වා අනුක්රමිකව අඩකින් අඩු වේ mdb_env_open
වෙතින් වෙනස් ප්රතිඵලයක් ලබා නොදෙනු ඇත ENOMEM
. න්යායාත්මකව, ප්රතිවිරුද්ධ ක්රමයක් ද ඇත - පළමුව එන්ජිමට අවම මතකයක් වෙන් කරන්න, පසුව, දෝෂ ලැබුණු විට, MDB_MAP_FULL
, එය වැඩි කරන්න. කෙසේ වෙතත්, එය වඩාත් කටුක ය. හේතුව, ශ්රිතය භාවිතයෙන් මතකය (remap) නැවත වෙන් කිරීමේ ක්රියා පටිපාටියයි mdb_env_set_map_size
එන්ජිමෙන් කලින් ලැබුණු සියලුම ආයතන (කර්සර, ගනුදෙනු, යතුරු සහ අගයන්) අවලංගු කරයි. සංග්රහයේ මෙම සිදුවීම් හැරීම සැලකිල්ලට ගැනීම එහි සැලකිය යුතු සංකූලතාවයට තුඩු දෙනු ඇත. කෙසේ වෙතත්, අතථ්ය මතකය ඔබට ඉතා වැදගත් නම්, මෙය බොහෝ දුරට ඉදිරියට ගොස් ඇති දෙබල දෙස සමීපව බැලීමට හේතුවක් විය හැකිය.
දෙවන පරාමිතිය, අපට නොගැලපෙන පෙරනිමි අගය, නූල් ආරක්ෂාව සහතික කිරීමේ යාන්ත්ර විද්යාව නියාමනය කරයි. අවාසනාවකට, අවම වශයෙන් iOS 10 ට නූල් ප්රාදේශීය ආචයනය සඳහා සහය පිළිබඳ ගැටළු තිබේ. මෙම හේතුව නිසා, ඉහත උදාහරණයේ, කොඩිය සමඟ ගබඩාව විවෘත වේ MDB_NOTLS
. මීට අමතරව, එය ද අවශ්ය විය
දත්ත සමුදායන්
දත්ත සමුදාය අපි ඉහත සාකච්ඡා කළ වෙනම B-tree අවස්ථාවක් වේ. එහි විවෘත කිරීම සිදු වන්නේ ගනුදෙනුවක් තුළ වන අතර එය මුලින් ටිකක් අමුතු බවක් පෙනෙන්නට පුළුවන.
MDB_txn *txn;
MDB_dbi dbi;
mdb_txn_begin(env, NULL, MDB_RDONLY, &txn);
mdb_dbi_open(txn, NULL, MDB_CREATE, &dbi);
mdb_txn_abort(txn);
ඇත්ත වශයෙන්ම, LMDB හි ගනුදෙනුවක් යනු ගබඩා ආයතනයක් මිස නිශ්චිත දත්ත සමුදා ආයතනයක් නොවේ. විවිධ දත්ත සමුදායන්හි පිහිටා ඇති ආයතනවල පරමාණුක මෙහෙයුම් සිදු කිරීමට මෙම සංකල්පය ඔබට ඉඩ සලසයි. න්යායාත්මකව, මෙය විවිධ දත්ත සමුදා ස්වරූපයෙන් වගු ආකෘති නිර්මාණය කිරීමේ හැකියාව විවෘත කරයි, නමුත් එක් අවස්ථාවක මම වෙනත් මාර්ගයක් ගෙන, විස්තරාත්මකව පහත විස්තර කර ඇත.
යතුරු සහ අගයන්
ව්යුහය MDB_val
යතුර සහ වටිනාකම යන දෙකෙහිම සංකල්පය ආදර්ශන කරයි. ගබඩාවට ඒවායේ අර්ථ ශාස්ත්රය ගැන අදහසක් නැත. ඇයට, වෙනත් දෙයක් යනු දී ඇති ප්රමාණයේ බයිට් මාලාවක් පමණි. උපරිම යතුරු ප්රමාණය බයිට් 512 කි.
typedef struct MDB_val {
size_t mv_size;
void *mv_data;
} MDB_val;
සංසන්දනයක් භාවිතා කරමින්, ගබඩාව යතුරු ආරෝහණ අනුපිළිවෙලට වර්ග කරයි. ඔබ එය ඔබේම දේ සමඟ ප්රතිස්ථාපනය නොකරන්නේ නම්, පෙරනිමි එක භාවිතා කරනු ඇත, එය ශබ්දකෝෂ අනුපිළිවෙලට බයිට් බයිට් ලෙස වර්ග කරයි.
ගනුදෙනු
ගනුදෙනු ව්යුහය විස්තරාත්මකව විස්තර කෙරේ
- සියලුම මූලික ගුණාංග සඳහා සහය දක්වයි
අම්ලය : පරමාණුකත්වය, අනුකූලතාව, හුදකලාව සහ විශ්වසනීයත්වය. MDBX හි සවි කර ඇති macOS සහ iOS වල කල්පැවැත්ම සම්බන්ධයෙන් දෝෂයක් ඇති බව මට සටහන් නොකර සිටිය නොහැක. ඔබට ඒවායේ වැඩි විස්තර කියවිය හැකියREADME . - බහු නූල් කිරීම සඳහා වන ප්රවේශය "තනි ලේඛක / බහු පාඨක" යෝජනා ක්රමය මගින් විස්තර කෙරේ. ලේඛකයන් එකිනෙකා අවහිර කරයි, නමුත් පාඨකයන් අවහිර නොකරන්න. පාඨකයන් ලේඛකයන් හෝ එකිනෙකා අවහිර නොකරයි.
- කැදලි ගනුදෙනු සඳහා සහාය.
- බහුවිධ සහාය.
LMDB වල Multiversion එක කොච්චර හොදද කියනවා නම් මට ඒක ක්රියාවෙන් පෙන්නන්න ඕන. පහත කේතයෙන් ඔබට පෙනෙන්නේ සෑම ගනුදෙනුවක්ම එය විවෘත කරන අවස්ථාවේ පවතින දත්ත සමුදායේ අනුවාදය සමඟ හරියටම ක්රියා කරන බවත්, පසුව සිදුවන සියලුම වෙනස්කම් වලින් සම්පූර්ණයෙන්ම හුදකලා වී ඇති බවත්ය. ගබඩාව ආරම්භ කිරීම සහ එයට පරීක්ෂණ වාර්තාවක් එකතු කිරීම රසවත් කිසිවක් නියෝජනය නොකරයි, එබැවින් මෙම චාරිත්ර නරක් වීම යටතේ ඉතිරි වේ.
පරීක්ෂණ ප්රවේශයක් එකතු කිරීම
MDB_env *env;
MDB_dbi dbi;
MDB_txn *txn;
mdb_env_create(&env);
mdb_env_open(env, "./testdb", MDB_NOTLS, 0664);
mdb_txn_begin(env, NULL, 0, &txn);
mdb_dbi_open(txn, NULL, 0, &dbi);
mdb_txn_abort(txn);
char k = 'k';
MDB_val key;
key.mv_size = sizeof(k);
key.mv_data = (void *)&k;
int v = 997;
MDB_val value;
value.mv_size = sizeof(v);
value.mv_data = (void *)&v;
mdb_txn_begin(env, NULL, 0, &txn);
mdb_put(txn, dbi, &key, &value, MDB_NOOVERWRITE);
mdb_txn_commit(txn);
MDB_txn *txn1, *txn2, *txn3;
MDB_val val;
// Открываем 2 транзакции, каждая из которых смотрит
// на версию базы данных с одной записью.
mdb_txn_begin(env, NULL, 0, &txn1); // read-write
mdb_txn_begin(env, NULL, MDB_RDONLY, &txn2); // read-only
// В рамках первой транзакции удаляем из базы данных существующую в ней запись.
mdb_del(txn1, dbi, &key, NULL);
// Фиксируем удаление.
mdb_txn_commit(txn1);
// Открываем третью транзакцию, которая смотрит на
// актуальную версию базы данных, где записи уже нет.
mdb_txn_begin(env, NULL, MDB_RDONLY, &txn3);
// Убеждаемся, что запись по искомому ключу уже не существует.
assert(mdb_get(txn3, dbi, &key, &val) == MDB_NOTFOUND);
// Завершаем транзакцию.
mdb_txn_abort(txn3);
// Убеждаемся, что в рамках второй транзакции, открытой на момент
// существования записи в базе данных, её всё ещё можно найти по ключу.
assert(mdb_get(txn2, dbi, &key, &val) == MDB_SUCCESS);
// Проверяем, что по ключу получен не абы какой мусор, а валидные данные.
assert(*(int *)val.mv_data == 997);
// Завершаем транзакцию, работающей хоть и с устаревшей, но консистентной базой данных.
mdb_txn_abort(txn2);
SQLite සමඟ එකම උපක්රමය උත්සාහ කර කුමක් සිදුවේදැයි බැලීමට මම නිර්දේශ කරමි.
මල්ටිවර්ෂන් iOS සංවර්ධකයෙකුගේ ජීවිතයට ඉතා හොඳ වරප්රසාද ගෙන එයි. මෙම දේපල භාවිතා කරමින්, ඔබට පරිශීලක අත්දැකීම් සලකා බැලීම් මත පදනම්ව, තිර ආකෘති සඳහා දත්ත මූලාශ්රයේ යාවත්කාලීන අනුපාතය පහසුවෙන් සහ ස්වභාවිකව සකස් කළ හැක. උදාහරණයක් ලෙස, පද්ධති මාධ්ය ගැලරියෙන් අන්තර්ගතය ස්වයංක්රීයව පැටවීම වැනි Mail.ru Cloud යෙදුමේ විශේෂාංගයක් ගනිමු. හොඳ සම්බන්ධතාවයක් සමඟ, සේවාදායකයාට තත්පරයකට ඡායාරූප කිහිපයක් සේවාදායකයට එක් කිරීමට හැකි වේ. එක් එක් බාගත කිරීමෙන් පසු ඔබ යාවත්කාලීන කරන්නේ නම් UICollectionView
පරිශීලකයාගේ වලාකුළෙහි මාධ්ය අන්තර්ගතය සමඟ, ඔබට මෙම ක්රියාවලියේදී fps 60ක් සහ සුමට අනුචලනය අමතක කළ හැක. නිතර තිර යාවත්කාලීන කිරීම් වැලැක්වීම සඳහා, ඔබ යටින් පවතින දත්ත වෙනස් වන අනුපාතය කෙසේ හෝ සීමා කළ යුතුය UICollectionViewDataSource
.
දත්ත සමුදාය බහුඅනුවර්තනය සඳහා සහය නොදක්වන්නේ නම් සහ වත්මන් තත්වය සමඟ පමණක් වැඩ කිරීමට ඔබට ඉඩ සලසයි නම්, දත්තවල කාල ස්ථායී ඡායාරූපයක් සෑදීමට ඔබට එය මතකයේ ඇති දත්ත ව්යුහයකට හෝ තාවකාලික වගුවකට පිටපත් කිරීමට අවශ්ය වේ. මෙම ඕනෑම ප්රවේශයක් ඉතා මිල අධික වේ. මතකයේ ගබඩා කිරීමේදී, ගොඩනඟන ලද වස්තු ගබඩා කිරීම නිසා ඇති වන මතකයේ පිරිවැය සහ අතිරික්ත ORM පරිවර්තනයන් සමඟ සම්බන්ධ වූ කාලය තුළ අපට පිරිවැය ලැබේ. තාවකාලික වගුව සම්බන්ධයෙන් ගත් කල, මෙය ඊටත් වඩා මිල අධික සතුටක් වන අතර එය අර්ථවත් වන්නේ සුළු නොවන අවස්ථාවන්හිදී පමණි.
LMDB හි multiversion විසඳුම ඉතා අලංකාර ලෙස ස්ථාවර දත්ත මූලාශ්රයක් පවත්වාගෙන යාමේ ගැටලුව විසඳයි. ගනුදෙනුවක් සහ වොයිලා විවෘත කිරීම පමණක් ප්රමාණවත් වේ - අපි එය සම්පූර්ණ කරන තුරු, දත්ත කට්ටලය සවි කර ඇති බවට සහතික වේ. එහි යාවත්කාලීන වේගය සඳහා තර්කනය දැන් සම්පූර්ණයෙන්ම ඉදිරිපත් කිරීමේ ස්තරය අතේ, සැලකිය යුතු සම්පත්වල උඩිස් කාර්යක් නොමැත.
කර්සර්
B-tree traversal හරහා යතුරු-අගය යුගල හරහා ක්රමානුකූලව පුනරාවර්තනය කිරීම සඳහා කර්සර යාන්ත්රණයක් සපයයි. ඒවා නොමැතිව, අප දැන් හැරී ඇති දත්ත සමුදායේ වගු ඵලදායී ලෙස ආදර්ශනය කිරීමට නොහැකි වනු ඇත.
4.2 මේස ආකෘති නිර්මාණය
යතුරු ඇණවුම් කිරීමේ ගුණය ඔබට මූලික වියුක්තයන් මත වගුවක් වැනි ඉහළ මට්ටමේ වියුක්තයක් තැනීමට ඉඩ සලසයි. සියලුම පරිශීලක ගොනු සහ ෆෝල්ඩර පිළිබඳ තොරතුරු හැඹිලිගත කරන වලාකුළු සේවාලාභියෙකුගේ ප්රධාන වගුවේ උදාහරණය භාවිතා කරමින් මෙම ක්රියාවලිය සලකා බලමු.
වගු සැලැස්ම
ෆෝල්ඩර ගසක් සහිත වගු ව්යුහයක් සකස් කළ යුතු පොදු අවස්ථාවන්ගෙන් එකක් වන්නේ දී ඇති නාමාවලියක් තුළ පිහිටා ඇති සියලුම මූලද්රව්ය තෝරා ගැනීමයි. මේ ආකාරයේ කාර්යක්ෂම විමසුම් සඳහා හොඳ දත්ත සංවිධාන ආකෘතියක් වේ.
පහත පින්තූරයේ දැක්වෙන්නේ, අතේ ඇති කාර්යය මත පදනම්ව, බයිට් අරාවක ආකාරයේ යතුරු නිරූපණයක් පෙනෙන්නේ කෙසේද යන්නයි. මාපිය නාමාවලියෙහි (රතු) හඳුනාගැනීම් සහිත බයිට් පළමුව, පසුව වර්ගය (කොළ) සහ වලිගයේ නම (නිල්) තබා ඇත.පෙරනිමි LMDB සංසන්දනකය මඟින් ශබ්දකෝෂ අනුපිළිවෙලින් වර්ග කර, ඒවා ඇණවුම් කරනු ලබන්නේ අවශ්ය ආකාරය. එකම රතු උපසර්ගය සහිත යතුරු අනුක්රමිකව ගමන් කිරීමෙන් අමතර පසු සැකසුම් අවශ්ය නොවී පරිශීලක අතුරුමුහුණතෙහි (දකුණු පසින්) පෙන්විය යුතු අනුපිළිවෙලට ඒවායේ ආශ්රිත අගයන් අපට ලබා දේ.
අනුක්රමික යතුරු සහ අගයන්
වස්තු ශ්රේණිගත කිරීම සඳහා බොහෝ ක්රම ලෝකයේ සොයාගෙන ඇත. අපට වේගය හැර වෙනත් අවශ්යතාවයක් නොතිබූ බැවින්, අපි අපටම හැකි වේගවත්ම දේ තෝරා ගත්තෙමු - C භාෂා ව්යුහයේ උදාහරණයක් මගින් අල්ලා ගත් මතකයේ ඩම්ප් එකක්, මේ අනුව, නාමාවලි මූලද්රව්යයක යතුර පහත ව්යුහය සමඟ ආකෘතිගත කළ හැකිය. NodeKey
.
typedef struct NodeKey {
EntityId parentId;
uint8_t type;
uint8_t nameBuffer[256];
} NodeKey;
සුරැකීමට NodeKey
වස්තුව තුළ අවශ්ය ගබඩා තුළ MDB_val
ව්යුහයේ ආරම්භයේ ලිපිනය වෙත දත්ත දර්ශකය ස්ථානගත කරන්න, සහ ශ්රිතය සමඟ ඔවුන්ගේ ප්රමාණය ගණනය කරන්න sizeof
.
MDB_val serialize(NodeKey * const key) {
return MDB_val {
.mv_size = sizeof(NodeKey),
.mv_data = (void *)key
};
}
දත්ත සමුදා තේරීමේ නිර්ණායක පිළිබඳ පළමු පරිච්ඡේදයේ, CRUD මෙහෙයුම් තුළ ගතික ප්රතිපාදන අවම කිරීම වැදගත් තේරීම් සාධකයක් ලෙස මම සඳහන් කළෙමි. කාර්ය කේතය serialize
දත්ත ගබඩාවට නව වාර්තා ඇතුළත් කිරීමේදී LMDB සම්බන්ධයෙන් ඒවා සම්පූර්ණයෙන්ම වළක්වා ගත හැකි ආකාරය පෙන්වයි. සේවාදායකයෙන් එන බයිට් අරාව මුලින්ම අට්ටි ව්යුහයන් බවට පරිවර්තනය වන අතර පසුව ඒවා සුළු වශයෙන් ගබඩාවට දමනු ලැබේ. LMDB තුළ ගතික ප්රතිපාදන ද නොමැති බව සලකන විට, ඔබට iOS ප්රමිතීන්ට අනුව අපූරු තත්වයක් ලබා ගත හැකිය - ජාලයේ සිට තැටිය දක්වා වූ සම්පූර්ණ මාර්ගය ඔස්සේ දත්ත සමඟ වැඩ කිරීමට ස්ටැක් මතකය පමණක් භාවිතා කරන්න!
ද්විමය සංසන්දනයකින් යතුරු ඇණවුම් කිරීම
ප්රධාන අනුපිළිවෙල සම්බන්ධය සංසන්දනය කරන විශේෂ ශ්රිතයක් මගින් නියම කෙරේ. එන්ජිම ඒවායේ අඩංගු බයිට් වල අර්ථ ශාස්ත්රය ගැන කිසිවක් නොදන්නා බැවින්, පෙරනිමි සංසන්දනය කරන්නාට බයිටෙන් බයිට සංසන්දනය කිරීම හැර ශබ්දකෝෂ අනුපිළිවෙලට යතුරු සැකසීම හැර වෙනත් විකල්පයක් නොමැත. ව්යුහයන් සංවිධානය කිරීම සඳහා එය භාවිතා කිරීම කපන පොරවකින් රැවුල බෑමට සමාන වේ. කෙසේ වෙතත්, සරල අවස්ථාවන්හිදී මෙම ක්රමය පිළිගත හැකි බව මට පෙනේ. විකල්පය පහත විස්තර කර ඇත, නමුත් මෙහි මම මෙම මාර්ගය දිගේ විසිරී ඇති රේක් කිහිපයක් සටහන් කරමි.
මතක තබා ගත යුතු පළමු දෙය නම් ප්රාථමික දත්ත වර්ගවල මතක නිරූපණයයි. මේ අනුව, සියලුම ඇපල් උපාංගවල, පූර්ණ සංඛ්යා විචල්යයන් ආකෘතියේ ගබඩා කර ඇත
// value (hex dump)
000 (0000)
256 (0001)
001 (0100)
257 (0101)
...
254 (fe00)
510 (fe01)
255 (ff00)
511 (ff01)
මෙම ගැටළුව විසඳීම සඳහා, byte-byte comparator සඳහා සුදුසු ආකෘතියක් තුළ යතුර තුළ පූර්ණ සංඛ්යා ගබඩා කළ යුතුය. පවුලෙන් ලැබෙන කාර්යයන් ඔබට අවශ්ය පරිවර්තනය සිදු කිරීමට උපකාරී වනු ඇත hton*
(විශේෂයෙන් htons
උදාහරණයෙන් ද්විත්ව බයිට් අංක සඳහා).
ක්රමලේඛනයේ නූල් නිරූපණය කිරීමේ ආකෘතිය, ඔබ දන්නා පරිදි, සමස්තයකි
මතක තබා ගත යුතු දෙවන කරුණ නම් packed
.
බාහිර සංසන්දකයක් සමඟ යතුරු ඇණවුම් කිරීම
ද්විමය සංසන්දනය කරන්නෙකුට ප්රධාන සංසන්දනාත්මක තර්කනය ඉතා සංකීර්ණ විය හැක. බොහෝ හේතු වලින් එකක් වන්නේ ව්යුහයන් තුළ තාක්ෂණික ක්ෂේත්ර තිබීමයි. දැනටමත් අපට හුරුපුරුදු ඩිරෙක්ටරි මූලද්රව්යයක් සඳහා යතුරක උදාහරණය භාවිතා කරමින් ඒවායේ සිදුවීම මම නිදර්ශනය කරමි.
typedef struct NodeKey {
EntityId parentId;
uint8_t type;
uint8_t nameBuffer[256];
} NodeKey;
එහි සරල බව තිබියදීත්, අතිමහත් බහුතරයක දී එය මතකය අධික ලෙස පරිභෝජනය කරයි. සාමාන්ය ගොනු සහ ෆෝල්ඩර නම් කලාතුරකින් අක්ෂර 256-20 ඉක්මවන නමුත් නම සඳහා වන බෆරය බයිට් 30ක් ගනී.
වාර්තාවක ප්රමාණය ප්රශස්ත කිරීම සඳහා වන එක් සම්මත ක්රමයක් නම් එය සැබෑ ප්රමාණයට "කපා දැමීම" වේ. එහි සාරය නම් සියලුම විචල්ය-දිග ක්ෂේත්රවල අන්තර්ගතය ව්යුහයේ අවසානයේ බෆරයක ගබඩා කර ඇති අතර ඒවායේ දිග වෙනම විචල්යවල ගබඩා කර ඇත. මෙම ප්රවේශයට අනුව යතුර NodeKey
පහත පරිදි පරිවර්තනය වේ.
typedef struct NodeKey {
EntityId parentId;
uint8_t type;
uint8_t nameLength;
uint8_t nameBuffer[256];
} NodeKey;
තවද, අනුක්රමික කරන විට, දත්ත ප්රමාණය නියම කර නොමැත sizeof
සම්පූර්ණ ව්යුහය, සහ සියලුම ක්ෂේත්රවල ප්රමාණය ස්ථාවර දිගක් සහ බෆරයේ ඇත්ත වශයෙන්ම භාවිතා කරන කොටසේ ප්රමාණයයි.
MDB_val serialize(NodeKey * const key) {
return MDB_val {
.mv_size = offsetof(NodeKey, nameBuffer) + key->nameLength,
.mv_data = (void *)key
};
}
ප්රතිනිර්මාණය කිරීමේ ප්රතිඵලයක් ලෙස, යතුරු මගින් අල්ලා ගත් අවකාශයේ සැලකිය යුතු ඉතිරියක් අපට ලැබුණි. කෙසේ වෙතත්, තාක්ෂණික ක්ෂේත්රය හේතුවෙන් nameLength
, පෙරනිමි ද්විමය සංසන්දනකය යතුරු සංසන්දනය සඳහා තවදුරටත් සුදුසු නොවේ. අපි එය අපගේම ලෙස ප්රතිස්ථාපනය නොකරන්නේ නම්, නමට වඩා වර්ග කිරීමේදී නමේ දිග ප්රමුඛතා සාධකයක් වනු ඇත.
LMDB සෑම දත්ත සමුදායකටම තමන්ගේම ප්රධාන සංසන්දන කාර්යයක් ලබා ගැනීමට ඉඩ සලසයි. මෙය ශ්රිතය භාවිතයෙන් සිදු කෙරේ mdb_set_compare
විවෘත කිරීමට පෙර දැඩි ලෙස. පැහැදිලි හේතු නිසා, දත්ත සමුදායේ ජීවිත කාලය පුරාම එය වෙනස් කළ නොහැක. සංසන්දනය කරන්නාට ආදානය ලෙස ද්විමය ආකෘතියෙන් යතුරු දෙකක් ලැබෙන අතර, ප්රතිදානයේදී එය සංසන්දනාත්මක ප්රතිඵලය ලබා දෙයි: (-1) ට අඩු, (1) ට වඩා වැඩි හෝ (0 ට සමාන). සඳහා ව්යාජ කේතය NodeKey
ඒ වගේ.
int compare(MDB_val * const a, MDB_val * const b) {
NodeKey * const aKey = (NodeKey * const)a->mv_data;
NodeKey * const bKey = (NodeKey * const)b->mv_data;
return // ...
}
දත්ත සමුදායේ ඇති සියලුම යතුරු එකම වර්ගයේ පවතින තාක් කල්, යෙදුම් යතුරු ව්යුහයේ වර්ගයට ඒවායේ බයිට් නිරූපණය කොන්දේසි විරහිතව වාත්තු කිරීම නීත්යානුකූල වේ. මෙහි එක් සූක්ෂ්මතාවයක් ඇත, නමුත් එය "කියවන වාර්තා" උපවගන්තියේ පහත සාකච්ඡා කරනු ඇත.
අනුක්රමික අගයන්
LMDB ගබඩා කර ඇති වාර්තාවල යතුරු සමඟ අතිශයින් තීව්ර ලෙස ක්රියා කරයි. ඔවුන් එකිනෙකා සමඟ සංසන්දනය කිරීම ඕනෑම ව්යවහාරික මෙහෙයුමක රාමුව තුළ සිදු වන අතර, සම්පූර්ණ විසඳුමේ කාර්ය සාධනය සංසන්දනය කිරීමේ වේගය මත රඳා පවතී. පරමාදර්ශී ලෝකයක, පෙරනිමි ද්විමය සංසන්දනකය යතුරු සංසන්දනය කිරීමට ප්රමාණවත් විය යුතුය, නමුත් ඔබට ඔබේම දෑ භාවිතා කිරීමට සිදුවුවහොත්, එහි ඇති යතුරු ඉවත් කිරීමේ ක්රියා පටිපාටිය හැකි තරම් වේගවත් විය යුතුය.
දත්ත සමුදාය වාර්තාවේ (අගය) වටිනාකම කොටස ගැන විශේෂයෙන් උනන්දු නොවේ. එය බයිට් නිරූපණයකින් වස්තුවකට පරිවර්තනය කිරීම සිදුවන්නේ එය දැනටමත් යෙදුම් කේතය මගින් අවශ්ය වූ විට පමණි, උදාහරණයක් ලෙස, එය තිරය මත පෙන්වීමට. මෙය සිදුවන්නේ සාපේක්ෂව කලාතුරකින් බැවින්, මෙම ක්රියා පටිපාටිය සඳහා වේග අවශ්යතා එතරම් තීරණාත්මක නොවන අතර, එය ක්රියාත්මක කිරීමේදී අපට පහසුව කෙරෙහි අවධානය යොමු කිරීමට වඩා නිදහස්ය.උදාහරණයක් ලෙස, තවමත් බාගත කර නොමැති ගොනු පිළිබඳ පාර-දත්ත අනුක්රමික කිරීමට, අපි භාවිතා කරමු. NSKeyedArchiver
.
NSData *data = serialize(object);
MDB_val value = {
.mv_size = data.length,
.mv_data = (void *)data.bytes
};
කෙසේ වෙතත්, කාර්ය සාධනය තවමත් වැදගත් වන අවස්ථා තිබේ. උදාහරණයක් ලෙස, පරිශීලක වලාකුළක ගොනු ව්යුහය පිළිබඳ metainformation සුරැකීමේදී, අපි භාවිතා කරන්නේ එම මතක ඩම්ප් එකයි. ඒවායේ අනුක්රමික නිරූපණයක් උත්පාදනය කිරීමේ කාර්යයේ විශේෂත්වය වන්නේ නාමාවලියක මූලද්රව්ය පන්ති ධුරාවලියක් මගින් ආදර්ශනය කර තිබීමයි.
C භාෂාවෙන් එය ක්රියාත්මක කිරීම සඳහා, උරුමක්කාරයන්ගේ නිශ්චිත ක්ෂේත්ර වෙනම ව්යුහයන් තුළ තබා ඇති අතර, පාදම සමඟ ඔවුන්ගේ සම්බන්ධතාවය වර්ගය සමිති ක්ෂේත්රයක් හරහා නිශ්චිතව දක්වා ඇත. වෘත්තීය සමිතියේ සැබෑ අන්තර්ගතයන් තාක්ෂණික ගුණාංග වර්ගය හරහා නියම කර ඇත.
typedef struct NodeValue {
EntityId localId;
EntityType type;
union {
FileInfo file;
DirectoryInfo directory;
} info;
uint8_t nameLength;
uint8_t nameBuffer[256];
} NodeValue;
වාර්තා එකතු කිරීම සහ යාවත්කාලීන කිරීම
අනුක්රමික යතුර සහ අගය ගබඩාවට එකතු කළ හැක. මෙය සිදු කිරීම සඳහා, කාර්යය භාවිතා කරන්න mdb_put
.
// key и value имеют тип MDB_val
mdb_put(..., &key, &value, MDB_NOOVERWRITE);
වින්යාස කිරීමේ අදියරේදී, එකම යතුර සමඟ විවිධ වාර්තා ගබඩා කිරීමට ගබඩාවට අවසර දීම හෝ තහනම් කිරීම කළ හැකිය. යතුරු අනුපිටපත් කිරීම තහනම් නම්, වාර්තාවක් ඇතුළත් කිරීමේදී, පවතින වාර්තාවක් යාවත්කාලීන කිරීමට අවසර තිබේද නැද්ද යන්න ඔබට තීරණය කළ හැකිය. කේත දෝෂයක ප්රති result ලයක් ලෙස පමණක් කැඩී යාම සිදුවිය හැකි නම්, ධජය නියම කිරීමෙන් ඔබට එයින් ආරක්ෂා විය හැකිය NOOVERWRITE
.
ඇතුළත් කිරීම් කියවීම
LMDB හි වාර්තා කියවීමට, ශ්රිතය භාවිතා කරන්න mdb_get
. යතුරු-අගය යුගලය කලින් ඉවත දැමූ ව්යුහයන් මගින් නිරූපණය කරන්නේ නම්, මෙම ක්රියා පටිපාටිය මේ ආකාරයෙන් පෙනේ.
NodeValue * const readNode(..., NodeKey * const key) {
MDB_val rawKey = serialize(key);
MDB_val rawValue;
mdb_get(..., &rawKey, &rawValue);
return (NodeValue * const)rawValue.mv_data;
}
ඉදිරිපත් කරන ලද ලැයිස්තුගත කිරීම මඟින් ව්යුහය ඩම්ප් හරහා අනුක්රමිකකරණය ලිවීමේදී පමණක් නොව දත්ත කියවීමේදී ගතික ප්රතිපාදන ඉවත් කිරීමට ඔබට ඉඩ සලසයි. ශ්රිතයෙන් ව්යුත්පන්නයි mdb_get
දත්ත සමුදාය වස්තුවේ බයිට් නිරූපණය ගබඩා කරන අතථ්ය මතක ලිපිනය දෙස දර්ශකය හරියටම බලයි. ඇත්ත වශයෙන්ම, අපට ඉතා ඉහළ දත්ත කියවීමේ වේගයක් නොමිලේ ලබා දෙන ORM වර්ගයක් ලැබේ. ප්රවේශයේ සියලු අලංකාරය තිබියදීත්, එය සමඟ සම්බන්ධ වූ විශේෂාංග කිහිපයක් මතක තබා ගැනීම අවශ්ය වේ.
- කියවීමට පමණක් වූ ගනුදෙනුවක් සඳහා, වටිනාකම් ව්යුහය වෙත දර්ශකය වලංගුව පවතිනුයේ ගනුදෙනුව වසා දමන තෙක් පමණි. කලින් සඳහන් කළ පරිදි, වස්තුවක් පිහිටා ඇති B-tree පිටු, පිටපත්-මත-ලිවීමේ මූලධර්මයට ස්තූතිවන්ත වන අතර, ඒවා අවම වශයෙන් එක් ගනුදෙනුවකින් සඳහන් වන තාක් කල් නොවෙනස්ව පවතී. ඒ සමගම, ඔවුන් හා සම්බන්ධ අවසාන ගනුදෙනුව අවසන් වූ වහාම, නව දත්ත සඳහා පිටු නැවත භාවිතා කළ හැකිය. වස්තූන් උත්පාදනය කළ ගනුදෙනුව නොනැසී පැවතීමට අවශ්ය නම්, ඒවා තවමත් පිටපත් කළ යුතුය.
- කියවීම් ලිවීමේ ගනුදෙනුවක් සඳහා, ලැබෙන අගය ව්යුහයට දර්ශකය වලංගු වන්නේ පළමු වෙනස් කිරීමේ ක්රියා පටිපාටිය (දත්ත ලිවීම හෝ මකා දැමීම) දක්වා පමණි.
- ව්යුහය වුවද
NodeValue
සම්පූර්ණ නොවන නමුත් කපා ඇත ("බාහිර සංසන්දකයක් භාවිතයෙන් යතුරු ඇණවුම් කිරීම" යන උපවගන්තිය බලන්න), ඔබට දර්ශකය හරහා එහි ක්ෂේත්ර වෙත ආරක්ෂිතව ප්රවේශ විය හැක. ප්රධාන දෙය නම් එය නොසලකා හැරීම නොවේ! - කිසිදු තත්වයක් යටතේ ලැබුණු දර්ශකය හරහා ව්යුහය වෙනස් නොකළ යුතුය. සියලුම වෙනස්කම් සිදු කළ යුත්තේ ක්රමය හරහා පමණි
mdb_put
. කෙසේ වෙතත්, මෙම ව්යුහය පිහිටා ඇති මතක ප්රදේශය කියවීමට පමණක් ප්රකාරයට සිතියම්ගත කර ඇති බැවින් ඔබට මෙය කිරීමට කොතරම් අපහසු වුවත්, එය කළ නොහැකි වනු ඇත. - උදාහරණයක් ලෙස, කාර්යය භාවිතයෙන් උපරිම ගබඩා ප්රමාණය වැඩි කිරීම සඳහා ගොනුවක් ක්රියාවලි ලිපින අවකාශයට නැවත සකස් කරන්න
mdb_env_set_map_size
පොදුවේ සියලුම ගනුදෙනු සහ අදාළ ආයතන සම්පූර්ණයෙන්ම අවලංගු කරන අතර විශේෂයෙන් ඇතැම් වස්තූන් වෙත යොමු කරයි.
අවසාන වශයෙන්, තවත් අංගයක් කෙතරම් ද්රෝහී ද යත්, එහි සාරය හෙළි කිරීම තවත් ඡේදයකට නොගැලපේ. B-tree ගැන පරිච්ඡේදයේ, මම එහි පිටු මතකයේ සකස් කර ඇති ආකාරය පිළිබඳ රූප සටහනක් ලබා දුන්නා. අනුක්රමික දත්ත සහිත බෆරයේ ආරම්භයේ ලිපිනය නියත වශයෙන්ම අත්තනෝමතික විය හැකි බව මෙයින් පහත දැක්වේ. මේ නිසා, ඔවුන් වෙත දර්ශකය ව්යුහය තුළ ලැබී ඇත MDB_val
සහ ව්යුහයකට පොයින්ටරයක් දක්වා අඩු කළ විට, එය සාමාන්ය නඩුවේදී නොගැලපෙන බව පෙනේ. ඒ අතරම, සමහර චිප්ස් වල ගෘහ නිර්මාණ ශිල්පයට (iOS නම් මෙය armv7 වේ) ඕනෑම දත්තයක ලිපිනය යන්ත්ර වචනයේ ප්රමාණයේ ගුණාකාරයක් හෝ, වෙනත් වචන වලින් කිවහොත්, පද්ධතියේ බිට් ප්රමාණය ( armv7 සඳහා එය බිටු 32කි). වෙනත් වචන වලින් කිවහොත්, මෙහෙයුමක් වැනි *(int *foo)0x800002
ඔවුන් මත පැන යාමට සමාන වන අතර තීන්දුවක් සමඟ ක්රියාත්මක කිරීමට මඟ පාදයි EXC_ARM_DA_ALIGN
. එවැනි දුක්ඛිත ඉරණමක් වළක්වා ගැනීමට ක්රම දෙකක් තිබේ.
පළමුවැන්න පැහැදිලිවම පෙළගස්වන ලද ව්යුහයකට දත්ත මූලික පිටපත් කිරීම දක්වා දිව යයි. උදාහරණයක් ලෙස, අභිරුචි සංසන්දකයක මෙය පහත පරිදි පිළිබිඹු වේ.
int compare(MDB_val * const a, MDB_val * const b) {
NodeKey aKey, bKey;
memcpy(&aKey, a->mv_data, a->mv_size);
memcpy(&bKey, b->mv_data, b->mv_size);
return // ...
}
විකල්ප ක්රමයක් නම් ප්රධාන වටිනාකම් ව්යුහයන් ආරෝපණය-පෙළගැසී නොතිබිය හැකි බව සම්පාදකයාට කල්තියා දැනුම් දීමයි. aligned(1)
. ARM මත ඔබට එකම බලපෑමක් ඇති කළ හැකිය
typedef struct __attribute__((packed)) NodeKey {
uint8_t parentId;
uint8_t type;
uint8_t nameLength;
uint8_t nameBuffer[256];
} NodeKey;
පරාස විමසුම්
වාර්තා සමූහයක් පුනරාවර්තනය කිරීමට, LMDB කර්සරය සාරාංශයක් සපයයි. අපට දැනටමත් හුරුපුරුදු පරිශීලක වලාකුළු පාර-දත්ත සහිත වගුවක උදාහරණය භාවිතා කරමින් එය සමඟ වැඩ කරන්නේ කෙසේදැයි බලමු.
නාමාවලියක ගොනු ලැයිස්තුවක් ප්රදර්ශනය කිරීමේ කොටසක් ලෙස, එහි ළමා ගොනු සහ ෆෝල්ඩර සම්බන්ධ කර ඇති සියලුම යතුරු සොයා ගැනීමට අවශ්ය වේ. පෙර උප කොටස් වලදී අපි යතුරු වර්ග කළා NodeKey
එවැනි ඒවා මූලික වශයෙන් මාපිය නාමාවලියෙහි හැඳුනුම්පත මගින් ඇණවුම් කරනු ලැබේ. මේ අනුව, තාක්ෂණික වශයෙන්, ෆෝල්ඩරයක අන්තර්ගතය නැවත ලබා ගැනීමේ කාර්යය, දී ඇති උපසර්ගයක් සහිත යතුරු සමූහයේ ඉහළ මායිම මත කර්සරය තබා පහළ මායිම වෙත පුනරාවර්තනය වේ.
ඉහළ සීමාව අනුක්රමික සෙවුමකින් කෙලින්ම සොයාගත හැකිය. මෙය සිදු කිරීම සඳහා, කර්සරය දත්ත සමුදායේ ඇති සම්පූර්ණ යතුරු ලැයිස්තුවේ ආරම්භයේ තබා ඇති අතර මව් නාමාවලියෙහි හඳුනාගැනීමේ යතුරක් ඊට පහළින් දිස්වන තෙක් තවදුරටත් වැඩි වේ. මෙම ප්රවේශය පැහැදිලි අවාසි 2 ක් ඇත:
- රේඛීය සෙවුම් සංකීර්ණත්වය, දන්නා පරිදි, සාමාන්යයෙන් ගස්වල සහ විශේෂයෙන් B-ගසක එය ලඝුගණක කාලයකින් සිදු කළ හැක.
- නිෂ්ඵල ලෙස, සොයන පිටුවට පෙර ඇති සියලුම පිටු ගොනුවේ සිට ප්රධාන මතකයට ඔසවනු ලැබේ, එය අතිශයින් මිල අධිකය.
වාසනාවකට මෙන්, LMDB API මඟින් කර්සරය මුලින් ස්ථානගත කිරීමට ඵලදායී ක්රමයක් සපයයි.මෙය සිදු කිරීම සඳහා, ඔබ විසින් අගය පැහැදිලිවම අන්තරයේ ඉහළ මායිමේ පිහිටා ඇති යතුරට වඩා අඩු හෝ සමාන යතුරක් ජනනය කළ යුතුය. උදාහරණයක් ලෙස, ඉහත රූපයේ ලැයිස්තුවට අදාළව, අපට ක්ෂේත්රය ඇති යතුරක් සෑදිය හැකිය parentId
2 ට සමාන වනු ඇත, ඉතිරි සියල්ල ශුන්ය වලින් පිරී ඇත. එවැනි අර්ධ වශයෙන් පිරවූ යතුරක් ශ්රිත ආදානයට සපයනු ලැබේ mdb_cursor_get
මෙහෙයුම පෙන්නුම් කරයි MDB_SET_RANGE
.
NodeKey upperBoundSearchKey = {
.parentId = 2,
.type = 0,
.nameLength = 0
};
MDB_val value, key = serialize(upperBoundSearchKey);
MDB_cursor *cursor;
mdb_cursor_open(..., &cursor);
mdb_cursor_get(cursor, &key, &value, MDB_SET_RANGE);
යතුරු සමූහයක ඉහළ මායිම හමු වුවහොත්, අපි එය මුණගැසෙන තුරු හෝ යතුර තවත් එකක් හමුවන තුරු නැවත නැවත කියමු. parentId
, නැත්තම් යතුරු කොහෙත්ම ඉවර වෙන්නේ නෑ.
do {
rc = mdb_cursor_get(cursor, &key, &value, MDB_NEXT);
// processing...
} while (MDB_NOTFOUND != rc && // check end of table
IsTargetKey(key)); // check end of keys group
හොඳ දෙය නම් mdb_cursor_get භාවිතා කරන පුනරාවර්තනයේ කොටසක් ලෙස, අපට යතුර පමණක් නොව අගය ද ලැබේ. නියැදීමේ කොන්දේසි සපුරාලීම සඳහා, ඔබට වෙනත් දේ අතර, වාර්තාවේ වටිනාකම් කොටසේ ක්ෂේත්ර පරීක්ෂා කිරීමට අවශ්ය නම්, අමතර අභිනයන් නොමැතිව ඒවාට ප්රවේශ විය හැකිය.
4.3 වගු අතර ආකෘති සම්බන්ධතා
මේ වන විට, අපි තනි වගු දත්ත සමුදායක් සැලසුම් කිරීමේ සහ වැඩ කිරීමේ සියලු අංග සලකා බැලීමට සමත් වී ඇත. වගුවක් යනු එකම වර්ගයේ යතුරු-අගය යුගල වලින් සමන්විත වර්ග කළ වාර්තා සමූහයක් බව අපට පැවසිය හැකිය. ඔබ යතුරක් සෘජුකෝණාස්රයක් ලෙසත් ඒ ආශ්රිත අගය සමාන්තර නලයක් ලෙසත් ප්රදර්ශනය කරන්නේ නම්, ඔබට දත්ත සමුදායේ දෘශ්ය රූප සටහනක් ලැබේ.
කෙසේ වෙතත්, සැබෑ ජීවිතයේ දී එතරම් කුඩා ලේ වැගිරීමකින් ලබා ගත හැක්කේ කලාතුරකිනි. බොහෝ විට දත්ත සමුදායකදී, පළමුව, වගු කිහිපයක් තිබීම අවශ්ය වන අතර, දෙවනුව, ප්රාථමික යතුරට වඩා වෙනස් අනුපිළිවෙලකට ඒවා තුළ තේරීම් සිදු කිරීම අවශ්ය වේ. මෙම අවසාන කොටස ඔවුන්ගේ නිර්මාණය සහ අන්තර් සම්බන්ධතාවයේ ගැටළු සඳහා කැප කර ඇත.
දර්ශක වගු
වලාකුළු යෙදුමට "ගැලරි" කොටසක් ඇත. එය දිනය අනුව වර්ග කරන ලද සම්පූර්ණ වලාකුළෙන් මාධ්ය අන්තර්ගතය පෙන්වයි. එවැනි තේරීමක් ප්රශස්ත ලෙස ක්රියාත්මක කිරීම සඳහා, ප්රධාන වගුව අසල ඔබට නව වර්ගයේ යතුරු සමඟ තවත් එකක් සෑදිය යුතුය. ඒවායේ ප්රාථමික වර්ග කිරීමේ නිර්ණායකය ලෙස ක්රියා කරන ගොනුව නිර්මාණය කළ දිනය සහිත ක්ෂේත්රයක් අඩංගු වනු ඇත. නව යතුරු ප්රධාන වගුවේ ඇති යතුරු වලට සමාන දත්ත සඳහන් කරන බැවින් ඒවා දර්ශක යතුරු ලෙස හැඳින්වේ. පහත පින්තූරයේ ඔවුන් තැඹිලි පාටින් උද්දීපනය කර ඇත.
එකම දත්ත ගබඩාව තුළ විවිධ වගු වල යතුරු එකිනෙකින් වෙන් කිරීම සඳහා, ඒ සියල්ලටම අමතර තාක්ෂණික ක්ෂේත්ර වගුවක් එක් කරන ලදී. එය වර්ග කිරීම සඳහා ඉහළම ප්රමුඛතාවය ලබා දීමෙන්, අපි පළමුව වගු මගින් සහ වගු තුළ - අපගේම නීතිවලට අනුව යතුරු කාණ්ඩගත කිරීම සාක්ෂාත් කර ගනිමු.
දර්ශක යතුර මූලික යතුර ලෙස එකම දත්ත යොමු කරයි. ප්රාථමික යතුරේ අගය කොටසෙහි පිටපතක් ඇසුරු කිරීම හරහා මෙම දේපල සෘජුව ක්රියාත්මක කිරීම දෘෂ්ටි කෝණයකින් ප්රශස්ත නොවේ:
- ලබා ගත් ඉඩ ප්රමාණය අනුව, පාරදත්ත තරමක් පොහොසත් විය හැක.
- කාර්ය සාධන දෘෂ්ටි කෝණයකින්, නෝඩයක පාර-දත්ත යාවත්කාලීන කිරීමේදී, ඔබට එය යතුරු දෙකක් භාවිතයෙන් නැවත ලිවීමට සිදුවනු ඇත.
- කේත සහය පිළිබඳ දෘෂ්ටි කෝණයෙන්, අපට එක් යතුරු සඳහා දත්ත යාවත්කාලීන කිරීමට අමතක වුවහොත්, ගබඩාවේ දත්ත නොගැලපෙන දෝෂයක් අපට ලැබෙනු ඇත.
ඊළඟට, මෙම අඩුපාඩු ඉවත් කරන්නේ කෙසේදැයි අපි සලකා බලමු.
වගු අතර සබඳතා සංවිධානය කිරීම
දර්ශක වගුව ප්රධාන වගුව සමඟ සම්බන්ධ කිරීම සඳහා රටාව හොඳින් ගැලපේ "යතුර වටිනාකමක් ලෙස". එහි නමට අනුව, දර්ශක වාර්තාවේ අගය කොටස ප්රාථමික යතුරු අගයේ පිටපතකි. මෙම ප්රවේශය ප්රාථමික වාර්තාවේ වටිනාකම කොටසෙහි පිටපතක් ගබඩා කිරීම හා සම්බන්ධ ඉහත සඳහන් සියලු අවාසි ඉවත් කරයි. එකම පිරිවැය වන්නේ දර්ශක යතුර මගින් අගයක් ලබා ගැනීම සඳහා, ඔබ එකක් වෙනුවට දත්ත සමුදාය වෙත විමසුම් 2ක් කළ යුතුය. ක්රමානුකූලව, ප්රතිඵලයක් ලෙස ලැබෙන දත්ත සමුදා ක්රමය මේ ආකාරයට පෙනේ.
වගු අතර සබඳතා සංවිධානය කිරීම සඳහා තවත් රටාවකි "අතිරික්ත යතුර". එහි සාරය නම් යතුරට අමතර ගුණාංග එකතු කිරීමයි, ඒවා වර්ග කිරීම සඳහා නොව, ආශ්රිත යතුර ප්රතිනිර්මාණය කිරීම සඳහා අවශ්ය වේ, Mail.ru Cloud යෙදුමේ එහි භාවිතය පිළිබඳ සැබෑ උදාහරණ ඇත, කෙසේ වෙතත්, ගැඹුරට කිමිදීම වළක්වා ගැනීම සඳහා. නිශ්චිත iOS රාමු වල සන්දර්භය, මම කල්පිත, නමුත් පැහැදිලි උදාහරණයක් දෙන්නෙමි
ක්ලවුඩ් ජංගම සේවාලාභීන්ට පරිශීලකයා වෙනත් පුද්ගලයින් සමඟ බෙදාගෙන ඇති සියලුම ගොනු සහ ෆෝල්ඩර පෙන්වන පිටුවක් ඇත. එවැනි ලිපිගොනු සාපේක්ෂව ස්වල්පයක් ඇති බැවින් සහ ඒවාට සම්බන්ධ ප්රචාරණය පිළිබඳ විවිධ වර්ගයේ නිශ්චිත තොරතුරු රාශියක් ඇති බැවින් (ප්රවේශය ලබා දී ඇත්තේ කාටද, කුමන අයිතිවාසිකම් සමඟද යනාදිය), එහි වටිනාකම කොටස බර කිරීම තාර්කික නොවේ. එය සමඟ ප්රධාන වගුවේ සටහන් කරන්න. කෙසේ වෙතත්, ඔබට එවැනි ගොනු නොබැඳි ලෙස ප්රදර්ශනය කිරීමට අවශ්ය නම්, ඔබ තවමත් එය කොතැනක හෝ ගබඩා කළ යුතුය. ස්වාභාවික විසඳුමක් වන්නේ ඒ සඳහා වෙනම වගුවක් නිර්මාණය කිරීමයි. පහත රූප සටහනේ, එහි යතුර "P" සමඟ උපසර්ග කර ඇති අතර, "ප්රොප්නේම්" යන ස්ථාන දරන්නා වඩාත් නිශ්චිත අගය "පොදු තොරතුරු" සමඟ ප්රතිස්ථාපනය කළ හැක.
නව වගුව නිර්මාණය කරන ලද ගබඩා කිරීම සඳහා සියලුම අද්විතීය පාර-දත්ත, වාර්තාවේ අගය කොටසෙහි තබා ඇත. ඒ සමගම, ප්රධාන වගුවේ දැනටමත් ගබඩා කර ඇති ගොනු සහ ෆෝල්ඩර පිළිබඳ දත්ත අනුපිටපත් කිරීමට ඔබට අවශ්ය නොවේ. ඒ වෙනුවට, අතිරික්ත දත්ත "P" යතුරට "node ID" සහ "timestamp" ක්ෂේත්ර ආකාරයෙන් එකතු කරනු ලැබේ. ඔවුන්ට ස්තූතියි, ඔබට දර්ශක යතුරක් සෑදිය හැකිය, එයින් ඔබට ප්රාථමික යතුරක් ලබා ගත හැකිය, එයින් ඔබට අවසාන වශයෙන් නෝඩ් පාර-දත්ත ලබා ගත හැකිය.
නිගමනය
LMDB ක්රියාත්මක කිරීමේ ප්රතිඵල අපි ධනාත්මකව තක්සේරු කරමු. ඊට පසු, යෙදුම් කැටි ගණන 30% කින් අඩු විය.
සිදු කරන ලද කාර්යයේ ප්රතිඵල iOS කණ්ඩායමෙන් ඔබ්බට අනුනාද විය. දැනට, ඇන්ඩ්රොයිඩ් යෙදුමේ ඇති ප්රධාන "ගොනු" කොටස් වලින් එකක් ද LMDB භාවිතා කිරීමට මාරු වී ඇති අතර, අනෙකුත් කොටස් ද පැමිණෙමින් තිබේ. යතුරු අගය ගබඩාව ක්රියාත්මක කර ඇති C භාෂාව, C++ හි හරස් වේදිකාවක් වටා යෙදුම් රාමුවක් නිර්මාණය කිරීමට හොඳ උපකාරයක් විය. ප්රතිඵලයක් ලෙස ලැබෙන C++ පුස්තකාලය Objective-C සහ Kotlin හි වේදිකා කේතය සමඟ බාධාවකින් තොරව සම්බන්ධ කිරීමට කේත උත්පාදක යන්ත්රයක් භාවිතා කරන ලදී.
මූලාශ්රය: www.habr.com