په iOS غوښتنلیکونو کې د کلیدي ارزښت ډیټابیس LMDB چمک او غربت

په iOS غوښتنلیکونو کې د کلیدي ارزښت ډیټابیس LMDB چمک او غربت

د 2019 په مني کې، د Mail.ru کلاوډ iOS ټیم کې یوه اوږده انتظار پیښه رامنځته شوه. د غوښتنلیک حالت د دوامداره ذخیره کولو اصلي ډیټابیس د ګرځنده نړۍ لپاره خورا بهرني شوی د بریښنایی حافظې نقشه شوی ډیټابیس (LMDB). د کټ لاندې موږ تاسو ته په څلورو برخو کې تفصیلي بیاکتنه وړاندې کوو. لومړی، اجازه راکړئ د داسې غیر معمولي او ستونزمن انتخاب د دلیلونو په اړه خبرې وکړو. بیا به موږ د LMDB جوړښت په زړه کې درې ستنې په پام کې ونیسو: د حافظې نقشه شوي فایلونه ، B+ - ونې ، د لیږد پلي کولو او ملټي ورژن پلي کولو لپاره کاپي پر لیکلو طریقه. په نهایت کې، د خوږ لپاره - عملي برخه. پدې کې به موږ وګورو چې څنګه د ډیټابیس سکیما ډیزاین او پلي کول د څو جدولونو سره ، په شمول د یو شاخص په شمول ، د ټیټې کچې کلیدي ارزښت API په سر کې.

منځپانګې

  1. د تطبیق لپاره هڅونه
  2. د LMDB موقعیت
  3. د LMDB درې ستنې
    3.1. د ویلو #1. د حافظې نقشه شوي فایلونه
    3.2. وییل #2. B+ - ونه
    3.3. وییل #3. کاپي پر لیکه
  4. د کلیدي ارزښت API په سر کې د ډیټا سکیما ډیزاین کول
    4.1. بنسټیز خلاصون
    4.2. د میز ماډلینګ
    4.3. د میزونو ترمنځ د اړیکو ماډل کول

1. د تطبیق لپاره هڅونه

په 2015 کې یو کال، موږ د دې اندازه کولو لپاره ستونزه واخیستله چې زموږ د غوښتنلیک انٹرفیس څو ځله وروسته پاتې کیږي. موږ دا د یو دلیل لپاره وکړل. موږ ډیر پرله پسې شکایتونه ترلاسه کړي چې ځینې وختونه غوښتنلیک د کارونکي عملونو ته ځواب ویل بندوي: تڼۍ نشي فشارولی ، لیستونه نه سکرول کیږي ، او داسې نور. د اندازه کولو میخانیکونو په اړه وویل په AvitoTech کې، نو دلته زه یوازې د شمیرو ترتیب ورکوم.

په iOS غوښتنلیکونو کې د کلیدي ارزښت ډیټابیس LMDB چمک او غربت

د اندازه کولو پایلې زموږ لپاره یو سړه شاور شو. دا معلومه شوه چې د بل هر څه په پرتله د یخنۍ له امله ډیرې ستونزې شتون لري. که د دې حقیقت درک کولو دمخه د کیفیت اصلي تخنیکي شاخص د حادثې وړ و، نو د تمرکز وروسته لیږدول شوی په یخچال کې وړیا.

جوړول ډشبورډ د منجمد سره او له مصرف وروسته کمیتي и کیفیت د دوی د دلیلونو تحلیل، اصلي دښمن روښانه شو - د غوښتنلیک په اصلي موضوع کې د درنو سوداګرۍ منطق اعدام شوی. د دې بې عزتۍ طبیعي عکس العمل د کار جریانونو ته د غورځولو لپاره یو سوځیدونکی هیله وه. د دې ستونزې په سیستماتیک ډول حل کولو لپاره ، موږ د سپک وزن لوبغاړو پراساس څو څو اړخیز جوړښت ته لاره هواره کړه. ما دا د iOS نړۍ لپاره د هغې موافقت ته وقف کړی دوه تارونه په اجتماعي ټویټر او د هابري په اړه مقاله. د اوسني داستان د یوې برخې په توګه، زه غواړم د پریکړې پر هغو اړخونو ټینګار وکړم چې د ډیټابیس انتخاب یې اغیزمن کړی.

د سیسټم تنظیم اداکار ماډل داسې انګیرل کیږي چې ملټي ریډینګ د هغې دوهم جوهر کیږي. په دې کې ماډل توکي د جریان سرحدونو څخه تیریدل خوښوي. او دوی دا کله ناکله او دلته او هلته نه کوي، مګر تقریبا په دوامداره توګه او هر ځای کې

په iOS غوښتنلیکونو کې د کلیدي ارزښت ډیټابیس LMDB چمک او غربت

ډیټابیس په وړاندې شوي ډیاګرام کې یو له بنسټیزو برخو څخه دی. د دې اصلي دنده د میکروپټر پلي کول دي شریک شوی ډیټابیس. که چیرې د تصدۍ نړۍ کې دا د خدماتو ترمینځ د معلوماتو ترکیب تنظیم کولو لپاره کارول کیږي ، نو د اداکار معمارۍ په حالت کې - د تارونو ترمینځ ډیټا. په دې توګه، موږ یو ډیټابیس ته اړتیا لرو چې حتی لږ تر لږه ستونزې به رامینځته نه کړي کله چې په څو اړخیز چاپیریال کې کار کوي. په ځانګړې توګه، دا پدې مانا ده چې له دې څخه ترلاسه شوي توکي باید لږترلږه د تار څخه خوندي وي، او په مثالي توګه په بشپړ ډول غیر متغیر وي. لکه څنګه چې تاسو پوهیږئ، وروستی کولی شي په ورته وخت کې د څو تارونو څخه پرته له کوم تالاشۍ څخه کار واخیستل شي، کوم چې په فعالیت باندې ګټور اغیزه لري.

په iOS غوښتنلیکونو کې د کلیدي ارزښت ډیټابیس LMDB چمک او غربتدوهم مهم فاکتور چې د ډیټابیس انتخاب یې اغیزمن کړ زموږ کلاوډ API و. دا د ګیټ لخوا منل شوي همغږي کولو طریقې څخه الهام اخیستی و. د هغه په ​​څیر، موږ موخه درلوده آف لائن - لومړی API، کوم چې د بادل پیرودونکو لپاره مناسب ښکاري. داسې انګیرل کیده چې دوی به یوازې یوځل د بادل بشپړ حالت پمپ کړي ، او بیا به په ډیری قضیو کې همغږي کول د بدلونونو رامینځته کولو له لارې پیښ شي. افسوس، دا فرصت لاهم یوازې په تیوریکي زون کې دی، او پیرودونکو په عمل کې د پیچونو سره کار کولو څرنګوالی نه دی زده کړی. د دې لپاره یو شمیر هدفمند دلایل شتون لري، چې د دې لپاره چې د معرفي کولو ځنډ ونه کړي، موږ به د قوسونو شاته پریږدو. اوس، هغه څه چې خورا ډیر په زړه پوري دي د درس لارښوونې پایلې دي چې څه پیښیږي کله چې یو API "A" ووایی او مصرف کونکي یې "B" نه وايي.

نو ، که تاسو تصور وکړئ git ، کوم چې ، کله چې د پل کمانډ اجرا کوي ، په ځایی سنیپ شاټ کې د پیچونو پلي کولو پرځای ، خپل بشپړ حالت د بشپړ سرور حالت سره پرتله کوي ، نو تاسو به په کافي اندازه دقیق نظر ولرئ چې څنګه په بادل کې همغږي کیږي. مراجعین دا اټکل کول اسانه دي چې د دې پلي کولو لپاره ، تاسو اړتیا لرئ د ټولو سرور او محلي فایلونو په اړه د میټا معلوماتو سره په حافظه کې دوه DOM ونې تخصیص کړئ. دا معلومه شوه چې که یو کاروونکي په بادل کې 500 زره فایلونه ذخیره کړي، نو بیا د دې ترکیب کولو لپاره دا اړینه ده چې د 1 ملیون نوډونو سره دوه ونې بیا جوړ او ویجاړ کړئ. مګر هر نوډ یو مجموعه ده چې د فرعي شیانو ګراف لري. په دې رڼا کې، د پروفایل پایلې تمه کیده. دا معلومه شوه چې حتی د ادغام الګوریتم په پام کې نیولو پرته، د ډیری کوچنیو شیانو د رامینځته کولو او وروسته له مینځه وړلو پروسه یو ښه پیسي لګښت لري. وضعیت د دې حقیقت له امله خراب شوی چې د اساسي ترکیب عملیات په لوی شمیر کې شامل دي. د کارن سکریپټونو څخه. د پایلې په توګه، موږ د ډیټابیس په غوره کولو کې دویم مهم معیارونه حل کوو - د شیانو متحرک تخصیص پرته د CRUD عملیاتو پلي کولو وړتیا.

نورې اړتیاوې ډیرې دودیزې دي او د دوی ټول لیست په لاندې ډول دی.

  1. د تار خوندیتوب.
  2. ملټي پروسس کول. د ورته ډیټابیس مثال کارولو غوښتنې لخوا ټاکل شوی چې نه یوازې د تارونو ترمینځ ، بلکه د اصلي غوښتنلیک او iOS توسیعونو ترمینځ هم ترکیب کولو لپاره.
  3. د غیر متغیر شیانو په توګه د ذخیره شوي ادارو استازیتوب کولو وړتیا
  4. د CRUD عملیاتو کې هیڅ متحرک تخصیص نشته.
  5. د اصلي ملکیتونو لپاره د لیږد ملاتړ اسيد: اتومیت، ثبات، انزوا او اعتبار.
  6. په خورا مشهور قضیو کې سرعت.

