iOS ايپليڪيشنن ۾ اهم قدر ڊيٽابيس LMDB جي چمڪ ۽ غربت

iOS ايپليڪيشنن ۾ اهم قدر ڊيٽابيس LMDB جي چمڪ ۽ غربت

2019 جي زوال ۾، Mail.ru Cloud iOS ٽيم ۾ هڪ ڊگهي انتظار وارو واقعو ٿيو. ايپليڪيشن اسٽيٽ جي مسلسل اسٽوريج لاء مکيه ڊيٽابيس موبائل دنيا لاء تمام غير معمولي بڻجي چڪو آهي لائيٽنگ ميموري-ميپ ٿيل ڊيٽابيس (LMDB). ڪٽ جي هيٺان اسان توهان کي چار حصن ۾ ان جو تفصيلي جائزو پيش ڪريون ٿا. پهرين، اچو ته اهڙي غير معمولي ۽ مشڪل انتخاب جي سببن بابت ڳالهايو. پوءِ اسان اڳتي وڌنداسين ٽن ٿنڀن تي غور ڪرڻ لاءِ LMDB آرڪيٽيڪچر جي دل تي: ميموري-ميپ ٿيل فائلون، B+-tree، ڪاپي-آن-لکڻ واري طريقي کي لاڳو ڪرڻ لاءِ ٽرانزيڪشن ۽ ملٽي ورشن. آخرڪار، شيرين لاء - عملي حصو. ان ۾ اسان ڏسنداسين ته ڊيٽابيس اسڪيما کي ڪيئن ڊزائين ڪرڻ ۽ ان تي عمل ڪرڻ ڪيترن ئي جدولن سان، جنهن ۾ هڪ انڊيڪس هڪ شامل آهي، گهٽ-سطح جي اهم-قدر API جي مٿان.

Contents

  1. عمل درآمد لاء حوصلا افزائي
  2. LMDB پوزيشن
  3. LMDB جا ٽي ستون
    3.1. وهيل نمبر 1. ميموري ميپ ٿيل فائلون
    3.2. وهيل نمبر 2. ب + وڻ
    3.3. وهيل نمبر 3. ڪاپي-تي-لکڻ
  4. اهم-قدر API جي چوٽي تي ڊيٽا اسڪيما ڊزائين ڪرڻ
    4.1. بنيادي خلاصيون
    4.2. ٽيبل ماڊلنگ
    4.3. جدولن جي وچ ۾ ماڊلنگ تعلقات

1. عمل درآمد لاء حوصلا افزائي

هڪ سال 2015 ۾، اسان اهو اندازو ڪرڻ جي تڪليف ڪئي ته اسان جي ايپليڪيشن جو انٽرفيس ڪيترا ڀيرا دير ٿي وڃي ٿو. اسان اهو هڪ سبب لاء ڪيو. اسان کي گهڻيون شڪايتون مليون آهن ته ڪڏهن ڪڏهن ايپليڪيشن صارف جي عملن جو جواب ڏيڻ بند ڪري ٿي: بٽڻ دٻائي نٿا سگهن، فهرستون اسڪرول نه ٿيون ڪن، وغيره. ماپ جي mechanics جي باري ۾ ٻڌايو AvitoTech تي، تنهنڪري هتي آئون صرف انگن جو حڪم ڏيان ٿو.

iOS ايپليڪيشنن ۾ اهم قدر ڊيٽابيس LMDB جي چمڪ ۽ غربت

ماپ جا نتيجا اسان لاءِ ٿڌو شاور بڻجي ويا. اهو ظاهر ٿيو ته منجمد ٿيڻ جي ڪري ٻين کان وڌيڪ مسئلا آهن. جيڪڏهن هن حقيقت کي سمجهڻ کان اڳ معيار جو بنيادي ٽيڪنيڪل اشارو حادثي کان آزاد هو، پوء ڌيان کان پوء منتقل ڪيو ويو منجمد مفت تي.

تعمير ڪرڻ فريز سان گڏ ڊيش بورڊ ۽ خرچ ڪرڻ کان پوء مقداري и معيار انهن جي سببن جو تجزيو، مکيه دشمن پڌرو ٿيو - ڳري ڪاروباري منطق ايپليڪيشن جي مکيه سلسلي ۾. ان بي عزتي جو فطري رد عمل ان کي ڪم جي وهڪري ۾ اڇلائڻ جي ٻرندڙ خواهش هئي. سسٽماتي طور تي هن مسئلي کي حل ڪرڻ لاء، اسان هلڪو وزن جي اداڪارين جي بنياد تي هڪ گھڻن موضوعن واري فن تعمير کي استعمال ڪيو. مون ان کي وقف ڪيو iOS دنيا لاءِ ان جي موافقت لاءِ ٻه سلسلا تي اجتماعي Twitter ۽ Habré تي مضمون. موجوده داستان جي حصي جي طور تي، مان فيصلي جي انهن پهلوئن تي زور ڏيڻ چاهيان ٿو جن ڊيٽابيس جي چونڊ کي متاثر ڪيو.

سسٽم آرگنائيزيشن جو اداڪار ماڊل فرض ڪري ٿو ته ملٽي ٿريڊنگ ان جو ٻيو جوهر بڻجي وڃي ٿو. ان ۾ ماڊل شيون، نديءَ جون حدون پار ڪرڻ پسند ڪن ٿيون. ۽ اهي ائين ڪن ٿا ڪڏهن ڪڏهن ۽ هتي ۽ اُتي نه، پر لڳ ڀڳ مسلسل ۽ هر هنڌ

iOS ايپليڪيشنن ۾ اهم قدر ڊيٽابيس LMDB جي چمڪ ۽ غربت

ڊيٽابيس پيش ڪيل ڊراگرام ۾ بنيادي حصن مان هڪ آهي. ان جو مکيه ڪم macropattern کي لاڳو ڪرڻ آهي حصيداري ڊيٽابيس. جيڪڏهن انٽرنيشنل دنيا ۾ اهو استعمال ڪيو ويندو آهي ڊيٽا جي هم وقت سازي کي منظم ڪرڻ لاء خدمتن جي وچ ۾، پوء اداڪار فن تعمير جي صورت ۾ - ڊيٽا جي وچ ۾ ڊيٽا. اهڙيء طرح، اسان کي هڪ ڊيٽابيس جي ضرورت آهي جيڪا گهٽ ۾ گهٽ مشڪلاتن جو سبب نه هوندي جڏهن ان سان گڏ هڪ گھڻن موضوعن واري ماحول ۾ ڪم ڪندي. خاص طور تي، هن جو مطلب اهو آهي ته ان مان حاصل ڪيل شيون گهٽ ۾ گهٽ ڌاڳو-محفوظ، ۽ مثالي طور تي مڪمل طور تي غير ميوٽيل هجڻ گهرجي. جئين توهان کي خبر آهي، بعد ۾ هڪ ئي وقت استعمال ڪري سگهجي ٿو ڪيترن ئي موضوعن کان بغير ڪنهن به تالا لڳائڻ جي، جنهن جي ڪارڪردگي تي فائدي وارو اثر آهي.

iOS ايپليڪيشنن ۾ اهم قدر ڊيٽابيس LMDB جي چمڪ ۽ غربتٻيو اهم عنصر جيڪو متاثر ڪيو ڊيٽابيس جي چونڊ تي اسان جو ڪلائوڊ API هو. اهو git پاران منظور ڪيل هم وقت سازي واري طريقي سان متاثر ٿيو. هن وانگر، اسان جو مقصد هو آف لائن-پهرين API، جيڪو کلاؤڊ ڪلائنٽ لاءِ مناسب کان وڌيڪ ڏسڻ ۾ اچي ٿو. اهو فرض ڪيو ويو هو ته اهي صرف هڪ ڀيرو بادل جي مڪمل حالت کي پمپ ڪندا، ۽ پوء اڪثريت جي اڪثريت ۾ هم وقت سازي تبديلين جي رولنگ ذريعي ٿيندي. افسوس، اهو موقعو اڃا تائين صرف نظرياتي زون ۾ آهي، ۽ گراهڪ نه سکيو آهي ته ڪيئن پيچ سان ڪم ڪرڻ عملي طور تي. ان جا ڪيئي مقصدي سبب آهن، جن جي تعارف ۾ دير نه ڪرڻ جي لاءِ، اسين بريڪٽس پٺيان ڇڏينداسين. هاڻي، جيڪو وڌيڪ دلچسپيءَ جو آهي اهو سبق جو سبق آموز نتيجو آهي ته ڇا ٿئي ٿو جڏهن هڪ API چوي ٿو “A” ۽ ان جو صارف “B” نٿو چوي.

تنهن ڪري، جيڪڏهن توهان تصور ڪريو گيٽ، جيڪو، جڏهن پل ڪمان تي عمل ڪندي، هڪ مقامي سنيپ شاٽ تي پيچ لاڳو ڪرڻ جي بدران، ان جي مڪمل حالت کي مڪمل سرور اسٽيٽ سان موازنہ ڪري ٿو، پوء توهان کي بلڪل صحيح خيال هوندو ته ڪڪر ۾ هم وقت سازي ڪيئن ٿيندي آهي. گراهڪ اهو اندازو لڳائڻ آسان آهي ته ان کي لاڳو ڪرڻ لاءِ، توهان کي ميموري ۾ ٻه 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 جي چمڪ ۽ غربت

مٿي ڏنل ڊراگرام ڏيکاري ٿو ته LMDB جو SQLite سان مقابلو ڪرڻ، جيڪو پڻ اعلي سطح تي لاڳو ٿئي ٿو، عام طور تي ڪور ڊيٽا سان SQLite کان وڌيڪ صحيح ناهي. اهو وڌيڪ مناسب هوندو ته ساڳين اسٽوريج انجڻن جو حوالو ڏيڻ لاءِ برابر حریف - BerkeleyDB، LevelDB، Sophia، RocksDB، وغيره. اتي به ترقيون آهن جتي LMDB SQLite لاءِ اسٽوريج انجڻ جي جزو طور ڪم ڪري ٿو. اهڙو پهريون تجربو 2012ع ۾ ڪيو ويو خرچ ڪيو LMDB پاران هاورڊ چو. نتيجا ايترو ته دلچسپ ثابت ٿيو ته هن جي شروعات کي او ايس ايس جي شوقينن طرفان ورتو ويو، ۽ ان جو تسلسل شخص ۾ مليو. LumoSQL. جنوري 2020 ۾، هن منصوبي جو ليکڪ ڊين شيرر هو پيش ڪيو اهو LinuxConfAu تي.

LMDB بنيادي طور تي ايپليڪيشن ڊيٽابيس لاءِ انجڻ جي طور تي استعمال ٿيندو آهي. لائبريري ان جي ظاهري ڊولپرز کي ڏئي ٿي OpenLDAP، جيڪي پنهنجي منصوبي جي بنياد جي طور تي BerkeleyDB سان انتهائي ناخوش هئا. هڪ معمولي لائبريري کان شروع btree، هاورڊ چو اسان جي وقت جي سڀ کان مشهور متبادل مان هڪ پيدا ڪرڻ جي قابل هو. هن پنهنجي تمام بهترين رپورٽ هن ڪهاڻي ڏانهن وقف ڪئي، انهي سان گڏ LMDB جي اندروني جوڙجڪ ڏانهن. "دي لائيٽنگ ميموري-نقشي ڊيٽابيس". اسٽوريج جي سهولت کي فتح ڪرڻ جو هڪ سٺو مثال ليونيڊ يوريوف (اڪا يليو) مثبت ٽيڪنالاجيز مان سندس رپورٽ ۾ هاء لوڊ 2015 ۾ "LMDB انجڻ هڪ خاص چيمپيئن آهي". ان ۾، هو ReOpenLDAP کي لاڳو ڪرڻ جي ساڳي ڪم جي حوالي سان LMDB بابت ڳالهائيندو آهي، ۽ LevelDB اڳ ۾ ئي تقابلي تنقيد جي تابع ٿي چڪو آهي. عمل درآمد جي نتيجي ۾، مثبت ٽيڪنالاجيون پڻ فعال طور تي ترقي پذير ڪانٽو هئي ايم ڊي بي ايڪس تمام سوادج خاصيتن سان، اصلاح ۽ بگ فڪسس.

LMDB اڪثر استعمال ڪيو ويندو آهي جيئن ته اسٽوريج. مثال طور، Mozilla Firefox برائوزر چونڊيو اهو ڪيترن ئي ضرورتن لاء، ۽، نسخو 9، Xcode کان شروع ٿئي ٿو ترجيح ڏني انڊيڪس محفوظ ڪرڻ لاءِ ان جو SQLite.

انجڻ موبائيل ڊولپمينٽ جي دنيا ۾ پڻ پنهنجي سڃاڻپ ٺاهي آهي. ان جي استعمال جا نشان ٿي سگهن ٿا ڳولهيو ٽيليگرام لاءِ iOS ڪلائنٽ ۾. LinkedIn اڃا به اڳتي وڌيو ۽ LMDB کي پنهنجي گھر جي ڊيٽا ڪيشنگ فريم ورڪ Rocket Data لاءِ ڊفالٽ اسٽوريج طور چونڊيو، جنهن بابت ٻڌايو 2016 ۾ سندس مضمون ۾.

LMDB ڪاميابيءَ سان برڪلي ڊي بي جي ڇڏيل جاءِ ۾ سج ۾ هڪ جڳهه لاءِ وڙهندي رهي آهي جڏهن اهو Oracle جي ڪنٽرول هيٺ آيو. لائبريري ان جي رفتار ۽ اعتبار جي ڪري پيار ڪيو ويندو آهي، ان جي ساٿين جي مقابلي ۾. جئين توهان کي خبر آهي، هتي ڪي به مفت لنچ نه آهن، ۽ مان واپار بند تي زور ڏيڻ چاهيان ٿو جيڪو توهان کي منهن ڏيڻو پوندو جڏهن LMDB ۽ SQLite جي وچ ۾ چونڊيو وڃي. مٿي ڏنل ڊراگرام واضح طور تي ڏيکاري ٿو ته رفتار ڪيئن وڌي وئي آهي. پهرين، اسان ڊسڪ اسٽوريج جي چوٽي تي تجريد جي اضافي تہن لاء ادا نه ڪندا آهيون. اهو واضح آهي ته هڪ سٺو فن تعمير اڃا تائين انهن کان سواء نٿو ڪري سگهي، ۽ اهي لازمي طور تي ايپليڪيشن ڪوڊ ۾ ظاهر ٿيندا، پر اهي تمام گهڻو ذيلي هوندا. انهن ۾ خاصيتون شامل نه هونديون جيڪي مخصوص ايپليڪيشن لاءِ گهربل نه هونديون آهن، مثال طور، SQL ٻولي ۾ سوالن لاءِ سپورٽ. ٻيو، اهو ممڪن آهي ته ايپليڪيشن آپريشن جي نقشي کي بهتر طور تي لاڳو ڪرڻ لاء ڊسڪ اسٽوريج جي درخواستن تي. جيڪڏهن SQLite منهنجي ڪم ۾ هڪ سراسري ايپليڪيشن جي سراسري شمارياتي ضرورتن تي ٻڌل آهي، پوءِ توهان، هڪ ايپليڪيشن ڊولپر جي حيثيت سان، ڪم جي لوڊشيڊنگ جي مکيه منظرنامي کان چڱيءَ طرح واقف آهيو. وڌيڪ پيداواري حل لاءِ، توهان کي ادا ڪرڻو پوندو وڌايل قيمت ٽيگ ٻنهي جي ابتدائي حل جي ترقيءَ لاءِ ۽ ان جي ايندڙ مدد لاءِ.

3. LMDB جا ٽي ستون

ايل ايم ڊي بي کي پکيءَ جي نظر کان ڏسڻ کان پوءِ، اونهي وڃڻ جو وقت هو. ايندڙ ٽن حصن کي مکيه ٿنڀن جي تجزيي لاءِ وقف ڪيو ويندو جن تي اسٽوريج فن تعمير آهي:

  1. ڊسڪ سان ڪم ڪرڻ ۽ اندروني ڊيٽا جي جوڙجڪ کي هم وقت سازي ڪرڻ لاء هڪ ميکانيزم جي طور تي ميموري-ميپ ٿيل فائلون.
  2. B+-tree هڪ تنظيم جي طور تي ذخيرو ٿيل ڊيٽا جي جوڙجڪ جي.
  3. ACID ٽرانزيڪشن پراپرٽيز ۽ ملٽي ورشن مهيا ڪرڻ لاءِ هڪ طريقي جي طور تي ڪاپي-آن-لکيو.

3.1. وهيل نمبر 1. ميموري ميپ ٿيل فائلون