د دې اړتیاو سیټ سره، SQLite یو ښه انتخاب و او پاتې دی. په هرصورت، د بدیلونو د مطالعې د یوې برخې په توګه، زه یو کتاب ته ورسیدم "د LevelDB سره پیل کول". د هغې تر مشرۍ لاندې، یو بنچمارک لیکل شوی و چې په ریښتیني بادل سناریوګانو کې د مختلف ډیټابیسونو سره د کار سرعت پرتله کوي. پایله زموږ د وحشي تمو څخه ډیره شوه. په خورا مشهور قضیو کې - د ټولو فایلونو په ترتیب شوي لیست کې د کرسر ترلاسه کول او د ورکړل شوي لارښود لپاره د ټولو فایلونو ترتیب شوي لیست - LMDB د SQLite په پرتله 10 ځله ګړندی وګرځید. انتخاب څرګند شو.

په iOS غوښتنلیکونو کې د کلیدي ارزښت ډیټابیس LMDB چمک او غربت

2. د LMDB موقعیت

LMDB یو ډیر کوچنی کتابتون دی (یوازې 10K قطارونه) چې د ډیټابیس ترټولو ټیټ بنسټیز پرت پلي کوي - ذخیره.

په iOS غوښتنلیکونو کې د کلیدي ارزښت ډیټابیس LMDB چمک او غربت

پورتني ډیاګرام ښیي چې د SQLite سره LMDB پرتله کول، کوم چې لوړې کچې پلي کوي، په عمومي توګه د کور ډیټا سره د SQLite څخه ډیر سم ندي. دا به ډیر عادلانه وي چې ورته ذخیره انجنونه د مساوي سیالیو په توګه په ګوته کړئ - BerkeleyDB، LevelDB، Sophia، RocksDB، او داسې نور. دلته حتی پرمختګونه شتون لري چیرې چې LMDB د SQLite لپاره د ذخیره کولو انجن برخې په توګه کار کوي. دا ډول لومړۍ تجربه په ۲۰۱۲ کال کې شوې وه مصرف شوی د LMDB لخوا هاوارډ چو. پایلې دومره په زړه پورې وګرځید چې د هغه نوښت د OSS مینه والو لخوا غوره شو، او په شخص کې یې دوام وموند. LumoSQL. د 2020 په جنوري کې ، د دې پروژې لیکوال ډین شیرر و وړاندې کړی دا په LinuxConfAu کې.

LMDB په عمده توګه د غوښتنلیک ډیټابیسونو لپاره د انجن په توګه کارول کیږي. کتابتون خپله بڼه د پراختیا کونکو ته ورکوي OpenLDAP، څوک چې د دوی د پروژې اساس په توګه د BerkeleyDB څخه خورا ناخوښه وو. د یو معمولي کتابتون څخه پیل کول btree، هاوارډ چو وتوانید چې زموږ د وخت ترټولو مشهور بدیلونه رامینځته کړي. هغه خپل خورا ښه راپور دې کیسې ته او همدارنګه د LMDB داخلي جوړښت ته وقف کړ. "د بریښنایی حافظې نقشه شوی ډیټابیس". د ذخیره کولو تاسیساتو فتح کولو یوه ښه بیلګه د لیونید یورییف (اکا yleo) د هایلوډ 2015 په خپل راپور کې د مثبت ټیکنالوژیو څخه "د LMDB انجن یو ځانګړی اتل دی". په دې کې، هغه د LMDB په اړه د ورته کار په شرایطو کې د ReOpenLDAP پلي کولو په اړه خبرې کوي، او LevelDB لا دمخه د پرتله کولو نیوکې سره مخ شوی. د پلي کولو په پایله کې، مثبت ټیکنالوژي حتی په فعاله توګه وده کونکي فورک درلود MDBX د خورا خوندور ځانګړتیاو سره ، اصلاح کول او بګ فکسونه.

LMDB اکثرا د ذخیره کولو په توګه کارول کیږي. د مثال په توګه، د موزیلا فایرفوکس براوزر غوره کړه دا د یو شمیر اړتیاو لپاره، او، د 9 نسخه، Xcode څخه پیل کیږي غوره د شاخصونو ذخیره کولو لپاره دا SQLite.

انجن د ګرځنده پرمختګ په نړۍ کې هم خپل نښه کړې ده. د هغې د کارولو نښې کیدی شي موندل د ټیلیګرام لپاره د iOS پیرودونکي کې. LinkedIn نور هم لاړ او LMDB یې د خپل کورني ډیټا کیشینګ چوکاټ راکټ ډیټا لپاره د ډیفالټ ذخیره په توګه غوره کړ، چې په اړه یې وویل په 2016 کې د هغه په ​​مقاله کې.

LMDB په بریالیتوب سره په لمر کې د ځای لپاره مبارزه کوي چې د برکلي ډی بی لخوا پریښودل شوی ځای کې وروسته له هغې چې دا د اوریکل کنټرول لاندې راغی. کتابتون د خپل سرعت او اعتبار لپاره خوښ دی، حتی د خپلو ملګرو په پرتله. لکه څنګه چې تاسو پوهیږئ، وړیا ډوډۍ شتون نلري، او زه غواړم د سوداګرۍ بند باندې ټینګار وکړم چې تاسو به د LMDB او SQLite ترمنځ غوره کولو په وخت کې ورسره مخ شئ. پورته انځور په روښانه توګه ښیي چې د سرعت زیاتوالی څنګه ترلاسه کیږي. لومړی، موږ د ډیسک ذخیره کولو په سر کې د خلاصون اضافي پرتونو لپاره پیسې نه ورکوو. دا روښانه ده چې یو ښه معمار لاهم د دوی پرته نشي کولی ، او دوی به په لازمي ډول د غوښتنلیک کوډ کې څرګند شي ، مګر دوی به خورا فرعي وي. دوی به هغه ځانګړتیاوې ونه لري چې د ځانګړي غوښتنلیک لخوا اړین ندي، د بیلګې په توګه، په SQL ژبه کې د پوښتنو لپاره ملاتړ. دوهم، دا ممکنه ده چې د ډیسک ذخیره کولو غوښتنو په اړه د غوښتنلیک عملیاتو نقشه په غوره توګه پلي کړئ. که SQLite زما په کار کې د اوسط غوښتنلیک د اوسط احصایوي اړتیاو پراساس دی، نو تاسو، د غوښتنلیک جوړونکي په توګه، د اصلي کاري بار سناریوګانو څخه ښه خبر یاست. د یو ډیر ګټور حل لپاره، تاسو باید د ابتدايي حل د پراختیا او د هغې د راتلونکي مالتړ لپاره د لوړ قیمت ټاګ تادیه کړئ.

3. د LMDB درې ستنې

د الوتونکو د سترګو څخه LMDB ته د کتلو سره، دا وخت و چې ژور لاړ شو. راتلونکې درې برخې به د اصلي ستنو تحلیل ته وقف شي چې د ذخیره کولو جوړښت یې پروت دی:

  1. د حافظې نقشه شوي فایلونه د ډیسک سره کار کولو او د داخلي ډیټا جوړښتونو ترکیب کولو میکانیزم په توګه.
  2. B+ - د ذخیره شوي معلوماتو د جوړښت تنظیم په توګه.
  3. د ACID لیږد ملکیتونو او ملټي ورژن چمتو کولو لپاره د یوې تګلارې په توګه کاپي پر لیکل.

3.1. د ویلو #1. د حافظې نقشه شوي فایلونه

د حافظې نقشه شوي فایلونه دومره مهم معماري عنصر دي چې حتی د ذخیره کولو په نوم څرګندیږي. ذخیره شوي معلوماتو ته د لاسرسي د کیچ کولو او همغږي کولو مسلې په بشپړ ډول عملیاتي سیسټم ته پاتې دي. LMDB په خپل ځان کې هیڅ کیچ نلري. دا د لیکوال لخوا شعوري پریکړه ده ، ځکه چې د نقشه شوي فایلونو څخه مستقیم ډیټا لوستل تاسو ته اجازه درکوي د انجن پلي کولو کې ډیری کونجونه پرې کړئ. لاندې د دوی د ځینې بشپړ لیست څخه لرې دی.

  1. په ذخیره کې د معلوماتو دوامداره ساتل کله چې د ډیری پروسو سره کار کوي د عملیاتي سیسټم مسؤلیت کیږي. په راتلونکې برخه کې، دا میکانیزم په تفصیل او انځورونو سره بحث کیږي.
  2. د کیچونو نشتوالی د متحرک تخصیص سره تړلي سر څخه LMDB په بشپړ ډول له مینځه وړي. په عمل کې د معلوماتو لوستل پدې معنی دي چې په مجازی حافظه کې سمې پتې ته د پوائنټر ترتیب کول او نور څه ندي. دا د ساینسي افسانې په څیر ښکاري ، مګر د ذخیره کولو سرچینې کوډ کې کالوک ته ټول زنګونه د ذخیره کولو تنظیم کولو فنکشن کې متمرکز دي.
  3. د کیچونو نشتوالی د لاکونو نشتوالی هم معنی لري چې د دوی لاسرسي ترکیب سره تړاو لري. لوستونکي، چې په ورته وخت کې د لوستونکو خپل سري شمیر شتون لري، ډاټا ته د دوی په لاره کې د یو واحد متیکس سره مخ نه کیږي. د دې له امله ، د لوستلو سرعت د CPUs شمیر پراساس مثالی خطي توزیع وړتیا لري. په LMDB کې، یوازې د تعدیل عملیات همغږي کیږي. په یو وخت کې یوازې یو لیکوال کیدی شي.
  4. لږترلږه د کیچ کولو او همغږي کولو منطق په څو اړخیز چاپیریال کې د کار کولو پورې اړوند خورا پیچلي ډول غلطی له مینځه وړي. د Usenix OSDI 2014 کنفرانس کې دوه په زړه پورې ډیټابیس مطالعې شتون درلود: "ټول د فایل سیسټمونه مساوي ندي رامینځته شوي: د کریش - دوامداره غوښتنلیکونو جوړولو پیچلتیا باندې" и "د ساتیرۍ او ګټې لپاره ډیټابیس شکنجه کول". له دوی څخه تاسو کولی شئ د LMDB د بې ساري اعتبار او د ACID لیږد ملکیتونو نږدې بې عیب پلي کولو په اړه معلومات راټول کړئ ، کوم چې د SQLite څخه غوره دی.
  5. د LMDB minimalism ماشین ته اجازه ورکوي چې د دې کوډ نمایش په بشپړ ډول د پروسیسر L1 کیچ کې د راتلونکي سرعت ځانګړتیاو سره موقعیت ولري.

بدبختانه ، په iOS کې ، د حافظې نقشه شوي فایلونو سره ، هرڅه دومره بادل ندي لکه څنګه چې موږ یې غواړو. د دې لپاره چې د دوی سره تړلي نیمګړتیاوې په ډیر شعور سره وغږیږو ، دا اړینه ده چې په عملیاتي سیسټمونو کې د دې میکانیزم پلي کولو عمومي اصول په یاد ولرئ.

د حافظې نقشه شوي فایلونو په اړه عمومي معلومات

په iOS غوښتنلیکونو کې د کلیدي ارزښت ډیټابیس LMDB چمک او غربتد هر غوښتنلیک سره چې چلیږي، عملیاتي سیسټم د پروسې په نوم یوه اداره شریکوي. هرې پروسې ته د ادرسونو یو پرله پسې سلسله تخصیص شوې چې په هغه کې دا هرڅه ځای په ځای کوي چې د کار کولو لپاره ورته اړتیا لري. په ټیټ پته کې د کوډ او هارډ کوډ شوي ډیټا او سرچینو سره برخې شتون لري. بیا د متحرک ادرس ځای وده کونکي بلاک راځي ، چې موږ ته د هپ په نوم پیژندل کیږي. دا د هغو ادارو پتې لري چې د برنامه د عملیاتو پرمهال څرګندیږي. په پورتنۍ برخه کې د حافظې ساحه ده چې د غوښتنلیک سټیک لخوا کارول کیږي. دا یا وده کوي یا قرارداد کوي؛ په بل عبارت، د هغې اندازه هم یو متحرک طبیعت لري. د دې لپاره چې سټیک او هپ د یو بل سره د فشار او مداخلې مخه ونیسي، دوی د پته ځای په مختلفو سرونو کې موقعیت لري. د پورته او ښکته د دوو متحرک برخو ترمنځ یو سوری شتون لري. عملیاتي سیسټم په دې منځنۍ برخه کې پته کاروي ترڅو د پروسې سره مختلف ادارې شریک کړي. په ځانګړې توګه، دا کولی شي په ډیسک کې د فایل سره د پتې یو مشخص دوامداره سیټ شریک کړي. دا ډول فایل ته د حافظې نقشه ویل کیږي

پروسې ته تخصیص شوي پته ځای خورا لوی دی. په تیوریکي توګه، د پتې شمیر یوازې د پوائنټر اندازې پورې محدود دی، کوم چې د سیسټم د بټ ظرفیت لخوا ټاکل کیږي. که فزیکي حافظه د 1-to-1 سره نقشه شوې وي، نو لومړی پروسه به ټول RAM له مینځه یوسي، او د هیڅ ملټي ټاسک کولو خبرې به نه وي.

په هرصورت، زموږ د تجربې څخه موږ پوهیږو چې عصري عملیاتي سیسټمونه کولی شي په ورته وخت کې څومره پروسې ترسره کړي څومره چې وغواړي. دا د دې حقیقت له امله ممکنه ده چې دوی یوازې د کاغذ پروسو ته ډیری حافظه تخصیص کوي ، مګر په حقیقت کې دوی اصلي فزیکي حافظې ته یوازې هغه برخه باروي چې دلته او اوس یې غوښتنه ده. له همدې امله، د پروسې سره تړلې حافظه مجازی بلل کیږي.

په iOS غوښتنلیکونو کې د کلیدي ارزښت ډیټابیس LMDB چمک او غربت

عملیاتي سیسټم مجازی او فزیکي حافظه د یوې ټاکلې اندازې په پاڼو کې تنظیموي. هرڅومره ژر چې د مجازی حافظې یوه ځانګړې پاڼه غوښتنه کې وي، عملیاتي سیسټم دا په فزیکي حافظه کې باروي او په ځانګړي میز کې یې سره سمون لري. که چیرې وړیا سلاټونه شتون ونلري، نو بیا د مخکینۍ بار شوي پاڼې څخه یو ډیسک ته کاپي کیږي، او یو یې په تقاضا کې ځای نیسي. دا کړنلاره، چې موږ به یې په لنډه توګه بیرته راګرځوو، د تبادلې په نوم یادیږي. لاندې انځور د پروسې تشریح کوي. په دې کې، A پاڼه د 0 پته سره پورته شوې او د 4 پتې سره د اصلي حافظې پاڼې کې ځای پر ځای شوې. دا حقیقت د 0 حجرې د ارتباط جدول کې منعکس شوی.

په iOS غوښتنلیکونو کې د کلیدي ارزښت ډیټابیس LMDB چمک او غربت

کیسه دقیقا ورته ده د فایلونو سره په حافظه کې نقشه شوي. په منطقي توګه، دوی په دوامداره توګه او په بشپړه توګه د مجازی پته ځای کې موقعیت لري. په هرصورت، دوی د پاڼې په واسطه د فزیکي حافظې پاڼې ته ننوځي او یوازې د غوښتنې سره سم. د دې ډول پاڼو تعدیل په ډیسک کې د فایل سره همغږي کیږي. په دې توګه، تاسو کولی شئ په ساده ډول په حافظه کې د بایټونو سره کار کولو سره فایل I/O ترسره کړئ - ټول بدلونونه به په اتوماتيک ډول د عملیاتي سیسټم کرنل لخوا سرچینې فایل ته لیږدول کیږي.

لاندې انځور ښیي چې څنګه LMDB خپل حالت همغږي کوي کله چې د مختلف پروسو څخه ډیټابیس سره کار کوي. په ورته فایل کې د مختلف پروسو مجازی حافظې نقشه کولو سره، موږ په حقیقت کې عملیاتي سیسټم مکلف یو چې د دوی د پته ځایونو ځینې بلاکونه د یو بل سره په انتقالي توګه همغږي کړي، چیرته چې LMDB ښکاري.

په iOS غوښتنلیکونو کې د کلیدي ارزښت ډیټابیس LMDB چمک او غربت

یو مهم ټکی دا دی چې LMDB، د ډیفالټ په واسطه، د لیکلو سیسټم کال میکانیزم له لارې د ډیټا فایل بدلوي، او فایل پخپله یوازې د لوستلو حالت کې ښکاره کوي. دا چلند دوه مهمې پایلې لري.

لومړۍ پایله د ټولو عملیاتي سیسټمونو لپاره عام ده. د دې جوهر د غلط کوډ لخوا ډیټابیس ته د غیر ارادي زیان پروړاندې محافظت اضافه کول دي. لکه څنګه چې تاسو پوهیږئ، د پروسې اجرا وړ لارښوونې د دې پتې ځای کې له هر ځای څخه ډیټا ته د لاسرسي لپاره وړیا دي. په ورته وخت کې، لکه څنګه چې موږ یوازې یادونه وکړه، د لوستلو لیکلو حالت کې د فایل ښودلو معنی دا ده چې هر ډول لارښوونې کولی شي دا تعدیل کړي. که هغه دا په غلطۍ سره ترسره کړي، د مثال په توګه، په حقیقت کې په غیر موجود شاخص کې د سري عنصر د بیا لیکلو هڅه کوي، نو هغه کولی شي په ناڅاپي توګه دې پتې ته نقشه شوې فایل بدل کړي، کوم چې به د ډیټابیس فساد لامل شي. که فایل یوازې د لوستلو حالت کې ښودل شوی وي ، نو د ورته پتې ځای بدلولو هڅه به د سیګنال سره د برنامې بیړني پای ته رسیدو لامل شي. SIGSEGV، او فایل به پاتې وي.

دویمه پایله لا دمخه د iOS لپاره ځانګړې ده. نه لیکوال او نه هم کومې بلې سرچینې په واضح ډول دا یادونه کړې، مګر له دې پرته LMDB به په دې ګرځنده عملیاتي سیسټم کې د چلولو لپاره مناسب نه وي. بله برخه د هغې غور ته وقف شوې ده.

په iOS کې د حافظې نقشه شوي فایلونو مشخصات

په 2018 کې په WWDC کې په زړه پورې راپور شتون درلود "iOS حافظه ژور ډوب". دا موږ ته وایی چې په iOS کې ، ټولې پاڼې چې په فزیکي حافظه کې موقعیت لري له 3 ډولونو څخه یو دي: خندا ، فشار شوي او پاک.

په iOS غوښتنلیکونو کې د کلیدي ارزښت ډیټابیس LMDB چمک او غربت