ميموري ميپ ٿيل فائلون اهڙيون اهم تعميراتي عنصر آهن جيڪي اهي مخزن جي نالي ۾ به ظاهر ٿين ٿيون. محفوظ ڪيل معلومات تائين رسائي جي ڪيشنگ ۽ هم وقت سازي جا مسئلا مڪمل طور تي آپريٽنگ سسٽم ڏانهن ڇڏي ويا آهن. LMDB پاڻ ۾ ڪا به ڪيش نه رکندو آھي. اهو ليکڪ طرفان هڪ شعوري فيصلو آهي، ڇاڪاڻ ته ڊيٽا کي سڌو سنئون ميپ ٿيل فائلن مان پڙهڻ توهان کي انجڻ جي عمل ۾ ڪيترن ئي ڪنڊن کي ڪٽڻ جي اجازت ڏئي ٿي. انھن مان ڪجھ جي مڪمل فهرست ھيٺ ڏنل آھي.

  1. اسٽوريج ۾ ڊيٽا جي تسلسل کي برقرار رکڻ جڏهن ان سان گڏ ڪيترن ئي عملن سان ڪم ڪري ٿي آپريٽنگ سسٽم جي ذميواري. ايندڙ حصي ۾، هن مشيني تفصيل سان بحث ڪيو ويو آهي ۽ تصويرن سان.
  2. ڪيش جي غير موجودگي مڪمل طور تي LMDB کي متحرڪ مختص سان لاڳاپيل مٿي کان ختم ڪري ٿي. عملي طور تي ڊيٽا پڙهڻ جو مطلب آهي هڪ پوائنٽر مقرر ڪرڻ صحيح پتي ڏانهن ورچوئل ميموري ۾ ۽ ٻيو ڪجهه به نه. اهو آواز سائنس فڪشن وانگر آهي، پر اسٽوريج سورس ڪوڊ ۾ ڪالوڪ کي سڀئي ڪالون اسٽوريج ترتيب جي فنڪشن ۾ مرڪوز آهن.
  3. ڪيچ جي غير موجودگي جو مطلب پڻ تالا جي غير موجودگي سان لاڳاپيل آهي انهن جي رسائي جي هم وقت سازي سان. پڙهندڙ، جن مان هڪ ئي وقت پڙهندڙن جو هڪ صوابديدي تعداد ٿي سگهي ٿو، انهن جي ڊيٽا جي رستي تي هڪ واحد ميوٽڪس کي منهن نه ڏيو. انهي جي ڪري، پڙهڻ جي رفتار ۾ سي پي يو جي تعداد جي بنياد تي مثالي لڪير اسڪالبل آهي. LMDB ۾، صرف تبديل ٿيندڙ عملن کي هم وقت سازي ڪئي وئي آهي. هڪ وقت ۾ فقط هڪ ليکڪ ٿي سگهي ٿو.
  4. گھٽ ۾ گھٽ ڪيشنگ ۽ هم وقت سازي جي منطق کي ختم ڪري ٿو انتهائي پيچيده قسم جي غلطين کي ملائي ٿريڊ ماحول ۾ ڪم ڪرڻ سان. Usenix OSDI 2014 ڪانفرنس ۾ ٻه دلچسپ ڊيٽابيس اڀياس هئا: "سڀ فائل سسٽم برابر نه ٺاهيا ويا آهن: حادثو-مسلسل ايپليڪيشنن کي ترتيب ڏيڻ جي پيچيدگي تي" и "مذاق ۽ نفعي لاءِ ڊيٽابيس کي اذيت ڏيڻ". انهن مان توهان LMDB جي بي مثال اعتبار ۽ ACID ٽرانزيڪشن ملڪيت جي لڳ ڀڳ بي عيب عملدرآمد بابت معلومات گڏ ڪري سگهو ٿا، جيڪا SQLite کان وڌيڪ آهي.
  5. LMDB جي گھٽتائي واري مشين کي ان جي ڪوڊ جي نمائندگي ڪرڻ جي اجازت ڏئي ٿي مڪمل طور تي پروسيسر جي L1 ڪيش ۾ ايندڙ رفتار جي خاصيتن سان.

بدقسمتي سان، iOS ۾، ميموري-نقشي ٿيل فائلن سان، هر شي بي بادل ناهي جيئن اسان چاهيون ٿا. انهن سان لاڳاپيل گهٽتائي بابت وڌيڪ شعور سان ڳالهائڻ لاء، اهو ضروري آهي ته آپريٽنگ سسٽم ۾ هن ميڪانيزم کي لاڳو ڪرڻ جي عام اصولن کي ياد رکڻ گهرجي.

ميموري ميپ ٿيل فائلن بابت عام معلومات

iOS ايپليڪيشنن ۾ اهم قدر ڊيٽابيس LMDB جي چمڪ ۽ غربتھر ايپليڪيشن سان جيڪو ھلندو آھي، آپريٽنگ سسٽم ھڪڙو ادارو جوڙيندو آھي جنھن کي پروسيس سڏيو ويندو آھي. هر عمل کي مختص ڪيو ويو آهي پتي جي هڪ متضاد رينج جنهن ۾ اهو هر شيء کي رکي ٿو جيڪو ان کي هلائڻ جي ضرورت آهي. گھٽ ۾ گھٽ ايڊريس تي سيڪشن آھن ڪوڊ ۽ سخت ڪوڊ ٿيل ڊيٽا ۽ وسيلن سان. اڳيان اچي ٿو متحرڪ ايڊريس اسپيس جو وڌندڙ بلاڪ، جيڪو اسان کي نالي جي نالي سان مشهور آهي. اهو ادارن جي پتي تي مشتمل آهي جيڪي پروگرام جي آپريشن دوران ظاهر ٿيندا آهن. مٿي تي ميموري علائقو آهي جيڪو ايپليڪيشن اسٽيڪ پاران استعمال ڪيو ويو آهي. اهو يا ته وڌي ٿو يا ٺيڪ ٿئي ٿو؛ ٻين لفظن ۾، ان جي سائيز پڻ هڪ متحرڪ طبيعت آهي. اسٽيڪ ۽ هيپ کي هڪ ٻئي سان دٻائڻ ۽ مداخلت ڪرڻ کان روڪڻ لاءِ، اهي ايڊريس اسپيس جي مختلف سرن تي واقع آهن. مٿي ۽ هيٺان ٻن متحرڪ حصن جي وچ ۾ هڪ سوراخ آهي. آپريٽنگ سسٽم هن وچين حصي ۾ ايڊريس استعمال ڪري ٿو مختلف ادارن کي پروسيس سان لاڳاپيل ڪرڻ لاءِ. خاص طور تي، اهو ڊسڪ تي فائل سان پتي جي هڪ مخصوص مسلسل سيٽ سان لاڳاپيل ڪري سگهي ٿو. اهڙي فائل کي ميموري ميپڊ چئبو آهي

پروسيس لاءِ مختص ڪيل ايڊريس اسپيس تمام وڏو آهي. نظرياتي طور تي، پتي جو تعداد صرف پوائنٽر جي سائيز تائين محدود آهي، جيڪو سسٽم جي بٽ گنجائش طرفان طئي ڪيو ويندو آهي. جيڪڏهن فزيڪل ميموري کي 1 کان 1 تائين ميپ ڪيو ويو ته پوءِ پهريون عمل سڄي رام کي گوب ڪري ڇڏيندو، ۽ ان ۾ ملٽي ٽاسڪنگ جي ڪا به ڳالهه نه ٿيندي.

تنهن هوندي، اسان جي تجربي مان اسان ڄاڻون ٿا ته جديد آپريٽنگ سسٽم هڪ ئي وقت تي عمل ڪري سگهن ٿا جيترو گهربل عمل. اهو ممڪن آهي انهي حقيقت جي ڪري ته اهي صرف ڪاغذ تي عملن لاءِ تمام گهڻي ميموري مختص ڪن ٿا، پر حقيقت ۾ اهي بنيادي جسماني ياداشت ۾ لوڊ ڪن ٿا صرف اهو حصو جيڪو هتي ۽ هاڻي طلب ۾ آهي. تنهن ڪري، هڪ عمل سان لاڳاپيل ياداشت کي مجازي سڏيو ويندو آهي.

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 ڪنهن به وقت ميموري مان فائل تي ميپ ڪيل صفحن کي ان لوڊ ڪرڻ کان نه ڊڄندو آهي، ڇاڪاڻ ته اهي ڊسڪ تي فائل سان هم وقت سازي جي ضمانت آهن.

سڀ تبديل ٿيل صفحا گندي ياداشت ۾ ختم ٿين ٿا، ڪابه پرواهه ناهي ته اهي اصل ۾ ڪٿي هئا. خاص طور تي، ميموري-ميپ ٿيل فائلون تبديل ڪيون ويون آهن لکڻ سان انهن سان لاڳاپيل ورچوئل ميموري کي هن طريقي سان درجه بندي ڪيو ويندو. پرچم سان LMDB کولڻ MDB_WRITEMAP، ان ۾ تبديليون ڪرڻ بعد، توهان هن ذاتي طور تي تصديق ڪري سگهو ٿا.

جيئن ئي هڪ ايپليڪيشن تمام گهڻي جسماني ياداشت کڻڻ شروع ڪري ٿي، iOS ان کي گندي صفحي جي ڪمپريشن جي تابع ڪري ٿو. گندي ۽ ڪمپريس ٿيل صفحن تي قبضو ڪيل ڪل ميموري ايپليڪيشن جي نام نهاد ميموري فوٽ پرنٽ ٺاهي ٿي. هڪ دفعو اهو هڪ خاص حد تائين پهچي ٿو، OOM قاتل سسٽم ڊيمون پروسيس کان پوء اچي ٿو ۽ زبردستي ان کي ختم ڪري ٿو. ڊيسڪ ٽاپ آپريٽنگ سسٽم جي مقابلي ۾ iOS جي اها خاصيت آهي. ان جي ابتڙ، ميموري فوٽ پرنٽ کي گھٽائڻ سان صفحن کي فزيڪل ميموري کان ڊسڪ ۾ تبديل ڪرڻ iOS ۾ مهيا نه ڪيو ويو آهي. صرف ان جي سببن جو اندازو لڳائي سگهجي ٿو. ٿي سگهي ٿو ته صفحا تيزيءَ سان ڊسڪ ۽ پوئتي ڏانهن منتقل ڪرڻ جو طريقو موبائيل ڊوائيسز لاءِ تمام گهڻو توانائي استعمال ڪندڙ آهي، يا iOS SSD ڊرائيو تي سيلز کي ٻيهر لکڻ جو وسيلو بچائي ٿو، يا ٿي سگهي ٿو ته ڊزائنر سسٽم جي مجموعي ڪارڪردگيءَ کان مطمئن نه هئا، جتي سڀ ڪجهه آهي. مسلسل تبديل ٿيل. جيئن به هجي، حقيقت هڪ حقيقت رهي ٿي.

سٺي خبر، اڳ ۾ ئي ذڪر ڪيو ويو آهي، اهو آهي ته LMDB ڊفالٽ طرفان فائلن کي اپڊيٽ ڪرڻ لاء ايم ايم پي ميڪانيزم استعمال نٿو ڪري. هن جو مطلب اهو آهي ته ڏيکاريل ڊيٽا iOS پاران صاف ياداشت جي طور تي درجه بندي ڪئي وئي آهي ۽ ميموري فوٽ پرنٽ ۾ حصو نه ٿو ڏئي. توھان ان جي تصديق ڪري سگھو ٿا ھڪڙو Xcode اوزار استعمال ڪندي VM ٽريڪر. هيٺ ڏنل اسڪرين شاٽ آپريشن دوران ڪلائوڊ ايپليڪيشن جي iOS ورچوئل ميموري جي حالت ڏيکاري ٿو. شروعات ۾، 2 LMDB مثال ان ۾ شروع ڪيا ويا. پهرين کي اجازت ڏني وئي هئي ته هن جي فائل کي 1GiB ورچوئل ميموري تي ڏيکاري، ٻيو - 512MiB. ان حقيقت جي باوجود ته ٻنهي اسٽوريج جي رهائشي ياداشت جي هڪ خاص مقدار تي قبضو ڪيو ويو آهي، انهن مان نه ته گندي سائيز ۾ حصو وٺندا آهن.

iOS ايپليڪيشنن ۾ اهم قدر ڊيٽابيس LMDB جي چمڪ ۽ غربت

۽ هاڻي اهو وقت خراب خبر لاء آهي. 64-bit ڊيسڪ ٽاپ آپريٽنگ سسٽم ۾ ادل بدلڻ واري ميڪانيزم جي مهرباني، هر عمل جيترو ورچوئل ايڊريس اسپيس تي قبضو ڪري سگهي ٿو جيترو ان جي امڪاني ادل لاءِ مفت هارڊ ڊسڪ جي جاءِ اجازت ڏئي ٿي. iOS ۾ ڪمپريشن سان ادل بدلائڻ بنيادي طور تي نظرياتي وڌ ۾ وڌ گھٽائي ٿو. ھاڻي سڀني جاندار عملن کي مکيه (ريم پڙھڻ) ميموري ۾ فٽ ٿيڻ گھرجي، ۽ اھي سڀ جيڪي مناسب نه آھن انھن کي ختم ڪرڻ تي مجبور ڪيو وڃي. اهو بيان ڪيو ويو آهي جيئن مٿي ڄاڻايل آهي رپورٽ، ۽ ۾ سرڪاري دستاويز. نتيجي طور، iOS mmap ذريعي مختص ڪرڻ لاء موجود ميموري جي مقدار کي سختي سان محدود ڪري ٿو. هتي هتي توھان ميموري جي مقدار جي تجرباتي حدن تي نظر ڪري سگھو ٿا جيڪي مختص ٿي سگھن ٿيون مختلف ڊوائيسز تي ھن سسٽم ڪال استعمال ڪندي. سڀ کان جديد اسمارٽ فون ماڊلز تي، iOS 2 گيگا بائيٽ، ۽ iPad جي مٿين ورزن تي - 4 پاران سخاوت وارو ٿي چڪو آهي. عملي طور تي، توهان کي گهٽ ۾ گهٽ سپورٽ ڊوائيسز ماڊلز تي ڌيان ڏيڻو پوندو، جتي هر شيء تمام اداس آهي. اڃا به بدتر، VM ٽريڪر ۾ ايپليڪيشن جي ميموري اسٽيٽ کي ڏسڻ سان، توهان کي معلوم ٿيندو ته LMDB صرف هڪ کان پري آهي جيڪو ميموري ميپ ٿيل هجڻ جي دعويٰ ڪري ٿو. سسٽم مختص ڪندڙ، وسيلن جي فائلن، تصويري فريم ورڪ، ۽ ٻين ننڍڙن شڪارين طرفان سٺيون شيون کائي وينديون آهن.

Cloud ۾ تجربن جي نتيجن جي بنياد تي، اسان LMDB پاران مختص ڪيل ميموري لاء هيٺين سمجھوتي قدر تي آيا آھيون: 384 ميگا بائيٽ 32-bit ڊوائيسز لاء ۽ 768 64-bit ڊوائيسز لاء. هن حجم کي استعمال ڪرڻ کان پوء، ڪنهن به ترميمي عملن کي ڪوڊ سان ختم ٿيڻ شروع ٿئي ٿو MDB_MAP_FULL. اسان پنهنجي نگراني ۾ اهڙيون غلطيون ڏسندا آهيون، پر اهي ايتريون ننڍيون هونديون آهن جو هن مرحلي تي انهن کي نظرانداز ڪري سگهجي ٿو.

هڪ غير واضع سبب ذخيري جي ذريعي وڌيڪ ياداشت جي واپرائڻ لاء ڊگهي-زندگي ٽرانزيڪشن ٿي سگهي ٿو. اهو سمجهڻ لاءِ ته اهي ٻه واقعا ڪيئن جڙيل آهن، اسان کي LMDB جي باقي ٻن ٿنڀن تي غور ڪرڻ سان مدد ملندي.

3.2. وهيل نمبر 2. ب + وڻ

هڪ اهم-قيمت اسٽوريج جي مٿان جدولن کي نقل ڪرڻ لاء، هيٺين عملن کي ان جي API ۾ موجود هجڻ گهرجي:

  1. نئون عنصر داخل ڪرڻ.
  2. ڏنل چاٻي سان هڪ عنصر جي ڳولا ڪريو.
  3. هڪ عنصر کي هٽائڻ.
  4. چاٻين جي وقفن تي ٻيهر ترتيب ڏيو ان ترتيب ۾ جيڪي ترتيب ڏنل آھن.

iOS ايپليڪيشنن ۾ اهم قدر ڊيٽابيس LMDB جي چمڪ ۽ غربتآسان ترين ڊيٽا جو ڍانچو جيڪو آساني سان سڀني چار عملن کي لاڳو ڪري سگھي ٿو ھڪڙو بائنري سرچ وڻ آھي. ان جي هر نوڊس هڪ ڪنجي جي نمائندگي ڪري ٿي جيڪا ٻار جي چاٻين جي پوري سبسٽ کي ٻن ذيلي وڻن ۾ ورهائي ٿي. کاٻي پاسي ۾ اھي آھن جيڪي والدين کان ننڍا آھن، ۽ ساڄي ھڪڙي ۾ اھي آھن جيڪي وڏا آھن. چابين جو آرڊر ٿيل سيٽ حاصل ڪرڻ حاصل ڪيو ويندو آهي هڪ کلاسک وڻ جي ٽرورسلز ذريعي

بائنري وڻن ۾ ٻه بنيادي خاميون آهن جيڪي انهن کي ڊسڪ تي ٻڌل ڊيٽا ڍانچي جي طور تي اثرائتو ٿيڻ کان روڪين ٿيون. پهرين، انهن جي توازن جو درجو غير متوقع آهي. وڻن جي حاصلات جو هڪ وڏو خطرو آهي جنهن ۾ مختلف شاخن جي اوچائي تمام گهڻو مختلف ٿي سگهي ٿي، جيڪا توقع جي مقابلي ۾ ڳولا جي الورورٿمڪ پيچيدگي کي خاص طور تي خراب ڪري ٿي. ٻيو، نوڊس جي وچ ۾ ڪراس لنڪس جي گهڻائي ياداشت ۾ بائنري وڻن جي مقاميت کان محروم ڪري ٿي. بند نوڊس (انهن جي وچ ۾ ڪنيڪشن جي لحاظ کان) مجازي ياداشت ۾ مڪمل طور تي مختلف صفحن تي واقع ٿي سگهن ٿا. نتيجي طور، هڪ وڻ ۾ ڪيترن ئي پاڙيسري نوڊس جي هڪ سادي ٽريورسل پڻ صفحن جي مقابلي واري تعداد کي ڏسڻ جي ضرورت پوندي. اهو هڪ مسئلو آهي جيتوڻيڪ جڏهن اسان بائنري وڻن جي اثرائتي بابت ڳالهايون ٿا هڪ ان-ميموري ڊيٽا ڍانچي جي طور تي، ڇاڪاڻ ته پروسيسر ڪيش ۾ صفحن کي مسلسل گھمائڻ سستو خوشي ناهي. جڏهن اهو اڪثر ڪري ڊسڪ مان نوڊس سان لاڳاپيل صفحن کي ٻيهر حاصل ڪرڻ لاء اچي ٿو، صورتحال مڪمل طور تي ٿي ويندي آهي افسوسناڪ.