پاکه حافظه د پاڼو مجموعه ده چې د فزیکي حافظې څخه بې درده پورته کیدی شي. هغه معلومات چې دوی پکې شامل دي د اړتیا سره سم د اصلي سرچینو څخه بیرته پورته کیدی شي. یوازې د لوستلو حافظې نقشه شوي فایلونه پدې کټګورۍ کې راځي. iOS په هر وخت کې د حافظې څخه فایل ته نقشه شوي پا pagesې خلاصولو څخه ویره نلري ، ځکه چې دوی تضمین شوي د ډیسک فایل سره همغږي شي.

ټولې بدلې شوې پاڼې په ناپاکه حافظه کې پای ته رسیږي، مهمه نده چې دوی په اصل کې چیرته موقعیت لري. په ځانګړې توګه، د حافظې نقشه شوي فایلونه د دوی سره تړلې مجازی حافظې ته د لیکلو له لارې تعدیل شوي به پدې ډول طبقه بندي شي. د بیرغ سره د LMDB پرانیستل MDB_WRITEMAPپه دې کې د بدلونونو وروسته، تاسو کولی شئ دا په شخصي توګه تایید کړئ

هرڅومره ژر چې یو اپلیکیشن د ډیرې فزیکي حافظې په اخیستلو پیل وکړي ، iOS دا د ناپاک پاڼې کمپریشن تابع کوي. ټوله حافظه چې د ناپاکو او کمپریس شویو پاڼو لخوا نیول شوې ده د غوښتنلیک تش په نامه یادښت فوټپرنټ جوړوي. یوځل چې دا یو ټاکلي حد ارزښت ته ورسیږي ، د OOM وژونکي سیسټم ډیمون د پروسې وروسته راځي او په زور سره یې لغوه کوي. دا د ډیسټاپ عملیاتي سیسټمونو په پرتله د iOS ځانګړتیا ده. په مقابل کې، د فزیکي حافظې څخه ډیسک ته د پاڼو په بدلولو سره د حافظې فوټپرنټ کمول په iOS کې ندي چمتو شوي. لاملونه یوازې اټکل کیدی شي. شاید ډیسک او شا ته د پا pagesو په شدت سره حرکت کول د ګرځنده وسیلو لپاره خورا انرژي مصرفوي ، یا iOS په SSD ډرایو کې د حجرو بیا لیکلو سرچینې خوندي کوي ، یا شاید ډیزاینران د سیسټم له عمومي فعالیت څخه راضي نه وي ، چیرې چې هرڅه شتون لري. په دوامداره توګه بدل شوی. که څه هم وي، حقیقت یو حقیقت پاتې کیږي.

ښه خبر، چې مخکې یې یادونه وشوه، دا دی چې LMDB په ډیفالټ ډول د فایلونو تازه کولو لپاره د mmap میکانیزم نه کاروي. دا پدې مانا ده چې ښودل شوي ډاټا د iOS لخوا د پاک حافظې په توګه طبقه بندي شوي او د حافظې فوټ چاپ کې مرسته نه کوي. تاسو کولی شئ دا د VM ټریکر په نوم د Xcode وسیلې په کارولو سره تایید کړئ. لاندې سکرین شاټ د عملیاتو پرمهال د کلاوډ غوښتنلیک د iOS مجازی حافظې حالت ښیې. په پیل کې، 2 LMDB مثالونه په دې کې پیل شوي. لومړي ته اجازه ورکړل شوې وه چې خپل فایل د مجازی حافظې 1GiB کې ښکاره کړي ، دوهم - 512MiB. د دې حقیقت سره سره چې دواړه ذخیره د اوسیدونکي حافظې یو ټاکلی مقدار نیسي ، هیڅ یو یې د خندا اندازه نه کوي.

په iOS غوښتنلیکونو کې د کلیدي ارزښت ډیټابیس LMDB چمک او غربت

او اوس د بد خبرونو وخت دی. په 64-bit ډیسټاپ عملیاتي سیسټمونو کې د سویپ میکانیزم څخه مننه، هره پروسه کولی شي د خپل احتمالي سویپ لپاره د وړیا هارډ ډیسک ځای په څیر د مجازی پتې ځای ونیسي. په iOS کې د کمپریشن سره د سویپ بدلول په بنسټیز ډول نظریاتي اعظمي کموي. اوس د ژوند ټولې پروسې باید په اصلي (رام لوستلو) حافظه کې فټ شي، او ټول هغه چې مناسب نه وي باید ختم شي. دا لکه څنګه چې پورته ذکر شوي بیان شوي راپور، او په رسمي اسناد. د پایلې په توګه، iOS په جدي توګه د mmap له لارې د تخصیص لپاره موجود حافظه محدودوي. دلته دلته تاسو کولی شئ د حافظې مقدار تجربوي حدود وګورئ چې د دې سیسټم کال په کارولو سره په مختلف وسیلو کې تخصیص کیدی شي. په خورا عصري سمارټ فون ماډلونو کې، iOS د 2 ګیګابایټ لخوا سخاوتمند شوی، او د iPad په غوره نسخو کې - د 4 لخوا. په عمل کې، البته، تاسو باید د ټیټ ملاتړ شوي وسیلو ماډلونو باندې تمرکز وکړئ، چیرته چې هرڅه خورا غمجن دي. حتی بدتر ، په VM ټریکر کې د غوښتنلیک د حافظې حالت ته په کتلو سره ، تاسو به ومومئ چې LMDB یوازینی هغه څخه لرې دی چې د حافظې نقشه کولو ادعا کوي. ښه ټوټې د سیسټم تخصیص کونکو، د سرچینو فایلونو، د عکس چوکاټونو، او نورو کوچنیو ښکار کونکو لخوا خوړل کیږي.

په کلاوډ کې د تجربو د پایلو پراساس، موږ د LMDB لخوا تخصیص شوي حافظې لپاره لاندې جوړ شوي ارزښتونو ته رسیدلي: 384 میګابایټ د 32-bit وسیلو لپاره او 768 د 64-bit وسیلو لپاره. وروسته له دې چې دا حجم کارول کیږي، هر ډول تعدیل عملیات د کوډ سره پای ته رسیږي MDB_MAP_FULL. موږ په خپل نظارت کې دا ډول تېروتنې ګورو، مګر دا دومره کوچنۍ دي چې په دې مرحله کې دوی له پامه غورځول کیدی شي.

د ذخیره کولو لخوا د ډیر حافظې مصرف لپاره غیر څرګند دلیل کیدی شي اوږدمهاله لیږد وي. د دې لپاره چې پوه شي چې دا دوه پیښې څنګه سره تړلې دي، موږ به د LMDB پاتې دوه ستنو په پام کې نیولو سره مرسته وکړو.

3.2. وییل #2. B+ - ونه

د کلیدي ارزښت ذخیره کولو په سر کې د جدولونو تقلید کولو لپاره ، لاندې عملیات باید په API کې شتون ولري:

  1. د نوي عنصر داخلول.
  2. د ورکړل شوي کیلي سره د عنصر لټون وکړئ.
  3. د یو عنصر لرې کول.
  4. د کلیدونو وقفې په ترتیب سره تکرار کړئ.

په iOS غوښتنلیکونو کې د کلیدي ارزښت ډیټابیس LMDB چمک او غربتد معلوماتو ترټولو ساده جوړښت چې کولی شي په اسانۍ سره ټول څلور عملیات پلي کړي د بائنری لټون ونې دی. د دې هر نوډونه د کیلي نمایندګي کوي چې د ماشوم کیلي ټول فرعي سیټ په دوه فرعي ونو ویشي. په کیڼ اړخ کې هغه شامل دي چې د مور او پلار څخه کوچني دي، او په ښي خوا کې هغه شامل دي چې لوی دي. د کیلي ترتیب شوي سیټ ترلاسه کول د یو له کلاسیک ونې څخه د تیریدو له لارې ترلاسه کیږي

بائنری ونې دوه بنسټیز نیمګړتیاوې لري چې د ډیسک پر بنسټ د ډیټا جوړښت په توګه د اغیزمن کیدو مخه نیسي. لومړی، د دوی د توازن کچه د اټکل وړ نه ده. د ونو د ترلاسه کولو لپاره د پام وړ خطر شتون لري په کوم کې چې د مختلفو څانګو لوړوالی خورا توپیر لري، کوم چې د هغه څه په پرتله چې تمه کیږي د لټون الګوریتمیک پیچلتیا د پام وړ خرابوي. دوهم، د نوډونو تر مینځ د کراس لینکونو ډیروالی په حافظه کې د بائنری ونې ځایی ځای څخه محروموي. بند نوډونه (د دوی ترمینځ د اړیکو په اساس) په مجازی حافظه کې په بشپړ ډول مختلف مخونو کې موقعیت لري. د پایلې په توګه، حتی په یوه ونه کې د څو ګاونډیو نوډونو ساده تیریدنه ممکن د پرتله کولو شمیر پاڼو لیدلو ته اړتیا ولري. دا یوه ستونزه ده حتی کله چې موږ د حافظې ډیټا جوړښت په توګه د بائنری ونو اغیزې په اړه وغږیږو ، ځکه چې په دوامداره توګه د پروسیسر کیچ کې د پا pagesو ګرځول ارزانه خوښۍ ندي. کله چې دا د ډیسک څخه د نوډونو سره تړلي پا pagesې په مکرر ډول ترلاسه کولو خبره راځي ، وضعیت په بشپړ ډول رامینځته کیږي د افسوس وړ.

په iOS غوښتنلیکونو کې د کلیدي ارزښت ډیټابیس LMDB چمک او غربتB-ونې، د بائنری ونو ارتقاء ده، هغه ستونزې حل کوي چې په تیرو پراګراف کې پیژندل شوي. لومړی، دوی خپل ځان توازن کوي. دوهم، د دوی هر نوډ د ماشومانو کیلي سیټ په 2 کې نه ویشي، مګر د M ترتیب شوي فرعي سیټونو کې، او د M شمیره خورا لوی کیدی شي، د څو سوو، یا حتی زرګونو په ترتیب سره.