iOS ايپليڪيشنن ۾ اهم قدر ڊيٽابيس LMDB جي چمڪ ۽ غربتب-وڻ، بائنري وڻن جي ارتقا جي ڪري، پوئين پيراگراف ۾ ڄاڻايل مسئلن کي حل ڪريو. پهرين، اهي خود توازن آهن. ٻيو، انهن جي هر نوڊس ٻارن جي چاٻين جي سيٽ کي 2 ۾ نه، پر M آرڊر ڪيل سبسٽس ۾ ورهائي ٿو، ۽ نمبر M تمام وڏو ٿي سگهي ٿو، ڪيترن ئي سؤ يا هزارن جي ترتيب تي.

ان ڪري:

  1. هر نوڊ ۾ اڳ ۾ ئي ترتيب ڏنل ڪنجين جو وڏو تعداد شامل آهي ۽ وڻ تمام ننڍا آهن.
  2. وڻ ميموري ۾ جڳهه جي مقاميت جي ملڪيت حاصل ڪري ٿو، ڇاڪاڻ ته ڪنجيون جيڪي قدر جي ويجهو آهن قدرتي طور تي هڪ ٻئي جي ڀرسان ساڳئي يا پاڙيسري نوڊس تي واقع آهن.
  3. ٽرانزٽ نوڊس جو تعداد گھٽجي ويندو آھي جڏھن سرچ آپريشن دوران وڻ ھيٺ لھي ويندا آھن.
  4. رينج جي سوالن جي دوران پڙهيل ٽارگيٽ نوڊس جو تعداد گھٽجي ويو آهي، ڇاڪاڻ ته انهن مان هر هڪ اڳ ۾ ئي حڪم ڪيل چابين جو هڪ وڏو تعداد تي مشتمل آهي.

iOS ايپليڪيشنن ۾ اهم قدر ڊيٽابيس LMDB جي چمڪ ۽ غربت

LMDB ڊيٽا کي ذخيرو ڪرڻ لاءِ B-tree جي مختلف قسمن کي استعمال ڪري ٿو جنهن کي B+ وڻ سڏيو ويندو آهي. مٿي ڏنل ڊراگرام ڏيکاري ٿو ٽن قسمن جا نوڊس جيڪي ان ۾ موجود آهن:

  1. مٿي تي روٽ آهي. اهو هڪ گودام جي اندر ڊيٽابيس جي تصور کان سواء ٻيو ڪجهه به نه آهي. هڪ LMDB مثال اندر، توهان ڪيترائي ڊيٽابيس ٺاهي سگهو ٿا جيڪي نقشي واري ورچوئل ايڊريس اسپيس شيئر ڪن ٿا. انهن مان هر هڪ پنهنجي روٽ کان شروع ٿئي ٿو.
  2. سڀ کان گهٽ سطح تي پنن وارا آهن. اهي ۽ صرف انهن ۾ ڊيٽابيس ۾ محفوظ ڪيل اهم-قدر جوڙو شامل آهن. رستي ۾، هي B + وڻن جي خاصيت آهي. جيڪڏهن هڪ باقاعده B-وڻ سڀني سطحن جي نوڊس ۾ قيمتي حصن کي اسٽور ڪري ٿو، ته پوءِ B+ تبديلي صرف گهٽ ۾ گهٽ آهي. هن حقيقت کي درست ڪرڻ کان پوءِ، اسان اڳتي هلي LMDB ۾ استعمال ٿيندڙ وڻ جي ذيلي قسم کي صرف B-tree سڏينداسين.
  3. روٽ ۽ پنن جي وچ ۾ نيويگيشنل (شاخ) نوڊس سان 0 يا وڌيڪ ٽيڪنيڪل سطحون آهن. انهن جو ڪم پنن جي وچ ۾ ترتيب ڏنل سيٽن کي ورهائڻ آهي.

جسماني طور تي، نوڊس اڳ ۾ مقرر ڪيل ڊگھائي جي يادگيري جا بلاڪ آهن. انهن جي سائيز آپريٽنگ سسٽم ۾ ميموري صفحن جي سائيز جي هڪ کان وڌيڪ آهي، جنهن تي اسان مٿي ذڪر ڪيو آهي. نوڊ جي جوڙجڪ هيٺ ڏيکاريل آهي. هيڊر ميٽا معلومات تي مشتمل آهي، جنهن مان سڀ کان وڌيڪ واضح آهي مثال طور چيڪسم. اڳيان اچي ٿو آفسٽس بابت معلومات جنهن ۾ سيلز ڊيٽا سان واقع آهن. ڊيٽا يا ته ڪنجيون ٿي سگهي ٿي، جيڪڏهن اسان نيويگيشن نوڊس جي باري ۾ ڳالهائي رهيا آهيون، يا پنن جي صورت ۾ پوري ڪيئي-ويليو جوڙا. "هاء ڪارڪردگي جي اهم قدر اسٽورن جو جائزو".

iOS ايپليڪيشنن ۾ اهم قدر ڊيٽابيس LMDB جي چمڪ ۽ غربت

صفحي جي نوڊس جي اندروني مواد سان معاملو ڪرڻ کان پوء، اسان وڌيڪ نمائندگي ڪنداسين LMDB B-tree کي هيٺين شڪل ۾ آسان انداز ۾.

iOS ايپليڪيشنن ۾ اهم قدر ڊيٽابيس LMDB جي چمڪ ۽ غربت

نوڊس سان صفحا ترتيب سان ڊسڪ تي واقع آهن. اعلي نمبر وارا صفحا فائل جي آخر ۾ واقع آهن. نام نهاد ميٽا پيج ۾ آفسٽن بابت معلومات شامل آهي جنهن ذريعي سڀني وڻن جي پاڙن کي ڳولي سگهجي ٿو. فائل کولڻ وقت، LMDB صحيح ميٽا پيج جي ڳولا ۾ فائل پيج کي صفحي جي آخر کان شروع تائين اسڪين ڪري ٿو ۽ ان جي ذريعي موجوده ڊيٽابيس ڳولي ٿو.

iOS ايپليڪيشنن ۾ اهم قدر ڊيٽابيس LMDB جي چمڪ ۽ غربت

ھاڻي، ڊيٽا جي تنظيم جي منطقي ۽ جسماني ساخت جو خيال رکندي، اسان LMDB جي ٽئين ستون تي غور ڪري سگھون ٿا. اهو ان جي مدد سان آهي ته سڀئي اسٽوريج تبديليون ٽرانزيڪشن سان ٿينديون آهن ۽ هڪ ٻئي کان اڪيلائي ۾، ڊيٽابيس کي مڪمل طور تي ملائي ورشن جي ملڪيت ڏئي ٿي.

3.3. وهيل نمبر 3. ڪاپي-تي-لکڻ

ڪجھ بي وڻ جي عملن ۾ ان جي نوڊس ۾ تبديلين جو سلسلو شامل آھي. ھڪڙو مثال ھڪڙو نوڊ ڏانھن ھڪڙو نئون ڪني شامل ڪري رھيو آھي جيڪو اڳ ۾ ئي پنھنجي وڌ ۾ وڌ گنجائش تائين پهچي چڪو آھي. انهي حالت ۾، ضروري آهي ته، پهريون، نوڊ کي ٻن حصن ۾ ورهائڻ، ۽ ٻيو، ان جي والدين ۾ نئين بڊنگ چائلڊ نوڊ جي لنڪ شامل ڪرڻ. اهو عمل ممڪن طور تي تمام خطرناڪ آهي. جيڪڏهن ڪجهه سببن جي ڪري (حادثو، بجلي جي بندش، وغيره) سيريز مان تبديلين جو صرف حصو ٿئي ٿو، پوء وڻ هڪ متضاد حالت ۾ رهندو.