په دې توګه:

  1. هر نوډ ډیر شمیر دمخه ترتیب شوي کیلي لري او ونې خورا لنډې دي.
  2. ونه په حافظه کې د موقعیت د موقعیت ملکیت ترلاسه کوي، ځکه چې هغه کلیدونه چې نږدې ارزښت لري په طبیعي توګه د یو بل سره په ورته یا ګاونډیو نوډونو کې موقعیت لري.
  3. د ټرانزیټ نوډونو شمیر کله چې د لټون عملیاتو په جریان کې د ونې ښکته کیږي کم شوی.
  4. د رینج پوښتنو په جریان کې د لوستل شوي هدف نوډونو شمیر کم شوی ، ځکه چې هر یو یې دمخه د ترتیب شوي کیلي لوی شمیر لري.

په iOS غوښتنلیکونو کې د کلیدي ارزښت ډیټابیس LMDB چمک او غربت

LMDB د معلوماتو ذخیره کولو لپاره د B + ونې په نوم د B + ونې توپیر کاروي. پورتني انځور درې ډوله نوډونه ښیي چې په دې کې شتون لري:

  1. په سر کې ریښه ده. دا د ګودام دننه د ډیټابیس مفهوم پرته نور هیڅ نه کوي. په یوه LMDB مثال کې، تاسو کولی شئ ډیری ډیټابیسونه جوړ کړئ چې نقشه شوي مجازی پته ځای شریکوي. د دوی هر یو له خپل ریښې څخه پیل کیږي.
  2. په ټیټه کچه کې پاڼي دي. دوی او یوازې دوی په ډیټابیس کې زیرمه شوي کلیدي ارزښت جوړه لري. په هرصورت، دا د B+ - ونو ځانګړتیا ده. که منظم B-ونې د ټولو کچو په نوډونو کې د ارزښت برخې ذخیره کړي، نو د B+ توپیر یوازې په ټیټ کې دی. د دې حقیقت په ثابتولو سره، موږ به نور د ونې فرعي ډول ووایو چې په LMDB کې کارول کیږي په ساده ډول د B- ونې.
  3. د ريښو او پاڼو تر منځ د بحري (څانګو) نوډونو سره 0 يا زياتې تخنيکي کچې شتون لري. د دوی دنده دا ده چې د پاڼو تر مینځ د کیلي ترتیب شوي سیټ وویشئ.

په فزیکي توګه، نوډونه د مخکې ټاکل شوي اوږدوالي د حافظې بلاکونه دي. د دوی اندازه په عملیاتي سیسټم کې د حافظې پاڼو د اندازې څو برابره ده، کوم چې موږ پورته بحث وکړ. د نوډ جوړښت لاندې ښودل شوی. سرلیک د میټا معلومات لري، چې تر ټولو څرګند یې د مثال په توګه چکسم دی. بل د آفسیټونو په اړه معلومات راځي چیرې چې د ډیټا سره حجرې موقعیت لري. معلومات کیدای شي یا کیلي وي، که موږ د نیویګیشن نوډونو په اړه وغږیږو، یا د پاڼو په صورت کې د کلیدي ارزښت ټول جوړونه. تاسو کولی شئ په کار کې د پاڼو جوړښت په اړه نور ولولئ "د لوړ فعالیت کلیدي ارزښت پلورنځیو ارزونه".

په iOS غوښتنلیکونو کې د کلیدي ارزښت ډیټابیس LMDB چمک او غربت

د پاڼې نوډونو داخلي منځپانګې سره معامله کولو سره، موږ به په لاندې بڼه کې د LMDB B-tree په ساده ډول استازیتوب وکړو.

په iOS غوښتنلیکونو کې د کلیدي ارزښت ډیټابیس LMDB چمک او غربت

د نوډونو سره پاڼې په ترتیب سره په ډیسک کې موقعیت لري. لوړې شمیرې پاڼې د فایل په پای کې موقعیت لري. د میټا پاڼې په نوم یادیږي د آفسیټونو په اړه معلومات لري چې په واسطه یې د ټولو ونو ریښې موندل کیدی شي. کله چې یو فایل پرانیستل شي، LMDB د یوې معتبر میټا پاڼې په لټه کې د پاڼې له پای څخه تر پیل پورې د فایل پاڼه سکین کوي ​​او د دې له لارې موجوده ډیټابیسونه لټوي.

په iOS غوښتنلیکونو کې د کلیدي ارزښت ډیټابیس LMDB چمک او غربت

اوس، د ډیټا تنظیم منطقي او فزیکي جوړښت په اړه نظر سره، موږ کولی شو د LMDB دریم ستون ته پام وکړو. دا د هغې په مرسته ده چې د ذخیره کولو ټول تعدیلات په لیږد او یو له بل څخه په انزوا کې واقع کیږي، ډیټابیس په ټولیزه توګه د څو اړخیز ملکیت ورکوي.

3.3. وییل #3. کاپي پر لیکه

د B ونې ځینې عملیات د دې نوډونو کې یو لړ بدلونونه شامل دي. یوه بیلګه په نوډ کې نوې کیلي اضافه کول دي چې دمخه یې خپل اعظمي ظرفیت ته رسیدلی. په دې حالت کې، اړینه ده، لومړی، نوډ په دوو برخو وویشئ، او دویم، په خپل مور او پلار کې د نوي زیږون ماشوم نوډ سره یو لینک اضافه کړئ. دا کړنلاره په احتمالي توګه خورا خطرناکه ده. که د کوم دلیل لپاره (حادثه، د بریښنا بندیدل، او نور) د لړۍ څخه یوازې د بدلونونو برخه واقع شي، نو ونه به په متضاد حالت کې پاتې شي.

د ډیټابیس د غلطۍ زغملو لپاره یو دودیز حل دا دی چې د B-درې څنګ ته د ډیسک ډیټا اضافي جوړښت اضافه کړي - د لیږد لاګ چې د لیکلو دمخه لاګ (WAL) په نوم هم پیژندل کیږي. دا یوه فایل دی چې په پای کې د B- Tree ترمیم کولو دمخه د مطلوب عملیات په کلکه لیکل کیږي. په دې توګه، که د ځان تشخیص په وخت کې د معلوماتو فساد کشف شي، ډیټابیس د خپل ځان د تنظیم کولو لپاره د لاګ سره مشوره کوي.

LMDB د غلطۍ زغم میکانیزم په توګه یو بل میتود غوره کړی چې د کاپي پر لیکلو په نوم یادیږي. د دې جوهر دا دی چې په موجوده پاڼه کې د معلوماتو تازه کولو پرځای، دا لومړی په بشپړه توګه کاپي کوي او په کاپي کې ټول بدلونونه کوي.

په iOS غوښتنلیکونو کې د کلیدي ارزښت ډیټابیس LMDB چمک او غربت

بیا، د دې لپاره چې تازه شوي ډاټا شتون ولري، نو اړینه ده چې د نوډ سره لینک بدل کړئ چې په خپل اصلي نوډ کې اوسنی شوی. څرنګه چې د دې لپاره هم ترمیم ته اړتیا ده، دا هم مخکې له مخکې کاپي کیږي. پروسه په تکراري ډول د ریښی ټولې لارې ته دوام ورکوي. د بدلون لپاره وروستی شی د میټا پاڼې ډاټا ده

په iOS غوښتنلیکونو کې د کلیدي ارزښت ډیټابیس LMDB چمک او غربت

که چیرې ناڅاپه پروسه د تازه کولو پروسې په جریان کې خرابه شي، نو یا به نوې میټا پاڼه جوړه نشي، یا دا به په بشپړ ډول ډیسک ته ونه لیکل شي، او د هغې چک سم به غلط وي. په دې دواړو حالتونو کې، نوې پاڼې به د لاسرسي وړ نه وي، مګر زاړه به اغیزمن نشي. دا د LMDB اړتیا له مینځه وړي ترڅو د معلوماتو دوام ساتلو لپاره د مخکینۍ لاګ لیکلو لپاره. په حقیقت کې، په ډیسک کې د ډیټا ذخیره کولو جوړښت چې پورته تشریح شوي په ورته وخت کې خپل فعالیت ترسره کوي. د واضح لیږد لاګ نشتوالی د LMDB یو له ځانګړتیاو څخه دی چې د لوړ ډیټا لوستلو سرعت چمتو کوي.

په iOS غوښتنلیکونو کې د کلیدي ارزښت ډیټابیس LMDB چمک او غربت

پایله لرونکی ډیزاین چې د ضمیمه - یوازې B-درې په نوم یادیږي ، په طبیعي ډول د لیږد جلا کول او څو نسخه چمتو کوي. په LMDB کې، هر خلاص لیږد د اوسني اړونده ونې ریښې سره تړاو لري. تر هغه وخته پورې چې معامله بشپړه شوې نه وي، د هغې سره تړلې پاڼې پاڼې به هیڅکله د ډیټا نوي نسخو لپاره بدلې یا بیا کار نه شي. په دې توګه، تاسو کولی شئ تر هغه وخته پورې کار وکړئ چې تاسو یې د ډیټا د هغه سیټ سره کار کوئ چې په هغه وخت کې اړین وو. معامله پرانستل شوه، حتی که چیرې ذخیره په دې وخت کې په فعاله توګه تازه شي. دا د ملټي ورژن جوهر دی، LMDB زموږ د محبوب لپاره د ډیټا مثالی سرچینه جوړوي UICollectionView. د راکړې ورکړې پرانستلو سره، اړتیا نشته چې د غوښتنلیک د حافظې فوټپرنټ زیات کړئ په چټکۍ سره د حافظې ځینې جوړښت ته اوسني ډیټا پمپولو سره، د دې ویره چې هیڅ شی پاتې نشي. دا ځانګړتیا LMDB د ورته SQLite څخه توپیر کوي، کوم چې نشي کولی د داسې بشپړ انزوا فخر وکړي. په وروستنۍ کې د دوو معاملو پرانستلو او د دوی په یوه کې یو مشخص ریکارډ حذف کول، دا به نور امکان ونلري چې ورته ریکارډ په دویم پاتې یو کې ترلاسه کړي.