ڊيٽابيس ۾ غلطي برداشت ڪرڻ لاءِ هڪ روايتي حل اهو آهي ته B-tree جي اڳيان هڪ اضافي آن-ڊِسڪ ڊيٽا ڍانچي کي شامل ڪيو وڃي - هڪ ٽرانزيڪشن لاگ، جنهن کي رائٽ-ايڊ لاگ (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 جي مٿي تي هڪ ڊيٽا اسڪيما ڊزائين ڪرڻ

اچو ته اسان جي API تجزيي کي LMDB پاران مهيا ڪيل بنيادي تجزين کي ڏسڻ سان شروع ڪريون: ماحول ۽ ڊيٽابيس، ڪي ۽ قدر، ٽرانزيڪشن ۽ ڪرسر.

ڪوڊ لسٽنگ بابت هڪ نوٽ

عوامي LMDB API ۾ سڀئي ڪم انهن جي ڪم جو نتيجو هڪ غلطي ڪوڊ جي صورت ۾ واپس آڻيندا آهن، پر سڀني ايندڙ لسٽن ۾ ان جي تصديق کي اختصار جي خاطر ختم ڪيو ويو آهي. ڪانٽو سي ++ لفافي lmdbxx، جنهن ۾ غلطين کي C++ استثنا طور مادي ڪيو ويو آهي.

LMDB کي iOS يا macOS لاءِ پروجيڪٽ سان ڳنڍڻ جو تيز ترين طريقو، مان صلاح ڏيان ٿو منهنجو 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 Cloud ايپليڪيشن ۾، اسان صرف ٻن پيٽرولن جي ڊفالٽ قيمتن کي تبديل ڪيو.

پهرين هڪ مجازي پتي جي جڳهه جي ماپ آهي جيڪا اسٽوريج فائل کي ميپ ڪيو ويو آهي. بدقسمتي سان، جيتوڻيڪ ساڳئي ڊوائيس تي، مخصوص قدر رن کان هلائڻ لاء خاص طور تي مختلف ٿي سگهن ٿا. iOS جي هن خصوصيت کي ذهن ۾ رکڻ لاء، وڌ ۾ وڌ اسٽوريج حجم متحرڪ طور تي چونڊيو ويو آهي. ھڪڙي خاص قدر کان شروع ڪندي، اھو ترتيب سان اڌ ڪيو ويندو آھي فنڪشن تائين mdb_env_open کان مختلف نتيجو واپس نه ڪندو ENOMEM. نظريي ۾، اتي پڻ مخالف طريقو آهي - پهرين انجڻ کي گهٽ ۾ گهٽ ياداشت مختص ڪريو، ۽ پوء، جڏهن غلطي ملي ٿي، MDB_MAP_FULL، وڌايو. تنهن هوندي به، اهو تمام گهڻو وڌيڪ ٿلهو آهي. ان جو سبب اهو آهي ته فنڪشن کي استعمال ڪندي ميموري کي ٻيهر مختص ڪرڻ (ري ميپ) جو طريقو mdb_env_set_map_size انجڻ کان اڳ ۾ حاصل ڪيل سڀني ادارن (ڪرسر، ٽرانزيڪشن، ڪيچ ۽ قدر) کي رد ڪري ٿو. واقعن جي هن موڙ کي ڪوڊ ۾ اڪائونٽ ۾ آڻڻ ان جي اهم پيچيدگين جو سبب بڻجندو. جيڪڏهن، تنهن هوندي، مجازي ياداشت توهان لاء تمام ضروري آهي، پوء اهو هڪ سبب ٿي سگهي ٿو هڪ ويجهي نظر وٺڻ لاء ڪانٽو جيڪو تمام گهڻو اڳتي وڌي چڪو آهي. ايم ڊي بي ايڪس, جتي اعلان ڪيل خاصيتن ۾ "خودڪار آن-دي-فلائي ڊيٽابيس سائيز جي ترتيب" آهي.

ٻيو پيٽرولر، جنهن جو ڊفالٽ قدر اسان سان نه ٺهيو، ٿريڊ جي حفاظت کي يقيني بڻائڻ جي ميڪيڪل کي منظم ڪري ٿو. بدقسمتي سان، گهٽ ۾ گهٽ iOS 10 ۾ مسئلو آهي سپورٽ سان ٿريڊ مقامي اسٽوريج لاءِ. انهي سبب لاء، مٿين مثال ۾، مخزن کي پرچم سان کوليو ويو آهي MDB_NOTLS. ان کان علاوه اهو به ضروري هو ڪانٽو سي ++ ريپر lmdbxxهن خاصيت سان ۽ ان ۾ متغيرن کي ختم ڪرڻ لاءِ.

ڊيٽابيس

ڊيٽابيس هڪ الڳ بي-وڻ مثال آهي، جنهن تي اسان مٿي بحث ڪيو آهي. ان جو افتتاح هڪ ٽرانزيڪشن جي اندر ٿئي ٿو، جيڪو پهرين ۾ ٿورو عجيب لڳي سگهي ٿو.

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 ۾ طئي ڪيو ويو هو. توهان ان ۾ وڌيڪ پڙهي سگهو ٿا ريڊيو.
  2. ملٽي ٿريڊنگ جو طريقو بيان ڪيو ويو آهي "اڪيلو ليکڪ / گهڻن پڙهندڙن" اسڪيم ذريعي. ليکڪ هڪ ٻئي کي بلاڪ ڪندا آهن، پر پڙهندڙن کي بلاڪ نه ڪندا آهن. پڙهندڙ ليکڪن يا هڪ ٻئي کي بلاڪ نٿا ڪن.
  3. nested ٽرانزيڪشن لاء حمايت.
  4. Multiversion سپورٽ.

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 استعمال ڪندڙ جي ڪلائوڊ ۾ ميڊيا مواد سان، توهان هن پروسيس دوران 60 fps جي باري ۾ وساري سگهو ٿا ۽ آسان اسڪرولنگ. بار بار اسڪرين جي تازه ڪاري کي روڪڻ لاء، توهان کي ڪنهن حد تائين ان شرح کي محدود ڪرڻ جي ضرورت آهي جنهن تي ڊيٽا هيٺيون تبديليون UICollectionViewDataSource.

جيڪڏهن ڊيٽابيس ملٽي ورشن کي سپورٽ نٿو ڪري ۽ توهان کي صرف موجوده موجوده حالت سان ڪم ڪرڻ جي اجازت ڏئي ٿي، پوء ڊيٽا جو هڪ وقت جي مستحڪم سنيپ شاٽ ٺاهڻ لاء توهان کي ان کي ڪاپي ڪرڻ جي ضرورت آهي يا ته ڪجهه ميموري ڊيٽا جي جوڙجڪ ۾ يا هڪ عارضي ٽيبل تي. انهن مان ڪو به طريقو تمام مهانگو آهي. ان-ميموري اسٽوريج جي صورت ۾، اسان ميموري ۾ قيمتون حاصل ڪندا آهيون، تعمير ٿيل شيون محفوظ ڪرڻ جي ڪري، ۽ وقت ۾، بيڪار ORM تبديلين سان لاڳاپيل. جيئن ته عارضي ٽيبل لاء، اهو هڪ وڌيڪ قيمتي خوشي آهي، صرف غير معمولي ڪيسن ۾ احساس پيدا ڪري ٿو.

LMDB جو ملٽي ورشن حل هڪ مستحڪم ڊيٽا ماخذ کي برقرار رکڻ جي مسئلي کي تمام خوبصورت انداز ۾ حل ڪري ٿو. اهو ڪافي آهي صرف هڪ ٽرانزيڪشن ۽ وائيلا کي کولڻ لاءِ - جيستائين اسان ان کي مڪمل نه ڪريون، ڊيٽا سيٽ مقرر ٿيڻ جي ضمانت آهي. ان جي تازه ڪاري جي رفتار لاء منطق هاڻي مڪمل طور تي پيش ڪيل پرت جي هٿن ۾ آهي، ڪنهن به اهم وسيلن جي مٿي نه آهي.

ڪسر

ڪسر B-tree traversal ذريعي ڪيئي-ويليو جوڑوں تي ترتيب وار وار ڪرڻ لاءِ هڪ ميکانيزم مهيا ڪن ٿا. انهن جي بغير، اهو ناممڪن هوندو ته مؤثر طريقي سان ڊيٽابيس ۾ جدولن کي ماڊل، جنهن کي اسان هاڻي ڦيرايو.

4.2. ٽيبل ماڊلنگ

ڪيئي آرڊرنگ جي ملڪيت توهان کي اجازت ڏئي ٿي ته توهان هڪ اعليٰ سطحي تجريد ٺاهي سگهو ٿا جهڙوڪ بنيادي خلاصن جي مٿي تي ٽيبل. اچو ته هن عمل تي غور ڪريون مثال استعمال ڪندي ڪلائوڊ ڪلائنٽ جي مکيه ٽيبل جو، جيڪو سڀني صارفن جي فائلن ۽ فولڊرن بابت معلومات کي محفوظ ڪري ٿو.

ٽيبل اسڪيما

ھڪڙي عام منظرنامن مان ھڪڙو جنھن لاء ھڪڙي ٽيبل جي جوڙجڪ ھڪڙي فولڊر جي وڻ سان ٺھيل ھجڻ گھرجي ھڪڙي ڏنل ڊاريڪٽري ۾ واقع سڀني عناصر جي چونڊ آھي. ھن قسم جي موثر سوالن لاء ھڪڙو سٺو ڊيٽا آرگنائيزيشن ماڊل آھي. دماغي فهرست. ان کي لاڳو ڪرڻ لاءِ ڪي-ويليو اسٽوريج جي چوٽي تي، ضروري آهي ته فائلن ۽ فولڊرن جي ڪنجين کي اهڙي طرح ترتيب ڏيو ته جيئن اهي گروهه رکيا وڃن انهن جي رڪنيت جي بنياد تي والدين ڊاريڪٽري ۾. ان کان علاوه، ڊاريڪٽري جي مواد کي ونڊوز استعمال ڪندڙ کان واقف فارم ۾ ڊسپلي ڪرڻ لاء (پهريون فولڊر، پوء فائلون، ٻئي ترتيب ڏنل الفابيٽ ۾)، اهو ضروري آهي ته لاڳاپيل اضافي شعبن کي ڪني ۾ شامل ڪيو وڃي.

هيٺ ڏنل تصوير ڏيکاري ٿي ته ڪيئن، هٿ تي ڪم جي بنياد تي، هڪ بائيٽ صف جي صورت ۾ ڪنجي جي نمائندگي وانگر نظر اچي ٿي. والدين ڊاريڪٽري جي سڃاڻپ ڪندڙ (ڳاڙهو) سان گڏ بائيٽ پهرين رکيا ويا آهن، پوء قسم (سائي) سان ۽ نالي سان دم (نيرو) سان ترتيب ڏنل آهن. ڊفالٽ LMDB جي ترتيب سان ترتيب ڏنل ليڪسيگرافيڪل ترتيب ۾، اهي ترتيب ڏنل آهن. گهربل انداز. ساڳي ڳاڙهي اڳياڙيءَ سان ترتيب وار ڪنجيون چڙهڻ اسان کي انهن سان لاڳاپيل قدر ڏئي ٿو جيئن اهي صارف انٽرفيس ۾ ڏيکاريا وڃن (ساڄي پاسي)، بغير ڪنهن اضافي پوسٽ پروسيسنگ جي ضرورت جي.

iOS ايپليڪيشنن ۾ اهم قدر ڊيٽابيس LMDB جي چمڪ ۽ غربت

سريلائيزنگ ڪنجيون ۽ قدر

دنيا ۾ شين کي ترتيب ڏيڻ جا ڪيترائي طريقا ايجاد ڪيا ويا آهن. جيئن ته اسان کي رفتار کان سواءِ ٻي ڪا به ضرورت نه هئي، ان ڪري اسان پنهنجي لاءِ تيز ترين ممڪن چونڊيو - ميموري جو هڪ ڊمپ جنهن تي قبضو ڪيو ويو سي ٻوليءَ جي ڍانچي جي مثال سان. اهڙيءَ طرح، ڊائريڪٽري عنصر جي ڪنجي کي هيٺين ڍانچي سان ماڊل ڪري سگهجي ٿو. 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 معيار جي لحاظ کان هڪ شاندار صورتحال حاصل ڪري سگهو ٿا - نيٽ ورڪ کان ڊسڪ تائين سڄي رستي سان ڊيٽا سان ڪم ڪرڻ لاء صرف اسٽيڪ ميموري استعمال ڪريو!

بائنري ڪمپيريٽر سان ڪنجيون ترتيب ڏيڻ

اهم آرڊر جو تعلق هڪ خاص فنڪشن طرفان بيان ڪيو ويو آهي جنهن کي هڪ موازنہ سڏيو ويندو آهي. جيئن ته انجڻ کي بائٽس جي سيمينٽڪس جي باري ۾ ڪجھ به نه ڄاڻندو آهي جنهن ۾ اهي شامل آهن، ڊفالٽ ڪمپيريٽر وٽ ان کان سواءِ ٻيو ڪو به آپشن ناهي هوندو ته ڪن کي ليڪسيگرافڪ ترتيب ۾ ترتيب ڏئي، بائيٽ جي بائيٽ جي مقابلي جو رستو وٺي. اڏاوتن کي منظم ڪرڻ لاءِ ان کي استعمال ڪرڻ هڪ ڪٽڻ واري ڪُلهي سان شيڊنگ ڪرڻ جي برابر آهي. بهرحال، سادي ڪيسن ۾ مون کي اهو طريقو قابل قبول آهي. متبادل هيٺ بيان ڪيو ويو آهي، پر هتي آئون هن رستي تي پکڙيل ڪجهه ريڪ کي نوٽ ڪندس.

ياد رکڻ لاءِ پهرين شيءِ آهي ميموري نمائندگي ابتدائي ڊيٽا جي قسمن جي. اهڙيء طرح، سڀني ايپل ڊوائيسز تي، انٽيگر متغير فارميٽ ۾ ذخيرو ٿيل آهن نن Endي اينڊينين. هن جو مطلب اهو آهي ته گهٽ ۾ گهٽ اهم بائيٽ کاٻي پاسي هوندو، ۽ اهو ممڪن نه هوندو ته انٽيجرز کي ترتيب ڏيڻ سان بائيٽ جي بائيٽ جي مقابلي ۾. مثال طور، 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, default binary comparator هاڻي اهم موازن لاءِ مناسب ناهي. جيڪڏهن اسان ان کي پنهنجي پاڻ سان تبديل نه ڪندا آهيون، ته پوءِ نالي جي ڊگھائي هڪ اعليٰ ترجيحي عنصر هوندي جنهن کي ترتيب ڏيڻ ۾ نالو ئي هوندو.

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 // ...
}​