د سکې فلیپ اړخ د مجازی حافظې احتمالي د پام وړ لوړ مصرف دی. سلایډ ښیې چې د ډیټابیس جوړښت به څه ډول ښکاري که چیرې دا د 3 خلاص لوستلو لیږدونو سره په ورته وخت کې د ډیټابیس مختلف نسخو ته په کتلو سره تعدیل شي. څرنګه چې LMDB نشي کولی نوډونه بیا وکاروي چې د اوسني لیږد پورې تړلو ریښو څخه د لاسرسي وړ وي، پلورنځي پرته له دې چې په حافظه کې بل څلورم ریښه تخصیص کړي او یو ځل بیا د هغې لاندې بدل شوي پاڼې کلون کړي.

په iOS غوښتنلیکونو کې د کلیدي ارزښت ډیټابیس LMDB چمک او غربت

دلته به ګټور وي چې د حافظې نقشه شوي فایلونو برخه یاد کړئ. داسې بریښي چې د مجازی حافظې اضافي مصرف باید موږ ډیر اندیښمن نه کړي ، ځکه چې دا د غوښتنلیک د حافظې نقشه کې مرسته نه کوي. په هرصورت، په ورته وخت کې، دا یادونه وشوه چې iOS د دې په تخصیص کې خورا ستړی دی، او موږ نشو کولی، لکه په سرور یا ډیسټاپ کې، د 1 terabyte LMDB سیمه چمتو کړو او د دې ځانګړتیا په اړه فکر ونه کړو. که امکان ولري، تاسو باید هڅه وکړئ چې د لیږد ژوند د امکان تر حده لنډ کړئ.

4. د کلیدي ارزښت API په سر کې د ډیټا سکیما ډیزاین کول

راځئ چې د LMDB لخوا چمتو شوي لومړني خلاصونونو ته په کتلو سره زموږ د API تحلیل پیل کړو: چاپیریال او ډیټابیسونه ، کیلي او ارزښتونه ، لیږدونه او کرسر.

د کوډ لیست کولو په اړه یو یادښت

په عامه LMDB API کې ټولې دندې د دوی د کار پایله د خطا کوډ په بڼه بیرته راګرځوي، مګر په ټولو راتلونکو لیستونو کې د دې تایید د لنډیز لپاره له مینځه وړل کیږي. فورک C++ ریپرونه lmdbxx، په کوم کې چې تېروتنې د C++ استثنا په توګه رامینځته شوي.

د IOS یا macOS لپاره پروژې ته د LMDB سره وصل کولو ترټولو ګړندۍ لارې په توګه ، زه وړاندیز کوم زما CocoaPod POSLMDB.

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 کلاوډ غوښتنلیک کې، موږ یوازې د دوو پیرامیټونو اصلي ارزښتونه بدل کړل.

لومړی د مجازی پته ځای اندازه ده چې د ذخیره کولو فایل په کې نقشه شوی. له بده مرغه، حتی په ورته وسیله کې، ځانګړی ارزښت کولی شي د چلولو څخه تر چلولو پورې د پام وړ توپیر ولري. د iOS د دې ځانګړتیا په پام کې نیولو لپاره، د ذخیره کولو اعظمي حجم په متحرک ډول غوره شوی. د یو ټاکلي ارزښت څخه پیل کول، دا په ترتیب سره تر فعالیت پورې نیمایي کیږي mdb_env_open کومه نتیجه به بیرته نه راګرځوي چې له څخه توپیر لري ENOMEM. په تیوري کې، برعکس لاره هم شتون لري - لومړی انجن ته لږترلږه حافظه تخصیص کړئ، او بیا، کله چې غلطی ترلاسه شي، MDB_MAP_FULL، زیات کړئ. په هرصورت، دا خورا ډیر خړ دی. دلیل یې د فنکشن په کارولو سره د حافظې د بیا تخصیص (remap) لپاره پروسیجر دی mdb_env_set_map_size ټولې ادارې باطلوي (کرسر، لیږدونه، کیلي او ارزښتونه) مخکې له انجن څخه ترلاسه شوي. په کوډ کې د پیښو دا بدلون په پام کې نیولو سره به د دې مهم پیچلتیا لامل شي. که په هرصورت، مجازی حافظه ستاسو لپاره خورا مهم وي، نو دا ممکن یو دلیل وي چې هغه فورک ته نږدې کتنه وکړي چې ډیر مخکې تللي دي. MDBX، چیرې چې د اعلان شوي ځانګړتیاو په مینځ کې "د الوتنې په جریان کې د ډیټابیس اندازې اتوماتیک تنظیم" شتون لري.

دوهم پیرامیټر، د ډیفالټ ارزښت چې موږ ته مناسب نه و، د تار خوندیتوب ډاډمن کولو میکانیکونه تنظیموي. له بده مرغه، لږترلږه iOS 10 د تار محلي ذخیره کولو ملاتړ سره ستونزې لري. د دې دلیل لپاره، په پورته مثال کې، ذخیره د بیرغ سره پرانستل کیږي MDB_NOTLS. برسېره پر دې، دا هم اړین و فورک C++ ریپر lmdbxxد دې خاصیت او په دې کې د متغیرونو پرې کول.

ډاټابیسزونه

ډیټابیس د B - ونې جلا بیلګه ده، کوم چې موږ پورته بحث وکړ. د هغې پرانیستل د لیږد دننه واقع کیږي، کوم چې ممکن په لومړي سر کې یو څه عجيب ښکاري.

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;​​

د پرتله کوونکی په کارولو سره، پلورنځی کیلي په پورته ترتیب کې ترتیبوي. که تاسو دا د خپل ځان سره بدل نه کړئ، نو ډیفالټ به وکارول شي، کوم چې دوی په لیکسيګرافیک ترتیب کې د بایټ په واسطه ترتیبوي.

معاملې

د راکړې ورکړې جوړښت په تفصیل سره تشریح شوی پخوانی څپرکی، نو دلته به زه په لنډه توګه د دوی اصلي ملکیتونه تکرار کړم:

  1. د ټولو اساسي ملکیتونو ملاتړ کوي اسيد: اتومیت، ثبات، انزوا او اعتبار. زه نشم کولی مرسته وکړم مګر په یاد ولرئ چې په macOS او iOS کې د پایښت شرایطو کې یوه بګ شتون لري چې په MDBX کې ټاکل شوی و. تاسو کولی شئ په دوی کې نور ولولئ README.
  2. د ملټي ریډینګ طریقه د "واحد لیکوال / څو لوستونکو" سکیم لخوا تشریح شوې. لیکوالان یو بل بندوي، مګر لوستونکي نه بندوي. لوستونکي د لیکوالانو یا یو بل مخه نه نیسي.
  3. د نیست شوي معاملو لپاره ملاتړ.
  4. د څو اړخیز ملاتړ.

په 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 کلاوډ غوښتنلیک یوه ځانګړتیا واخلو لکه د سیسټم میډیا ګالري څخه د مینځپانګې اتومات کول. د ښه ارتباط سره، پیرودونکی کولی شي سرور ته په هره ثانیه کې څو عکسونه اضافه کړي. که تاسو د هر ډاونلوډ وروسته تازه کړئ UICollectionView د کارونکي کلاوډ کې د میډیا مینځپانګې سره ، تاسو کولی شئ د دې پروسې په جریان کې شاوخوا 60 fps او اسانه سکرول هیر کړئ. د سکرین د پرله پسې تازه معلوماتو مخنیوي لپاره ، تاسو اړتیا لرئ په یو ډول نرخ محدود کړئ په کوم کې چې په لاندې کې ډاټا بدلیږي UICollectionViewDataSource.

که ډیټابیس د ملټي ورژن ملاتړ نه کوي او تاسو ته اجازه درکوي یوازې د اوسني اوسني حالت سره کار وکړئ ، نو د ډیټا د وخت مستحکم سنیپ شاټ رامینځته کولو لپاره تاسو اړتیا لرئ دا یا د حافظې ځینې ډیټا جوړښت یا لنډمهاله میز ته کاپي کړئ. د دغو لارو څخه هر یو خورا ګران دی. په حافظه کې د ذخیره کولو په حالت کې، موږ دواړه په حافظه کې لګښتونه ترلاسه کوو، د جوړ شوي شیانو ذخیره کولو له امله رامنځته کیږي، او په وخت کې، د بې ځایه ORM بدلونونو سره تړاو لري. لکه څنګه چې د لنډمهاله میز لپاره، دا یو خورا ګران خوښي ده، یوازې په غیر معمولي قضیو کې احساس کوي.

د LMDB څو اړخیز حل په خورا ښکلي ډول د مستحکم ډیټا سرچینې ساتلو ستونزه حل کوي. دا یوازې د راکړې ورکړې او غږ خلاصولو لپاره کافي دي - تر هغه چې موږ یې بشپړ کړو ، د ډیټا سیټ د ثابت کیدو تضمین کیږي. د دې تازه سرعت لپاره منطق اوس په بشپړ ډول د پریزنټشن پرت په لاس کې دی ، پرته له کوم مهم سرچینو څخه.

کرسرونه

کرسرونه د B-tree traversal له لارې د کلیدي ارزښت جوړه په منظم ډول تکرار کولو میکانیزم چمتو کوي. د دوی پرته، دا به ناشونی وي چې په ډیټابیس کې د میزونو په مؤثره توګه ماډل کړئ، کوم چې موږ اوس ورته مخ کیږو.

4.2. د میز ماډلینګ

د کلیدي ترتیب ملکیت تاسو ته اجازه درکوي د لوړې کچې خلاصون رامینځته کړئ لکه د اساسي خلاصونونو په سر کې میز. راځئ چې دا پروسه د کلاوډ پیرودونکي اصلي میز مثال په کارولو سره په پام کې ونیسو، کوم چې د ټولو کاروونکو فایلونو او فولډرو په اړه معلومات ذخیره کوي.

د جدول سکیما

یو له عامو سناریوګانو څخه چې د میز جوړښت باید د فولډر ونې سره تنظیم شي د ټولو عناصرو انتخاب دی چې په ورکړل شوي لارښود کې موقعیت لري. د دې ډول مؤثره پوښتنو لپاره د ډیټا تنظیم ښه ماډل دی. د واټن لیست. د کلیدي ارزښت ذخیره کولو په سر کې د پلي کولو لپاره ، دا اړینه ده چې د فایلونو او فولډرو کیلي په داسې ډول ترتیب کړئ چې دوی په اصلي لارښود کې د دوی د غړیتوب پراساس ګروپ شوي وي. سربیره پردې ، د وینډوز کارونکي سره پیژندل شوي ب formه کې د لارښود مینځپانګې ښودلو لپاره (لومړی فولډر ، بیا فایلونه ، دواړه په الفبا ترتیب شوي) ، دا اړینه ده چې په کیلي کې ورته اضافي ساحې شاملې کړئ.

لاندې انځور ښیي چې څنګه، په لاس کې د دندې پراساس، د بایټ سرې په بڼه د کیلي نمایندګي ممکن داسې ښکاري. د اصلي لارښود (سرخ) د پیژندونکي سره بایټونه لومړی ځای په ځای شوي ، بیا د ډول (شین) سره او په پای کې د نوم سره (نیلي) کېښودل کیږي. د اړتیا وړ طریقه. په ترتیب سره د ورته سور مختګ سره کیلي تیریدل موږ ته د دوی اړوند ارزښتونه په ترتیب سره راکوي چې دوی باید د کارونکي انٹرفیس (ښي خوا ته) کې ښودل شي ، پرته له کوم اضافي پوسټ پروسس کولو ته اړتیا لري.

په iOS غوښتنلیکونو کې د کلیدي ارزښت ډیټابیس 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 معیارونو سره په زړه پوري وضعیت ترلاسه کړئ - یوازې د سټیک حافظې څخه کار واخلئ ترڅو د شبکې څخه ډیسک ته د ټولې لارې په اوږدو کې د ډیټا سره کار وکړئ!

د بائنری پرتله کونکي سره د کیلي ترتیب کول

د کلیدي ترتیب اړیکه د یو ځانګړي فعالیت لخوا مشخص کیږي چې د پرتله کونکي په نوم یادیږي. څرنګه چې انجن د بایټس د سیمانټیک په اړه هیڅ نه پوهیږي چې دوی پکې شامل دي، ډیفالټ پرتله کوونکی پرته له دې چې په لیکسيګرافیک ترتیب کې کلیدونه تنظیم کړي، د بایټ-بایټ پرتله کولو ته لاره هواروي. د جوړښتونو تنظیم کولو لپاره د دې کارول د ټوټې کولو کلور سره د خړوبولو سره ورته دي. په هرصورت، په ساده قضیو کې زه دا طریقه د منلو وړ وموم. بدیل لاندې تشریح شوی ، مګر دلته به زه د دې لارې په اوږدو کې ویشل شوي یو څو ریکونه یاد کړم.

د یادولو لپاره لومړی شی د لومړني ډیټا ډولونو حافظه نمایندګي ده. په دې توګه، د ایپل په ټولو وسیلو کې، د عدد متغیر په بڼه کې زیرمه شوي کوچنی اډیان. دا پدې مانا ده چې لږترلږه د پام وړ بایټ به په کیڼ اړخ کې وي، او دا به ممکنه نه وي چې د بایټ په واسطه د بایټ پرتله کولو په کارولو سره د عددونو ترتیب کول. د مثال په توګه، د 0 څخه تر 511 پورې د شمیرو سیټ سره د دې کولو هڅه به لاندې پایلې تولید کړي.

// value (hex dump)
000 (0000)
256 (0001)
001 (0100)
257 (0101)
...
254 (fe00)
510 (fe01)
255 (ff00)
511 (ff01)

د دې ستونزې د حل لپاره، انټیجرونه باید په کیلي کې په یوه بڼه کې ذخیره شي چې د بایټ بایټ پرتله کونکي لپاره مناسب وي. د کورنۍ دندې به تاسو سره د اړین بدلون په ترسره کولو کې مرسته وکړي 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) سره مساوي. لپاره Pseudocode 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​
};

په هرصورت، ځینې وختونه شتون لري کله چې فعالیت لاهم مهم دی. د مثال په توګه ، کله چې د کارونکي کلاوډ فایل جوړښت په اړه میټین معلومات خوندي کول ، موږ د شیانو ورته حافظه ډمپ کاروو. د دوی د لړۍ نمایندګۍ رامینځته کولو د دندې ځانګړتیا دا حقیقت دی چې د لارښود عناصر د ټولګیو د درجه بندۍ لخوا ماډل شوي.

په iOS غوښتنلیکونو کې د کلیدي ارزښت ډیټابیس LMDB چمک او غربت

په 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);

د ترتیب کولو په مرحله کې، ذخیره کول اجازه ورکول کیدی شي یا د ورته کیلي سره د ډیری ریکارډونو ذخیره کولو څخه منع شي. که چیرې د کیلي تکرار منع وي، نو کله چې ریکارډ داخل کړئ، تاسو کولی شئ معلومه کړئ چې د موجوده ریکارډ تازه کول اجازه لري که نه. که چیری کول یوازې په کوډ کې د غلطۍ په پایله کې پیښ کیدی شي ، نو تاسو کولی شئ د بیرغ په مشخص کولو سره له دې څخه ځان وژغورئ 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 ترلاسه کوو چې د خورا لوړ ډیټا لوستلو سرعت تقریبا وړیا چمتو کوي. د تګلارې د ټولو ښکلا سره سره، دا اړینه ده چې د هغې سره تړلي څو ځانګړتیاوې په یاد ولرئ.

  1. یوازې د لوستلو لیږد لپاره، د ارزښت جوړښت ته اشاره کوونکی تضمین شوی چې یوازې تر هغه پورې اعتبار لري چې معامله بنده وي. لکه څنګه چې مخکې یادونه وشوه، د B - ونې پاڼې چې په کوم شی کې موقعیت لري، د کاپي پر لیکلو اصولو څخه مننه، تر هغه پورې بدله پاتې کیږي تر هغه چې دوی لږترلږه د یوې معاملې لخوا حواله شوي وي. په ورته وخت کې، هرڅومره ژر چې د دوی سره تړلې وروستۍ معامله بشپړه شي، پاڼې د نوي معلوماتو لپاره بیا کارول کیدی شي. که چیرې د شیانو لپاره اړین وي چې د لیږد ژوندي پاتې شي چې دوی یې رامینځته کړي، نو بیا هم باید کاپي شي.
  2. د لوستلو لیکلو لیږد لپاره، د پایلې ارزښت جوړښت ته اشاره به یوازې د لومړي تعدیل طرزالعمل (د معلوماتو لیکل یا حذف کولو) پورې اعتبار ولري.
  3. که څه هم جوړښت NodeValue بشپړ نه دی، مګر تراشل شوی (فرعي برخه "د بهرني پرتله کونکي په کارولو سره د کیلي ترتیب کول" وګورئ)، تاسو کولی شئ په خوندي ډول د پوائنټر له لارې د هغې ساحو ته لاسرسی ومومئ. اصلي خبره دا نه ده چې دا بې عزته کړئ!
  4. په هیڅ حالت کې باید جوړښت د ترلاسه شوي پوائنټر له لارې تعدیل نشي. ټول بدلونونه باید یوازې د میتود له لارې ترسره شي mdb_put. په هرصورت، مهمه نده چې تاسو دا څومره سخت غواړئ، دا به ممکنه نه وي، ځکه چې د حافظې ساحه چیرې چې دا جوړښت موقعیت لري یوازې د لوستلو حالت کې نقشه شوې ده.
  5. د دې هدف لپاره د پروسې پته ځای ته فایل بیا جوړ کړئ ، د مثال په توګه ، د فنکشن په کارولو سره د ذخیره کولو اعظمي اندازه زیاته کړئ mdb_env_set_map_size په ټولیزه توګه ټولې معاملې او اړوندې ادارې په بشپړه توګه باطلوي او په ځانګړې توګه ځینې شیانو ته اشاره کوي.

په نهایت کې ، یوه بله ځانګړتیا دومره سپکه ده چې د هغې جوهر څرګندول یوازې په بل پراګراف کې نه راځي. د B ونې په اړه څپرکی کې، ما یو انځور ورکړ چې څنګه یې پاڼې په حافظه کې تنظیم شوي. دا له دې څخه تعقیب کیږي چې د سیریل شوي ډیټا سره د بفر پیل پته په بشپړ ډول خپلسري کیدی شي. د دې له امله، دوی ته اشاره په جوړښت کې ترلاسه شوه 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 داسې چې دوی په ابتدايي ډول د اصلي لارښود ID لخوا امر شوي. په دې توګه، په تخنیکي توګه، د فولډر مینځپانګې بیرته ترلاسه کولو دنده د ورکړل شوي مخفف سره د کیلي ګروپ پورتنۍ حد کې د کرسر ځای په ځای کولو او بیا ښکته حد ته تکرار کول دي.