جيستائين ڊيٽابيس ۾ سڀئي چابيون ساڳئي قسم جا آهن، غير مشروط طور تي انهن جي بائيٽ جي نمائندگي کي ايپليڪيشن جي بنيادي ڍانچي جي قسم تي قانوني آهي. هتي هڪ nuance آهي، پر ان تي بحث ڪيو ويندو "ريڊنگ رڪارڊ" جي ذيلي حصي ۾.

سيريلائيزنگ ويلز

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-tree صفحا جن تي ڪا شئي واقع آهي، ڪاپي-آن-لکڻ جي اصول جي مهرباني، جيستائين اهي گهٽ ۾ گهٽ هڪ ٽرانزيڪشن جي حوالي ڪيا وڃن، تيستائين تبديلي نه ٿيندي. ساڳئي وقت، جيئن ئي انهن سان لاڳاپيل آخري ٽرانزيڪشن مڪمل ٿئي ٿي، صفحا نئين ڊيٽا لاء ٻيهر استعمال ڪري سگھجن ٿيون. جيڪڏهن ضروري هجي ته شين کي زندهه رکڻ لاءِ ٽرانزيڪشن جيڪا انهن ٺاهي آهي، پوءِ انهن کي اڃا به نقل ڪرڻو پوندو.
  2. ريڊ رائٽ ٽرانزيڪشن لاءِ، نتيجي واري قدر جي جوڙجڪ ڏانهن اشارو صرف ان وقت تائين صحيح ٿيندو جيستائين پهرين ترميمي عمل (ڊيٽا لکڻ يا حذف ڪرڻ).
  3. جيتوڻيڪ ساخت NodeValue مڪمل طور تي نه، پر سنواريل (ڏسو ذيلي سيڪشن "ٻاهرين موازن کي استعمال ڪندي ڪيز کي ترتيب ڏيڻ")، توهان محفوظ طور تي پوائنٽر ذريعي ان جي فيلڊ تائين رسائي ڪري سگهو ٿا. بنيادي شيء ان کي ختم ڪرڻ نه آهي!
  4. ڪنهن به حالت ۾ حاصل ڪيل پوائنٽر ذريعي ساخت کي تبديل نه ڪيو وڃي. سڀني تبديلين کي صرف طريقي سان ڪيو وڃي mdb_put. تنهن هوندي به، توهان اهو ڪرڻ چاهيو ته ڪيترو به مشڪل هجي، اهو ممڪن نه ٿيندو، ڇاڪاڻ ته ميموري واري علائقي جتي هي ڍانچي واقع آهي صرف پڙهڻ واري موڊ ۾ نقشي ۾ ٺهيل آهي.
  5. ھڪڙي فائل کي ري ميپ ڪريو پروسيس ايڊريس اسپيس ڏانھن ان مقصد لاءِ، مثال طور، فنڪشن استعمال ڪندي وڌ ۾ وڌ اسٽوريج سائيز کي وڌايو mdb_env_set_map_size مڪمل طور تي سڀني ٽرانزيڪشن ۽ لاڳاپيل ادارن کي عام طور تي رد ڪري ٿو ۽ خاص طور تي ڪجهه شين ڏانهن اشارو ڪري ٿو.