په iOS غوښتنلیکونو کې د کلیدي ارزښت ډیټابیس LMDB چمک او غربت

پورتنۍ حد په مستقیم ډول د ترتیب شوي لټون لخوا موندل کیدی شي. د دې کولو لپاره ، کرسر په ډیټابیس کې د کیلي ټول لیست په پیل کې ځای په ځای شوی او نور هم وده کوي تر هغه چې د اصلي لارښود پیژندونکي سره کیلي لاندې څرګند شي. دا طریقه دوه څرګند زیانونه لري:

  1. د خطي لټون پیچلتیا، که څه هم، لکه څنګه چې پیژندل کیږي، په عمومي توګه په ونو کې او په ځانګړې توګه په B-ونې کې دا د لوګاریتمیک وخت کې ترسره کیدی شي.
  2. په بې ګټې ډول، د غوښتل شوي پاڼې څخه مخکې ټولې پاڼې د فایل څخه اصلي حافظې ته پورته کیږي، کوم چې خورا ګران دی.

خوشبختانه، 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. د میزونو ترمنځ د اړیکو ماډل کول

تر اوسه پورې، موږ د یو واحد میز ډیټابیس سره د ډیزاین کولو او کار کولو ټول اړخونه په پام کې نیولي دي. موږ کولی شو ووایو چې جدول د ترتیب شوي ریکارډونو مجموعه ده چې د ورته ډول کلیدي ارزښت جوړه جوړه وي. که تاسو کیلي د مستطیل په توګه ښکاره کړئ او اړونده ارزښت د موازي پیپ په توګه وښایئ، تاسو د ډیټابیس بصری ډیاګرام ترلاسه کوئ.

په iOS غوښتنلیکونو کې د کلیدي ارزښت ډیټابیس LMDB چمک او غربت

په هرصورت، په ریښتینې ژوند کې دا په ندرت سره ممکنه ده چې د دومره لږ وینې سره ترلاسه شي. ډیری وختونه په ډیټابیس کې دا اړینه ده، لومړی، څو میزونه ولري، او دویم، په ترتیب کې د ابتدايي کیلي څخه توپیر په ترتیب کې انتخاب کړئ. دا وروستۍ برخه د دوی د جوړولو او یو بل سره تړلو مسلو ته وقف شوې ده.

د شاخص جدول

د بادل غوښتنلیک د "ګالري" برخه لري. دا د ټول بادل څخه د میډیا مینځپانګه ښیې ، د نیټې لخوا ترتیب شوي. د دې ډول انتخاب غوره پلي کولو لپاره ، د اصلي میز تر څنګ تاسو اړتیا لرئ د نوي ډول کیلي سره بل جوړ کړئ. دوی به د فایل رامینځته کیدو نیټې سره ساحه ولري ، کوم چې به د لومړني ترتیب کولو معیار په توګه عمل وکړي. ځکه چې نوې کیلي په اصلي جدول کې د کیلي په څیر ورته ډیټا حواله کوي، دوی ته د شاخص کیلي ویل کیږي. په لاندې عکس کې دوی په نارنجي کې روښانه شوي.

په iOS غوښتنلیکونو کې د کلیدي ارزښت ډیټابیس LMDB چمک او غربت

د دې لپاره چې په ورته ډیټابیس کې د مختلف جدولونو کیلي له یو بل څخه جلا کړئ، یو اضافي تخنیکي ساحوي جدول Id ټولو ته اضافه شوی. د ترتیب کولو لپاره د لوړ لومړیتوب په جوړولو سره، موږ به لومړی د میزونو په واسطه، او د میزونو دننه - زموږ د خپلو مقرراتو سره سم د کلیدونو ګروپ کول ترلاسه کړو.

د شاخص کیلي د لومړني کیلي په څیر ورته ډیټا حواله کوي. د دې ملکیت مستقیم پلي کول د دې سره د لومړني کیلي ارزښت برخې کاپي د یوځای کولو له لارې د ډیری لیدونو څخه غوره ندي:

  1. د ځای په پام کې نیولو سره، میټاډاټا خورا بډایه کیدی شي.
  2. د فعالیت له نظره، له هغه وخته چې د نوډ میټاډاټا تازه کول، تاسو باید دا د دوه کیلي په کارولو سره بیا ولیکئ.
  3. د کوډ ملاتړ له نظره ، که موږ د یوې کیلي لپاره ډیټا تازه کول هیر کړو ، نو موږ به په ذخیره کې د ډیټا متضادیت یوه زړه راښکونکې بګ ترلاسه کړو.

بیا، موږ به په پام کې ونیسو چې دا نیمګړتیاوې څنګه له منځه یوسو.

د میزونو ترمنځ د اړیکو تنظیم کول

نمونه د شاخص جدول د اصلي جدول سره د نښلولو لپاره مناسبه ده "د ارزښت په توګه کلیدي". لکه څنګه چې د دې نوم وړاندیز کوي، د شاخص ریکارډ ارزښت برخه د لومړني کلیدي ارزښت یوه کاپي ده. دا طریقه ټول پورته ذکر شوي زیانونه له منځه وړي چې د لومړني ریکارډ د ارزښت برخې کاپي ذخیره کولو پورې تړاو لري. یوازینی لګښت دا دی چې د شاخص کیلي لخوا ارزښت ترلاسه کولو لپاره ، تاسو اړتیا لرئ د یوې پرځای ډیټابیس ته 2 پوښتنې وکړئ. په سکیماتیکه توګه، د پایلې ډیټابیس سکیما داسې ښکاري.

په iOS غوښتنلیکونو کې د کلیدي ارزښت ډیټابیس LMDB چمک او غربت

د میزونو تر مینځ د اړیکو تنظیم کولو بله بیلګه ده "بې ځایه کیلي". د دې جوهر دا دی چې کیلي ته اضافي ځانګړتیاوې اضافه کړي، کوم چې د ترتیب کولو لپاره نه، بلکې د اړونده کیلي بیا جوړولو لپاره اړین دي. د ځانګړو iOS چوکاټونو شرایط، زه به یو جعلي، مګر یو روښانه مثال ورکړم

د کلاوډ ګرځنده پیرودونکي یوه پاڼه لري چې ټول هغه فایلونه او فولډرونه ښیې چې کاروونکي یې د نورو خلکو سره شریک کړي. څرنګه چې په نسبي ډول داسې فایلونه شتون لري، او د دوی سره تړلې د تبلیغاتو په اړه د ځانګړو معلوماتو ډیری ډولونه شتون لري (چا ته لاسرسی ورکړل شوی، د کومو حقونو سره، او نور)، دا به منطقي نه وي چې د ارزښت برخې بار بار کړي. په اصلي جدول کې یې ثبت کړئ. په هرصورت، که تاسو غواړئ دا ډول فایلونه آفلاین ښکاره کړئ، تاسو لاهم اړتیا لرئ چې دا په بل ځای کې ذخیره کړئ. طبیعي حل دا دی چې د دې لپاره جلا میز جوړ کړئ. په لاندې انځور کې، د هغې کیلي د "P" سره مخکینۍ ده، او د ځای لرونکی "propname" د ډیر ځانګړي ارزښت "عامه معلوماتو" سره بدلیدلی شي.

په iOS غوښتنلیکونو کې د کلیدي ارزښت ډیټابیس LMDB چمک او غربت

ټول ځانګړي میټاډاټا ، د ذخیره کولو لپاره چې نوی جدول رامینځته شوی ، د ریکارډ ارزښت برخه کې ځای په ځای شوي. په ورته وخت کې، تاسو نه غواړئ د فایلونو او فولډرو په اړه ډاټا نقل کړئ چې دمخه په اصلي میز کې زیرمه شوي. پرځای یې، بې ځایه ډاټا د "P" کلید ته د "نوډ ID" او "timestamp" ساحو په بڼه اضافه شوي. د دوی څخه مننه ، تاسو کولی شئ د شاخص کیلي رامینځته کړئ ، له کوم څخه چې تاسو لومړني کیلي ترلاسه کولی شئ ، له هغې څخه ، په پای کې تاسو کولی شئ د نوډ میټاډاټا ترلاسه کړئ.

پایله

موږ د LMDB د تطبیق پایلې په مثبت ډول ارزوو. له هغې وروسته ، د غوښتنلیک کنګل کولو شمیر 30٪ کم شوی.

په iOS غوښتنلیکونو کې د کلیدي ارزښت ډیټابیس LMDB چمک او غربت

د ترسره شوي کار پایلې د iOS ټیم څخه هاخوا راپورته شوې. اوس مهال، د Android اپلیکیشن کې د اصلي "فایلونو" برخې څخه یو هم د LMDB کارولو ته بدل شوی، او نورې برخې په لاره کې دي. د C ژبه، په کوم کې چې د کلیدي ارزښت پلورنځی پلي کیږي، په پیل کې په C++ کې د کراس پلیټ فارم شاوخوا د غوښتنلیک چوکاټ رامینځته کولو کې ښه مرسته وه. د کوډ جنریټر کارول شوی و ترڅو په بې ساري ډول د C++ کتابتون د پلیټ فارم کوډ سره په هدف-C او کوټلین کې وصل کړي جيني د ډراپ باکس څخه، مګر دا یو بشپړ مختلف کیسه ده.

سرچینه: www.habr.com

Add a comment