آخر ۾، هڪ ٻي خصوصيت ايتري ته ٺڳي آهي جو ان جي جوهر کي ظاهر ڪرڻ صرف هڪ ٻئي پيراگراف ۾ مناسب نه آهي. ب-وڻ بابت باب ۾، مون هڪ خاڪو ڏنو آهي ته ڪيئن ان جا صفحا ياداشت ۾ ترتيب ڏنل آهن. انهي مان اهو آهي ته بفر جي شروعات جو پتو سيريل ٿيل ڊيٽا سان بلڪل بي ترتيب ٿي سگهي ٿو. انهي جي ڪري، انهن ڏانهن اشارو ڪيو ويو آهي ساخت ۾ 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 جي چمڪ ۽ غربت

مٿيون حدون سڌو سنئون ڳولها ذريعي ڳولي سگهجن ٿيون. هن کي ڪرڻ لاءِ، ڪرسر کي ڊيٽابيس ۾ چاٻين جي پوري لسٽ جي شروعات ۾ رکيو ويندو آهي ۽ اڳتي وڌايو ويندو آهي جيستائين ان جي هيٺان پيرن ڊاريڪٽري جي سڃاڻپ ڪندڙ سان هڪ ڪنجي ظاهر ٿئي. هن طريقي سان 2 واضح نقصان آهن:

  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 جي چمڪ ۽ غربت

ساڳئي ڊيٽابيس ۾ مختلف جدولن جي ڪنجين کي هڪ ٻئي کان الڳ ڪرڻ لاءِ، انهن سڀني ۾ هڪ اضافي ٽيڪنيڪل فيلڊ ٽيبل آئي ڊي شامل ڪئي وئي. ترتيب ڏيڻ لاءِ ان کي اعليٰ ترين ترجيح ڏيڻ سان، اسان چاٻين جي گروپنگ کي پھرين جدولن ذريعي، ۽ جدولن جي اندر - پنھنجن قاعدن موجب حاصل ڪنداسين.

انڊيڪس ڪيڏي ساڳي ڊيٽا جو حوالو ڏئي ٿو جيئن پرائمري ڪي. ھن ملڪيت جي ھڪڙي سڌي عمل کي ان سان ڳنڍڻ جي ذريعي بنيادي ڪي جي قيمت واري حصي جي ڪاپي ڪيترن ئي نقطي نظر کان بھترين نه آھي:

  1. خلا جي لحاظ کان ورتو ويو، ميٽاداٽ ڪافي امير ٿي سگهي ٿو.
  2. ڪارڪردگي جي نقطي نظر کان، جڏهن کان نوڊ جي ميٽا ڊيٽا کي اپڊيٽ ڪرڻ کان پوء، توهان کي ٻه چاٻيون استعمال ڪندي ان کي ٻيهر لکڻو پوندو.
  3. ڪوڊ سپورٽ جي نقطي نظر کان، جيڪڏهن اسان ڊيٽا کي تازه ڪاري ڪرڻ وساريون ٿا چاٻين مان هڪ لاء، اسان کي اسٽوريج ۾ ڊيٽا جي غير مطابقت جو هڪ خراب بگ حاصل ڪنداسين.

اڳيون، اسان غور ڪنداسين ته انهن گهٽتائي کي ڪيئن ختم ڪجي.

جدولن جي وچ ۾ لاڳاپن کي منظم ڪرڻ

انڊيڪس ٽيبل کي مکيه ٽيبل سان ڳنڍڻ لاءِ نمونو مناسب آھي "قيمت جي طور تي اهم". جيئن ته ان جو نالو مشورو ڏئي ٿو، انڊيڪس رڪارڊ جو قدر حصو بنيادي مکيه قيمت جي ڪاپي آهي. اهو طريقو بنيادي رڪارڊ جي قيمت واري حصي جي ڪاپي کي محفوظ ڪرڻ سان لاڳاپيل مٿين سڀني نقصانن کي ختم ڪري ٿو. صرف قيمت اها آهي ته قيمت حاصل ڪرڻ لاءِ انڊيڪس ڪيئي، توهان کي ڪرڻ جي ضرورت آهي 2 سوالن کي ڊيٽابيس ۾ هڪ بدران. اسڪيمي طور تي، نتيجو ڊيٽابيس اسڪيما هن طرح ڏسڻ ۾ اچي ٿو.

iOS ايپليڪيشنن ۾ اهم قدر ڊيٽابيس LMDB جي چمڪ ۽ غربت

ٽيبل جي وچ ۾ لاڳاپن کي منظم ڪرڻ لاء هڪ ٻيو نمونو آهي "غير ضروري چاٻي". ان جو خلاصو اهو آهي ته ڪي ۾ اضافي خاصيتون شامل ڪرڻ، جيڪي ترتيب ڏيڻ لاءِ نه، پر لاڳاپيل ڪي کي ٻيهر ٺاهڻ لاءِ گهربل آهن. Mail.ru Cloud ايپليڪيشن ۾ ان جي استعمال جا حقيقي مثال موجود آهن، جڏهن ته، ان جي استعمال کان بچڻ لاءِ. مخصوص iOS فريم ورڪ جي حوالي سان، مان هڪ فرضي، پر هڪ واضح مثال ڏيندس

ڪلائوڊ موبائل ڪلائنٽ وٽ ھڪڙو صفحو آھي جيڪو ڏيکاري ٿو سڀني فائلن ۽ فولڊرن کي جيڪو صارف ٻين ماڻھن سان شيئر ڪيو آھي. جيئن ته اهڙيون فائلون نسبتاً گهٽ آهن، ۽ انهن سان جڙيل پبلسٽي بابت مختلف قسم جي مخصوص معلومات (ڪنهن کي پهچ ڏني وئي آهي، ڪهڙن حقن سان، وغيره) موجود آهي، ان ڪري ان جي قيمت واري حصي تي بار وجهڻ عقلي نه هوندو. ان سان گڏ مکيه ٽيبل ۾ رڪارڊ ڪريو. تنهن هوندي، جيڪڏهن توهان چاهيو ٿا ته اهڙيون فائلون آف لائن ڏيکاري، توهان کي اڃا به ان کي ڪٿي رکڻو پوندو. هڪ قدرتي حل ان لاء هڪ الڳ ٽيبل ٺاهڻ آهي. هيٺ ڏنل ڊراگرام ۾، ان جي ڪنجي کي "P" سان اڳ ۾ لڳايو ويو آهي، ۽ جڳهه هولڊر "propname" کي وڌيڪ مخصوص قدر "عوامي معلومات" سان تبديل ڪري سگهجي ٿو.

iOS ايپليڪيشنن ۾ اهم قدر ڊيٽابيس LMDB جي چمڪ ۽ غربت

تمام منفرد ميٽاداٽا، اسٽوريج جي خاطر جيڪا نئين ٽيبل ٺاهي وئي هئي، رڪارڊ جي قيمت واري حصي ۾ رکيل آهي. ساڳئي وقت، توهان فائلن ۽ فولڊرن بابت ڊيٽا کي نقل ڪرڻ نٿا چاهيو جيڪي اڳ ۾ ئي مکيه ٽيبل ۾ محفوظ ٿيل آهن. ان جي بدران، بيڪار ڊيٽا شامل ڪئي وئي آهي "P" کي "نوڊ ID" ۽ "ٽائم اسٽيمپ" فيلڊ جي صورت ۾. انهن جي مهرباني، توهان هڪ انڊيڪس ڪيچ ٺاهي سگهو ٿا، جنهن مان توهان حاصل ڪري سگهو ٿا هڪ پرائمري ڪي، جنهن مان، آخرڪار، توهان حاصل ڪري سگهو ٿا نوڊ ميٽا ڊيٽا.

نتيجو

اسان مثبت طور تي LMDB جي عمل جي نتيجن جو جائزو وٺون ٿا. ان کان پوء، ايپليڪيشن منجمد جو تعداد 30٪ گھٽجي ويو.

iOS ايپليڪيشنن ۾ اهم قدر ڊيٽابيس LMDB جي چمڪ ۽ غربت

ڪم جا نتيجا iOS ٽيم کان ٻاهر گونجيا. في الحال، Android ايپليڪيشن ۾ مکيه "فائل" سيڪشن مان هڪ پڻ LMDB استعمال ڪرڻ ۾ تبديل ٿي چڪو آهي، ۽ ٻيا حصا رستي تي آهن. سي ٻولي، جنهن ۾ ڪي-ويليو اسٽور لاڳو ڪيو ويو آهي، شروعاتي طور تي C++ ۾ ڪراس پليٽ فارم جي چوڌاري هڪ ايپليڪيشن فريم ورڪ ٺاهڻ لاءِ سٺي مدد هئي. هڪ ڪوڊ جنريٽر استعمال ڪيو ويو هو بيحد طريقي سان نتيجو ڪندڙ C++ لائبريري کي پليٽ فارم ڪوڊ سان ڳنڍڻ لاءِ Objective-C ۽ Kotlin ۾ جيني Dropbox کان، پر اهو هڪ مڪمل طور تي مختلف ڪهاڻي آهي.

جو ذريعو: www.habr.com

تبصرو شامل ڪريو