ప్రోహోస్టర్ > బ్లాగ్ > పరిపాలన > iOS అప్లికేషన్లలో కీ-వాల్యూ డేటాబేస్ LMDB యొక్క షైన్ మరియు పేదరికం
iOS అప్లికేషన్లలో కీ-వాల్యూ డేటాబేస్ LMDB యొక్క షైన్ మరియు పేదరికం
2019 చివరలో, Mail.ru క్లౌడ్ iOS బృందంలో చాలా కాలంగా ఎదురుచూస్తున్న సంఘటన జరిగింది. అప్లికేషన్ స్థితి యొక్క నిరంతర నిల్వ కోసం ప్రధాన డేటాబేస్ మొబైల్ ప్రపంచానికి చాలా అన్యదేశంగా మారింది మెరుపు మెమరీ-మ్యాప్డ్ డేటాబేస్ (LMDB). కట్ క్రింద మేము మీకు నాలుగు భాగాలుగా వివరణాత్మక సమీక్షను అందిస్తున్నాము. మొదట, అటువంటి అల్పమైన మరియు కష్టమైన ఎంపికకు గల కారణాల గురించి మాట్లాడుదాం. అప్పుడు మేము LMDB ఆర్కిటెక్చర్ యొక్క గుండె వద్ద ఉన్న మూడు స్తంభాలను పరిగణలోకి తీసుకుంటాము: మెమరీ-మ్యాప్ చేసిన ఫైల్లు, B+-ట్రీ, లావాదేవీలు మరియు మల్టీవర్షన్ని అమలు చేయడానికి కాపీ-ఆన్-రైట్ విధానం. చివరగా, డెజర్ట్ కోసం - ఆచరణాత్మక భాగం. దీనిలో మేము తక్కువ-స్థాయి కీ-విలువ API పైన ఇండెక్స్ ఒకటితో సహా అనేక పట్టికలతో డేటాబేస్ స్కీమాను ఎలా రూపొందించాలో మరియు అమలు చేయాలో చూద్దాం.
2015లో ఒక సంవత్సరం, మా అప్లికేషన్ ఇంటర్ఫేస్ ఎంత తరచుగా లాగ్ అవుతుందో కొలవడానికి మేము ఇబ్బంది పడ్డాము. మేము ఒక కారణం కోసం దీన్ని చేసాము. కొన్నిసార్లు అప్లికేషన్ వినియోగదారు చర్యలకు ప్రతిస్పందించడం ఆపివేస్తుందని మేము తరచుగా ఫిర్యాదులను అందుకుంటున్నాము: బటన్లను నొక్కడం సాధ్యం కాదు, జాబితాలు స్క్రోల్ చేయవు, మొదలైనవి. కొలతల మెకానిక్స్ గురించి చెప్పారు AvitoTechలో, ఇక్కడ నేను సంఖ్యల క్రమాన్ని మాత్రమే ఇస్తాను.
కొలత ఫలితాలు మాకు చల్లని వర్షంగా మారాయి. ఫ్రీజ్ల వల్ల మిగతా వాటి కంటే చాలా ఎక్కువ సమస్యలు ఉన్నాయని తేలింది. ఈ వాస్తవాన్ని గ్రహించే ముందు నాణ్యత యొక్క ప్రధాన సాంకేతిక సూచిక క్రాష్ ఫ్రీగా ఉంటే, అప్పుడు ఫోకస్ తర్వాత మారారు ఫ్రీజ్ ఫ్రీలో.
నిర్మించారు ఫ్రీజ్లతో డాష్బోర్డ్ మరియు ఖర్చు చేసిన తర్వాత పరిమాణాత్మకమైన и నాణ్యత వారి కారణాల విశ్లేషణ, ప్రధాన శత్రువు స్పష్టమైంది - అప్లికేషన్ యొక్క ప్రధాన థ్రెడ్లో భారీ వ్యాపార తర్కం అమలు చేయబడింది. ఈ అవమానానికి సహజమైన ప్రతిచర్య దానిని పని స్ట్రీమ్లలోకి నెట్టాలనే కోరిక. ఈ సమస్యను క్రమపద్ధతిలో పరిష్కరించడానికి, మేము తేలికపాటి నటుల ఆధారంగా బహుళ-థ్రెడ్ నిర్మాణాన్ని ఆశ్రయించాము. నేను iOS ప్రపంచం కోసం దాని అనుసరణకు అంకితం చేసాను రెండు దారాలు సామూహిక Twitter మరియు హబ్రేపై కథనం. ప్రస్తుత కథనంలో భాగంగా, డేటాబేస్ ఎంపికను ప్రభావితం చేసిన నిర్ణయంలోని ఆ అంశాలను నేను నొక్కి చెప్పాలనుకుంటున్నాను.
సిస్టమ్ ఆర్గనైజేషన్ యొక్క యాక్టర్ మోడల్ మల్టీథ్రెడింగ్ దాని రెండవ సారాంశంగా మారుతుందని ఊహిస్తుంది. దానిలోని మోడల్ వస్తువులు స్ట్రీమ్ సరిహద్దులను దాటడానికి ఇష్టపడతాయి. మరియు వారు దీన్ని కొన్నిసార్లు మరియు ఇక్కడ మరియు అక్కడ కాదు, దాదాపు నిరంతరం మరియు ప్రతిచోటా చేస్తారు
సమర్పించబడిన రేఖాచిత్రంలోని మూలస్తంభాలలో డేటాబేస్ ఒకటి. మాక్రోప్యాటర్న్ను అమలు చేయడం దీని ప్రధాన పని షేర్డ్ డేటాబేస్. ఎంటర్ప్రైజ్ ప్రపంచంలో సేవల మధ్య డేటా సమకాలీకరణను నిర్వహించడానికి ఇది ఉపయోగించబడితే, యాక్టర్ ఆర్కిటెక్చర్ విషయంలో - థ్రెడ్ల మధ్య డేటా. అందువల్ల, బహుళ-థ్రెడ్ వాతావరణంలో దానితో పనిచేసేటప్పుడు కనీస ఇబ్బందులను కూడా కలిగించని డేటాబేస్ మాకు అవసరం. ప్రత్యేకించి, దీని నుండి పొందిన వస్తువులు కనీసం థ్రెడ్-సురక్షితమైనవి మరియు ఆదర్శంగా పూర్తిగా మార్చలేనివిగా ఉండాలి. మీకు తెలిసినట్లుగా, రెండోది ఏ లాకింగ్ను ఆశ్రయించకుండా అనేక థ్రెడ్ల నుండి ఏకకాలంలో ఉపయోగించవచ్చు, ఇది పనితీరుపై ప్రయోజనకరమైన ప్రభావాన్ని కలిగి ఉంటుంది.
డేటాబేస్ ఎంపికను ప్రభావితం చేసిన రెండవ ముఖ్యమైన అంశం మా క్లౌడ్ API. ఇది git ద్వారా స్వీకరించబడిన సమకాలీకరణ విధానం ద్వారా ప్రేరణ పొందింది. అతనిలాగే, మేము లక్ష్యంగా పెట్టుకున్నాము ఆఫ్లైన్-మొదటి API, ఇది క్లౌడ్ క్లయింట్లకు సముచితమైనది కంటే ఎక్కువగా కనిపిస్తుంది. వారు క్లౌడ్ యొక్క పూర్తి స్థితిని ఒక్కసారి మాత్రమే పంపిస్తారని భావించబడింది, ఆపై అధిక సంఖ్యలో కేసులలో సమకాలీకరణ మార్పులు చేయడం ద్వారా జరుగుతుంది. అయ్యో, ఈ అవకాశం ఇప్పటికీ సైద్ధాంతిక జోన్లో మాత్రమే ఉంది మరియు క్లయింట్లు ఆచరణలో పాచెస్తో ఎలా పని చేయాలో నేర్చుకోలేదు. దీనికి అనేక ఆబ్జెక్టివ్ కారణాలు ఉన్నాయి, పరిచయం ఆలస్యం చేయకుండా ఉండటానికి, మేము బ్రాకెట్లను వదిలివేస్తాము. ఇప్పుడు, API "A" అని చెప్పినప్పుడు మరియు దాని వినియోగదారు "B" అని చెప్పనప్పుడు ఏమి జరుగుతుందనే దాని గురించి పాఠం యొక్క సూచనాత్మక ముగింపులు మరింత ఆసక్తిని కలిగిస్తాయి.
కాబట్టి, మీరు gitని ఊహించినట్లయితే, పుల్ కమాండ్ను అమలు చేసేటప్పుడు, స్థానిక స్నాప్షాట్కు ప్యాచ్లను వర్తింపజేయడానికి బదులుగా, దాని పూర్తి స్థితిని పూర్తి సర్వర్ స్థితితో పోల్చి చూస్తే, క్లౌడ్లో సమకాలీకరణ ఎలా జరుగుతుందనే దాని గురించి మీకు ఖచ్చితమైన ఆలోచన ఉంటుంది. ఖాతాదారులు. దీన్ని అమలు చేయడానికి, మీరు అన్ని సర్వర్ మరియు స్థానిక ఫైల్ల గురించి మెటా-సమాచారంతో మెమరీలో రెండు DOM ట్రీలను కేటాయించాలని ఊహించడం సులభం. ఒక వినియోగదారు క్లౌడ్లో 500 వేల ఫైల్లను నిల్వ చేస్తే, దానిని సమకాలీకరించడానికి 1 మిలియన్ నోడ్లతో రెండు చెట్లను పునఃసృష్టి మరియు నాశనం చేయడం అవసరం అని తేలింది. కానీ ప్రతి నోడ్ సబ్బ్జెక్ట్ల గ్రాఫ్ను కలిగి ఉన్న మొత్తం. ఈ వెలుగులో, ప్రొఫైలింగ్ ఫలితాలు ఆశించబడ్డాయి. విలీన అల్గారిథమ్ను పరిగణనలోకి తీసుకోకుండానే, భారీ సంఖ్యలో చిన్న వస్తువులను సృష్టించడం మరియు నాశనం చేయడం అనే ప్రక్రియకు చాలా పెన్నీ ఖర్చవుతుందని తేలింది.ప్రాథమిక సమకాలీకరణ ఆపరేషన్ పెద్ద సంఖ్యలో చేర్చబడినందున పరిస్థితి మరింత దిగజారింది. వినియోగదారు స్క్రిప్ట్లు. ఫలితంగా, మేము డేటాబేస్ను ఎంచుకోవడంలో రెండవ ముఖ్యమైన ప్రమాణాన్ని పరిష్కరిస్తాము - వస్తువుల డైనమిక్ కేటాయింపు లేకుండా CRUD కార్యకలాపాలను అమలు చేయగల సామర్థ్యం.
ఇతర అవసరాలు మరింత సాంప్రదాయంగా ఉంటాయి మరియు వాటి మొత్తం జాబితా క్రింది విధంగా ఉంది.
థ్రెడ్ భద్రత.
మల్టీప్రాసెసింగ్. థ్రెడ్ల మధ్య మాత్రమే కాకుండా, ప్రధాన అప్లికేషన్ మరియు iOS పొడిగింపుల మధ్య కూడా స్థితిని సమకాలీకరించడానికి అదే డేటాబేస్ ఉదాహరణను ఉపయోగించాలనే కోరికతో నిర్దేశించబడింది.
నిల్వ చేయబడిన ఎంటిటీలను మార్చలేని వస్తువులుగా సూచించే సామర్థ్యం
CRUD కార్యకలాపాలలో డైనమిక్ కేటాయింపులు లేవు.
ప్రాథమిక లక్షణాల కోసం లావాదేవీ మద్దతు ACID: పరమాణుత్వం, స్థిరత్వం, ఐసోలేషన్ మరియు విశ్వసనీయత.
అత్యంత ప్రజాదరణ పొందిన కేసులను వేగవంతం చేయండి.
ఈ అవసరాల సెట్తో, SQLite ఒక మంచి ఎంపిక. అయితే, ప్రత్యామ్నాయాల అధ్యయనంలో భాగంగా, నాకు ఒక పుస్తకం వచ్చింది "LevelDBతో ప్రారంభించడం". ఆమె నాయకత్వంలో, నిజమైన క్లౌడ్ దృశ్యాలలో వివిధ డేటాబేస్లతో పని వేగాన్ని పోల్చి బెంచ్మార్క్ వ్రాయబడింది. ఫలితం మా క్రూరమైన అంచనాలను మించిపోయింది. అత్యంత జనాదరణ పొందిన సందర్భాల్లో - అన్ని ఫైల్ల క్రమబద్ధీకరించబడిన జాబితాలో కర్సర్ను పొందడం మరియు ఇచ్చిన డైరెక్టరీ కోసం అన్ని ఫైల్ల క్రమబద్ధీకరించబడిన జాబితా - LMDB SQLite కంటే 10 రెట్లు వేగంగా ఉంటుంది. ఎంపిక స్పష్టమైంది.
2. LMDB పొజిషనింగ్
LMDB అనేది చాలా చిన్న లైబ్రరీ (కేవలం 10K అడ్డు వరుసలు) ఇది డేటాబేస్ల యొక్క అత్యల్ప ప్రాథమిక పొరను అమలు చేస్తుంది - నిల్వ.
పై రేఖాచిత్రం LMDBని SQLiteతో పోల్చడం చూపిస్తుంది, ఇది కూడా అధిక స్థాయిలను అమలు చేస్తుంది, సాధారణంగా కోర్ డేటాతో SQLite కంటే సరైనది కాదు. అదే నిల్వ ఇంజిన్లను సమాన పోటీదారులుగా పేర్కొనడం మరింత న్యాయంగా ఉంటుంది - BerkeleyDB, LevelDB, Sophia, RocksDB, మొదలైనవి. LMDB SQLite కోసం స్టోరేజ్ ఇంజిన్ భాగం వలె పని చేసే పరిణామాలు కూడా ఉన్నాయి. అలాంటి ప్రయోగం 2012లో జరిగింది గడిపాడు LMDB ద్వారా హోవార్డ్ చు. Результаты అతని చొరవను OSS ఔత్సాహికులు ఎంచుకున్నారు మరియు వ్యక్తిలో దాని కొనసాగింపును కనుగొన్నారు. LumoSQL. జనవరి 2020లో, ఈ ప్రాజెక్ట్ రచయిత డెన్ షియరర్ సమర్పించారు ఇది LinuxConfAu వద్ద.
LMDB ప్రధానంగా అప్లికేషన్ డేటాబేస్ల కోసం ఇంజిన్గా ఉపయోగించబడుతుంది. లైబ్రరీ దాని రూపానికి డెవలపర్లకు రుణపడి ఉంటుంది OpenLDAP, తమ ప్రాజెక్ట్కు బర్కిలీడిబి ఆధారంగా తీవ్ర అసంతృప్తితో ఉన్నారు. నిరాడంబరమైన లైబ్రరీ నుండి ప్రారంభమవుతుంది btree, హోవార్డ్ చు మన కాలపు అత్యంత ప్రజాదరణ పొందిన ప్రత్యామ్నాయాలలో ఒకదాన్ని సృష్టించగలిగారు. అతను తన చాలా కూల్ నివేదికను ఈ కథకు, అలాగే LMDB యొక్క అంతర్గత నిర్మాణానికి అంకితం చేశాడు. "ది లైట్నింగ్ మెమరీ-మ్యాప్డ్ డేటాబేస్". నిల్వ సౌకర్యాన్ని జయించటానికి ఒక మంచి ఉదాహరణ లియోనిడ్ యూరివ్ (అకా yleoహైలోడ్ 2015లో తన నివేదికలో పాజిటివ్ టెక్నాలజీస్ నుండి "LMDB ఇంజిన్ ఒక ప్రత్యేక ఛాంపియన్". అందులో, అతను రీఓపెన్ఎల్డిఎపిని అమలు చేసే ఇదే విధమైన పని సందర్భంలో ఎల్ఎమ్డిబి గురించి మాట్లాడాడు మరియు లెవెల్డిబి ఇప్పటికే తులనాత్మక విమర్శలకు గురైంది. అమలు ఫలితంగా, సానుకూల సాంకేతికతలు చురుకుగా అభివృద్ధి చెందుతున్న ఫోర్క్ను కూడా కలిగి ఉన్నాయి MDBX చాలా రుచికరమైన ఫీచర్లు, ఆప్టిమైజేషన్లు మరియు బగ్ పరిష్కారాలను.
LMDB తరచుగా నిల్వగా ఉపయోగించబడుతుంది. ఉదాహరణకు, Mozilla Firefox బ్రౌజర్ ఎంచుకున్నారు ఇది అనేక అవసరాల కోసం, మరియు, వెర్షన్ 9, Xcode నుండి ప్రారంభమవుతుంది ప్రాధాన్యం ఇచ్చారు సూచికలను నిల్వ చేయడానికి దాని SQLite.
మొబైల్ డెవలప్మెంట్ ప్రపంచంలో కూడా ఇంజిన్ తనదైన ముద్ర వేసింది. దాని ఉపయోగం యొక్క జాడలు కావచ్చు найти టెలిగ్రామ్ కోసం iOS క్లయింట్లో. లింక్డ్ఇన్ మరింత ముందుకు వెళ్లి దాని స్వదేశీ డేటా కాషింగ్ ఫ్రేమ్వర్క్ రాకెట్ డేటా కోసం LMDBని డిఫాల్ట్ నిల్వగా ఎంచుకుంది, దీని గురించి చెప్పారు 2016లో తన వ్యాసంలో.
ఒరాకిల్ నియంత్రణలోకి వచ్చిన తర్వాత బర్కిలీడిబి వదిలిపెట్టిన గూడులో సూర్యునిలో స్థానం కోసం LMDB విజయవంతంగా పోరాడుతోంది. లైబ్రరీ దాని వేగం మరియు విశ్వసనీయత కోసం దాని సహచరులతో పోలిస్తే కూడా ఇష్టపడుతుంది. మీకు తెలిసినట్లుగా, ఉచిత భోజనాలు లేవు మరియు LMDB మరియు SQLite మధ్య ఎంపిక చేసుకునేటప్పుడు మీరు ఎదుర్కోవాల్సిన ట్రేడ్-ఆఫ్ను నేను నొక్కిచెప్పాలనుకుంటున్నాను. పై రేఖాచిత్రం పెరిగిన వేగం ఎలా సాధించబడుతుందో స్పష్టంగా చూపిస్తుంది. ముందుగా, డిస్క్ స్టోరేజ్ పైన సంగ్రహణ యొక్క అదనపు లేయర్ల కోసం మేము చెల్లించము. మంచి ఆర్కిటెక్చర్ ఇప్పటికీ అవి లేకుండా చేయలేమని స్పష్టంగా ఉంది మరియు అవి అనివార్యంగా అప్లికేషన్ కోడ్లో కనిపిస్తాయి, కానీ అవి చాలా సూక్ష్మంగా ఉంటాయి. అవి నిర్దిష్ట అప్లికేషన్ ద్వారా అవసరం లేని లక్షణాలను కలిగి ఉండవు, ఉదాహరణకు, SQL భాషలో ప్రశ్నలకు మద్దతు. రెండవది, డిస్క్ స్టోరేజీకి చేసిన అభ్యర్థనలపై అప్లికేషన్ ఆపరేషన్ల మ్యాపింగ్ని ఉత్తమంగా అమలు చేయడం సాధ్యమవుతుంది. SQLite అయితే నా పనిలో సగటు అప్లికేషన్ యొక్క సగటు గణాంక అవసరాలపై ఆధారపడి ఉంటుంది, అప్పుడు మీరు, ఒక అప్లికేషన్ డెవలపర్గా, ప్రధాన పనిభార దృశ్యాల గురించి బాగా తెలుసు. మరింత ఉత్పాదక పరిష్కారం కోసం, మీరు ప్రారంభ పరిష్కారం యొక్క అభివృద్ధి కోసం మరియు దాని తదుపరి మద్దతు కోసం పెరిగిన ధర ట్యాగ్ని చెల్లించాలి.
3. LMDB యొక్క మూడు స్తంభాలు
ఎల్ఎమ్డిబిని బర్డ్ఐ వ్యూ నుండి చూసిన తర్వాత, మరింత లోతుగా వెళ్లాల్సిన సమయం వచ్చింది. తదుపరి మూడు విభాగాలు నిల్వ నిర్మాణంపై ఆధారపడిన ప్రధాన స్తంభాల విశ్లేషణకు అంకితం చేయబడతాయి:
డిస్క్తో పని చేయడానికి మరియు అంతర్గత డేటా నిర్మాణాలను సమకాలీకరించడానికి మెకానిజం వలె మెమరీ-మ్యాప్ చేసిన ఫైల్లు.
నిల్వ చేయబడిన డేటా యొక్క నిర్మాణం యొక్క సంస్థగా B+-ట్రీ.
ACID లావాదేవీ లక్షణాలు మరియు మల్టీవర్షన్ను అందించడానికి ఒక విధానంగా కాపీ-ఆన్-రైట్.
3.1 వేల్ #1. మెమరీ మ్యాప్ చేయబడిన ఫైల్లు
మెమరీ-మ్యాప్ చేయబడిన ఫైల్లు చాలా ముఖ్యమైన నిర్మాణ మూలకం, అవి రిపోజిటరీ పేరుతో కూడా కనిపిస్తాయి. నిల్వ చేయబడిన సమాచారానికి యాక్సెస్ యొక్క కాషింగ్ మరియు సింక్రొనైజేషన్ సమస్యలు పూర్తిగా ఆపరేటింగ్ సిస్టమ్కు వదిలివేయబడతాయి. LMDB దానిలో ఏ కాష్లను కలిగి ఉండదు. మ్యాప్ చేసిన ఫైల్ల నుండి నేరుగా డేటాను చదవడం వలన ఇంజిన్ అమలులో చాలా మూలలను కత్తిరించడానికి మిమ్మల్ని అనుమతిస్తుంది కాబట్టి ఇది రచయిత చేతన నిర్ణయం. వాటిలో కొన్ని పూర్తి జాబితా నుండి చాలా దూరంగా ఉంది.
అనేక ప్రక్రియల నుండి పని చేస్తున్నప్పుడు నిల్వలో డేటా యొక్క స్థిరత్వాన్ని నిర్వహించడం ఆపరేటింగ్ సిస్టమ్ యొక్క బాధ్యత అవుతుంది. తదుపరి విభాగంలో, ఈ మెకానిక్స్ వివరంగా మరియు చిత్రాలతో చర్చించబడింది.
కాష్లు లేకపోవడం వల్ల డైనమిక్ కేటాయింపులతో అనుబంధించబడిన ఓవర్హెడ్ నుండి LMDB పూర్తిగా తొలగించబడుతుంది. ఆచరణలో డేటాను చదవడం అంటే వర్చువల్ మెమరీలో సరైన చిరునామాకు పాయింటర్ను సెట్ చేయడం మరియు మరేమీ లేదు. ఇది సైన్స్ ఫిక్షన్ లాగా ఉంది, కానీ స్టోరేజ్ సోర్స్ కోడ్లో కాల్లోక్కి చేసే అన్ని కాల్లు స్టోరేజ్ కాన్ఫిగరేషన్ ఫంక్షన్లో కేంద్రీకృతమై ఉంటాయి.
కాష్లు లేకపోవడం అంటే వాటి యాక్సెస్ని సమకాలీకరించడంతో సంబంధం ఉన్న లాక్లు లేకపోవడం. పాఠకులు, అదే సమయంలో పాఠకుల సంఖ్య ఏకపక్షంగా ఉండవచ్చు, డేటాకు వెళ్లే మార్గంలో ఒక్క మ్యూటెక్స్ను ఎదుర్కోరు. దీని కారణంగా, CPUల సంఖ్య ఆధారంగా పఠన వేగం ఆదర్శవంతమైన సరళ స్కేలబిలిటీని కలిగి ఉంటుంది. LMDBలో, సవరణ కార్యకలాపాలు మాత్రమే సమకాలీకరించబడతాయి. ఒక సమయంలో ఒక రచయిత మాత్రమే ఉండవచ్చు.
LMDB యొక్క మినిమలిజం దాని కోడ్ యొక్క మెషీన్ ప్రాతినిధ్యాన్ని పూర్తిగా తదుపరి స్పీడ్ లక్షణాలతో ప్రాసెసర్ యొక్క L1 కాష్లో ఉంచడానికి అనుమతిస్తుంది.
దురదృష్టవశాత్తూ, iOSలో, మెమరీ-మ్యాప్ చేయబడిన ఫైల్లతో, ప్రతిదీ మనం కోరుకున్నంత మేఘరహితంగా ఉండదు. వారితో మరింత స్పృహతో సంబంధం ఉన్న లోపాల గురించి మాట్లాడటానికి, ఆపరేటింగ్ సిస్టమ్స్లో ఈ మెకానిజంను అమలు చేసే సాధారణ సూత్రాలను గుర్తుంచుకోవడం అవసరం.
మెమరీ-మ్యాప్ చేసిన ఫైల్ల గురించి సాధారణ సమాచారం
రన్ అయ్యే ప్రతి అప్లికేషన్తో, ఆపరేటింగ్ సిస్టమ్ ప్రాసెస్ అనే ఎంటిటీని అనుబంధిస్తుంది. ప్రతి ప్రక్రియకు ఒక వరుస శ్రేణి చిరునామాలు కేటాయించబడతాయి, దీనిలో అది ఆపరేట్ చేయడానికి అవసరమైన ప్రతిదాన్ని ఉంచుతుంది. అత్యల్ప చిరునామాలలో కోడ్ మరియు హార్డ్-కోడెడ్ డేటా మరియు వనరులతో కూడిన విభాగాలు ఉన్నాయి. హీప్ పేరుతో మనకు బాగా తెలిసిన డైనమిక్ అడ్రస్ స్పేస్ యొక్క పెరుగుతున్న బ్లాక్ తర్వాత వస్తుంది. ఇది ప్రోగ్రామ్ యొక్క ఆపరేషన్ సమయంలో కనిపించే ఎంటిటీల చిరునామాలను కలిగి ఉంటుంది. ఎగువన అప్లికేషన్ స్టాక్ ఉపయోగించే మెమరీ ప్రాంతం. ఇది పెరుగుతుంది లేదా కుదించబడుతుంది; మరో మాటలో చెప్పాలంటే, దాని పరిమాణం కూడా డైనమిక్ స్వభావాన్ని కలిగి ఉంటుంది. స్టాక్ మరియు హీప్ ఒకదానికొకటి నెట్టడం మరియు జోక్యం చేసుకోకుండా నిరోధించడానికి, అవి చిరునామా స్థలం యొక్క వేర్వేరు చివర్లలో ఉంటాయి. ఎగువ మరియు దిగువన ఉన్న రెండు డైనమిక్ విభాగాల మధ్య రంధ్రం ఉంటుంది. ఆపరేటింగ్ సిస్టమ్ ఈ మధ్య విభాగంలోని చిరునామాలను ప్రాసెస్తో వివిధ రకాల ఎంటిటీలను అనుబంధించడానికి ఉపయోగిస్తుంది. ప్రత్యేకించి, ఇది డిస్క్లోని ఫైల్తో నిర్దిష్ట నిరంతర చిరునామాల సెట్ను అనుబంధించగలదు. అలాంటి ఫైల్ని మెమరీ మ్యాప్డ్ అంటారు
ప్రక్రియకు కేటాయించిన చిరునామా స్థలం చాలా పెద్దది. సిద్ధాంతపరంగా, చిరునామాల సంఖ్య పాయింటర్ పరిమాణం ద్వారా మాత్రమే పరిమితం చేయబడింది, ఇది సిస్టమ్ యొక్క బిట్ సామర్థ్యం ద్వారా నిర్ణయించబడుతుంది. ఫిజికల్ మెమరీ దానికి 1-టు-1 మ్యాప్ చేయబడితే, మొదటి ప్రక్రియ మొత్తం RAMని ధ్వంసం చేస్తుంది మరియు మల్టీ టాస్కింగ్ గురించి ఎటువంటి చర్చ ఉండదు.
అయినప్పటికీ, ఆధునిక ఆపరేటింగ్ సిస్టమ్లు కోరుకున్నన్ని ప్రక్రియలను ఏకకాలంలో అమలు చేయగలవని మా అనుభవం నుండి మాకు తెలుసు. కాగితంపై ప్రాసెస్లకు చాలా మెమరీని మాత్రమే కేటాయించడం వల్ల ఇది సాధ్యమవుతుంది, అయితే వాస్తవానికి అవి ఇక్కడ మరియు ఇప్పుడు డిమాండ్లో ఉన్న భాగాన్ని మాత్రమే ప్రధాన భౌతిక మెమరీలోకి లోడ్ చేస్తాయి. కాబట్టి, ప్రక్రియతో అనుబంధించబడిన మెమరీని వర్చువల్ అంటారు.
ఆపరేటింగ్ సిస్టమ్ వర్చువల్ మరియు ఫిజికల్ మెమరీని నిర్దిష్ట పరిమాణంలోని పేజీలుగా నిర్వహిస్తుంది. వర్చువల్ మెమరీ యొక్క నిర్దిష్ట పేజీ డిమాండ్లో ఉన్న వెంటనే, ఆపరేటింగ్ సిస్టమ్ దానిని భౌతిక మెమరీలోకి లోడ్ చేస్తుంది మరియు వాటిని ప్రత్యేక పట్టికలో సరిపోల్చుతుంది. ఉచిత స్లాట్లు లేనట్లయితే, గతంలో లోడ్ చేయబడిన పేజీలలో ఒకటి డిస్క్కి కాపీ చేయబడుతుంది మరియు డిమాండ్లో ఉన్నది దాని స్థానంలో ఉంటుంది. మేము త్వరలో తిరిగి వచ్చే ఈ విధానాన్ని మార్పిడి అంటారు. క్రింద ఉన్న బొమ్మ వివరించిన ప్రక్రియను వివరిస్తుంది. దానిపై, చిరునామా 0తో పేజీ A లోడ్ చేయబడింది మరియు చిరునామా 4తో ప్రధాన మెమరీ పేజీలో ఉంచబడింది. ఈ వాస్తవం సెల్ నంబర్ 0లోని కరస్పాండెన్స్ పట్టికలో ప్రతిబింబిస్తుంది.
మెమరీకి మ్యాప్ చేయబడిన ఫైల్లతో కథ సరిగ్గా అదే విధంగా ఉంటుంది. తార్కికంగా, అవి నిరంతరంగా మరియు పూర్తిగా వర్చువల్ అడ్రస్ స్పేస్లో ఉంటాయి. అయినప్పటికీ, అవి పేజీల వారీగా మరియు అభ్యర్థనపై మాత్రమే భౌతిక మెమరీని నమోదు చేస్తాయి. అటువంటి పేజీల సవరణ డిస్క్లోని ఫైల్తో సమకాలీకరించబడుతుంది. ఈ విధంగా, మీరు మెమరీలో బైట్లతో పని చేయడం ద్వారా ఫైల్ I/Oని అమలు చేయవచ్చు - అన్ని మార్పులు ఆపరేటింగ్ సిస్టమ్ కెర్నల్ ద్వారా సోర్స్ ఫైల్కి స్వయంచాలకంగా బదిలీ చేయబడతాయి.
వివిధ ప్రక్రియల నుండి డేటాబేస్తో పని చేస్తున్నప్పుడు LMDB దాని స్థితిని ఎలా సమకాలీకరిస్తుంది అని క్రింది చిత్రం ప్రదర్శిస్తుంది. వేర్వేరు ప్రక్రియల వర్చువల్ మెమరీని ఒకే ఫైల్కు మ్యాప్ చేయడం ద్వారా, LMDB కనిపించే చోట వాటి చిరునామా ఖాళీల యొక్క నిర్దిష్ట బ్లాక్లను ఒకదానితో ఒకటి ట్రాన్సిటివ్గా సమకాలీకరించడానికి మేము ఆపరేటింగ్ సిస్టమ్ను నిర్బంధిస్తాము.
ఒక ముఖ్యమైన సూక్ష్మభేదం ఏమిటంటే, LMDB, డిఫాల్ట్గా, రైట్ సిస్టమ్ కాల్ మెకానిజం ద్వారా డేటా ఫైల్ను సవరించి, ఫైల్ను రీడ్-ఓన్లీ మోడ్లో ప్రదర్శిస్తుంది. ఈ విధానం రెండు ముఖ్యమైన పరిణామాలను కలిగి ఉంది.
మొదటి పరిణామం అన్ని ఆపరేటింగ్ సిస్టమ్లకు సాధారణం. తప్పు కోడ్ ద్వారా డేటాబేస్కు అనుకోకుండా నష్టం జరగకుండా రక్షణను జోడించడం దీని సారాంశం. మీకు తెలిసినట్లుగా, ప్రాసెస్ యొక్క ఎక్జిక్యూటబుల్ సూచనలు దాని చిరునామా స్థలంలో ఎక్కడి నుండైనా డేటాను యాక్సెస్ చేయడానికి ఉచితం. అదే సమయంలో, మేము ఇప్పుడే గుర్తుంచుకున్నట్లుగా, రీడ్-రైట్ మోడ్లో ఫైల్ను ప్రదర్శించడం అంటే ఏదైనా సూచన దానిని సవరించగలదని అర్థం. ఆమె పొరపాటున దీన్ని చేస్తే, ఉదాహరణకు, అసలు ఉనికిలో లేని సూచికలో శ్రేణి మూలకాన్ని తిరిగి వ్రాయడానికి ప్రయత్నిస్తే, ఆమె అనుకోకుండా ఈ చిరునామాకు మ్యాప్ చేయబడిన ఫైల్ను మార్చవచ్చు, ఇది డేటాబేస్ యొక్క అవినీతికి దారి తీస్తుంది. ఫైల్ రీడ్-ఓన్లీ మోడ్లో ప్రదర్శించబడితే, సంబంధిత చిరునామా స్థలాన్ని మార్చే ప్రయత్నం సిగ్నల్తో ప్రోగ్రామ్ యొక్క అత్యవసర ముగింపుకు దారి తీస్తుంది. SIGSEGV, మరియు ఫైల్ చెక్కుచెదరకుండా ఉంటుంది.
రెండవ పరిణామం ఇప్పటికే iOSకి నిర్దిష్టంగా ఉంది. రచయిత లేదా ఏ ఇతర మూలాధారాలు దీనిని స్పష్టంగా పేర్కొనలేదు, కానీ అది లేకుండా LMDB ఈ మొబైల్ ఆపరేటింగ్ సిస్టమ్లో అమలు చేయడానికి తగినది కాదు. తదుపరి విభాగం దాని పరిశీలనకు అంకితం చేయబడింది.
iOSలో మెమరీ-మ్యాప్ చేసిన ఫైల్ల ప్రత్యేకతలు
2018లో WWDCలో అద్భుతమైన నివేదిక వచ్చింది "iOS మెమరీ డీప్ డైవ్". ఇది iOSలో, ఫిజికల్ మెమరీలో ఉన్న అన్ని పేజీలు 3 రకాల్లో ఒకటి అని మాకు చెబుతుంది: మురికి, కుదించబడిన మరియు శుభ్రంగా.
క్లీన్ మెమరీ అనేది భౌతిక మెమరీ నుండి నొప్పి లేకుండా అన్లోడ్ చేయగల పేజీల సమాహారం. వారు కలిగి ఉన్న డేటాను దాని అసలు మూలాల నుండి అవసరమైన విధంగా రీలోడ్ చేయవచ్చు. చదవడానికి-మాత్రమే మెమరీ-మ్యాప్ చేయబడిన ఫైల్లు ఈ వర్గంలోకి వస్తాయి. మెమరీ నుండి ఫైల్కి మ్యాప్ చేయబడిన పేజీలను ఎప్పుడైనా అన్లోడ్ చేయడానికి iOS భయపడదు, ఎందుకంటే అవి డిస్క్లోని ఫైల్తో సమకాలీకరించబడతాయని హామీ ఇవ్వబడుతుంది.
సవరించిన అన్ని పేజీలు అసలు ఎక్కడ ఉన్నా అవి డర్టీ మెమరీలో ముగుస్తాయి. ప్రత్యేకించి, వాటితో అనుబంధించబడిన వర్చువల్ మెమరీకి వ్రాయడం ద్వారా సవరించబడిన మెమరీ-మ్యాప్ చేయబడిన ఫైల్లు ఈ విధంగా వర్గీకరించబడతాయి. ఫ్లాగ్తో LMDBని తెరవడం MDB_WRITEMAP, దానికి మార్పులు చేసిన తర్వాత, మీరు దీన్ని వ్యక్తిగతంగా ధృవీకరించవచ్చు
అప్లికేషన్ చాలా భౌతిక మెమరీని తీసుకోవడం ప్రారంభించిన వెంటనే, iOS దానిని డర్టీ పేజీ కంప్రెషన్కు గురి చేస్తుంది. డర్టీ మరియు కంప్రెస్డ్ పేజీల ద్వారా ఆక్రమించబడిన మొత్తం మెమరీ అప్లికేషన్ యొక్క మెమరీ ఫుట్ప్రింట్ అని పిలవబడేది. అది ఒక నిర్దిష్ట థ్రెషోల్డ్ విలువను చేరుకున్న తర్వాత, OOM కిల్లర్ సిస్టమ్ డెమోన్ ప్రక్రియ తర్వాత వస్తుంది మరియు దానిని బలవంతంగా రద్దు చేస్తుంది. డెస్క్టాప్ ఆపరేటింగ్ సిస్టమ్లతో పోలిస్తే ఇది iOS యొక్క ప్రత్యేకత. దీనికి విరుద్ధంగా, భౌతిక మెమరీ నుండి డిస్క్కి పేజీలను మార్చుకోవడం ద్వారా మెమరీ పాదముద్రను తగ్గించడం iOSలో అందించబడలేదు. కారణాలను మాత్రమే ఊహించవచ్చు. పేజీలను డిస్క్ మరియు వెనుకకు తీవ్రంగా తరలించే విధానం మొబైల్ పరికరాలకు చాలా శక్తిని వినియోగిస్తుంది, లేదా iOS SSD డ్రైవ్లలో సెల్లను తిరిగి వ్రాసే వనరును ఆదా చేస్తుంది లేదా డిజైనర్లు సిస్టమ్ యొక్క మొత్తం పనితీరుతో సంతృప్తి చెందకపోవచ్చు, ఇక్కడ ప్రతిదీ ఉంది. నిరంతరం మార్పిడి. అది ఎలా ఉన్నా, వాస్తవం వాస్తవంగా మిగిలిపోయింది.
శుభవార్త, ఇదివరకే ప్రస్తావించబడింది, ఫైల్లను అప్డేట్ చేయడానికి LMDB డిఫాల్ట్గా mmap మెకానిజంను ఉపయోగించదు. దీనర్థం, ప్రదర్శించబడిన డేటా iOS ద్వారా క్లీన్ మెమరీగా వర్గీకరించబడింది మరియు మెమరీ ఫుట్ప్రింట్కు దోహదం చేయదు. మీరు దీన్ని VM ట్రాకర్ అనే Xcode సాధనాన్ని ఉపయోగించి ధృవీకరించవచ్చు. దిగువ స్క్రీన్షాట్ ఆపరేషన్ సమయంలో క్లౌడ్ అప్లికేషన్ యొక్క iOS వర్చువల్ మెమరీ స్థితిని చూపుతుంది. ప్రారంభంలో, 2 LMDB ఉదంతాలు ఇందులో ప్రారంభించబడ్డాయి. మొదటిది 1GiB వర్చువల్ మెమరీలో తన ఫైల్ను ప్రదర్శించడానికి అనుమతించబడింది, రెండవది - 512MiB. రెండు స్టోరేజీలు కొంత మొత్తంలో రెసిడెంట్ మెమరీని కలిగి ఉన్నప్పటికీ, వాటిలో ఏవీ మురికి పరిమాణాన్ని అందించవు.
మరియు ఇప్పుడు ఇది చెడు వార్తల సమయం. 64-బిట్ డెస్క్టాప్ ఆపరేటింగ్ సిస్టమ్లలోని స్వాప్ మెకానిజంకు ధన్యవాదాలు, ప్రతి ప్రక్రియ దాని సంభావ్య స్వాప్ కోసం ఉచిత హార్డ్ డిస్క్ స్థలం అనుమతించినంత ఎక్కువ వర్చువల్ చిరునామా స్థలాన్ని ఆక్రమించగలదు. iOSలో కుదింపుతో స్వాప్ను భర్తీ చేయడం వలన సైద్ధాంతిక గరిష్టాన్ని తీవ్రంగా తగ్గిస్తుంది. ఇప్పుడు అన్ని జీవన ప్రక్రియలు తప్పనిసరిగా ప్రధాన (RAMని చదవండి) మెమరీకి సరిపోతాయి మరియు సరిపోనివన్నీ తప్పనిసరిగా ముగించవలసి ఉంటుంది. ఇది పైన పేర్కొన్న విధంగా పేర్కొనబడింది నివేదికమరియు లోపల అధికారిక డాక్యుమెంటేషన్. పర్యవసానంగా, iOS mmap ద్వారా కేటాయింపు కోసం అందుబాటులో ఉన్న మెమరీ మొత్తాన్ని తీవ్రంగా పరిమితం చేస్తుంది. ఇక్కడ ఇక్కడ మీరు ఈ సిస్టమ్ కాల్ని ఉపయోగించి వివిధ పరికరాలలో కేటాయించబడే మెమరీ పరిమాణం యొక్క అనుభావిక పరిమితులను చూడవచ్చు. అత్యంత ఆధునిక స్మార్ట్ఫోన్ మోడళ్లలో, iOS 2 గిగాబైట్ల ద్వారా ఉదారంగా మారింది మరియు ఐప్యాడ్ యొక్క టాప్ వెర్షన్లలో - 4 ద్వారా. ఆచరణలో, మీరు అత్యల్ప మద్దతు ఉన్న పరికర నమూనాలపై దృష్టి పెట్టాలి, ఇక్కడ ప్రతిదీ చాలా విచారంగా ఉంటుంది. మరింత దారుణంగా, VM ట్రాకర్లో అప్లికేషన్ యొక్క మెమరీ స్థితిని చూడటం ద్వారా, మీరు LMDB మెమరీ-మ్యాప్ చేయబడిందని క్లెయిమ్ చేసే ఏకైక దానికి దూరంగా ఉన్నట్లు కనుగొంటారు. సిస్టమ్ కేటాయింపుదారులు, వనరుల ఫైల్లు, ఇమేజ్ ఫ్రేమ్వర్క్లు మరియు ఇతర చిన్న ప్రెడేటర్ల ద్వారా మంచి భాగాలు తినేస్తాయి.
క్లౌడ్లోని ప్రయోగాల ఫలితాల ఆధారంగా, మేము LMDB ద్వారా కేటాయించిన మెమరీ కోసం క్రింది రాజీ విలువలకు వచ్చాము: 384-బిట్ పరికరాల కోసం 32 మెగాబైట్లు మరియు 768-బిట్ పరికరాల కోసం 64. ఈ వాల్యూమ్ను ఉపయోగించిన తర్వాత, ఏదైనా సవరణ కార్యకలాపాలు కోడ్తో ముగుస్తాయి MDB_MAP_FULL. మా పర్యవేక్షణలో అటువంటి లోపాలను మేము గమనిస్తాము, కానీ అవి చాలా చిన్నవిగా ఉంటాయి, ఈ దశలో వాటిని నిర్లక్ష్యం చేయవచ్చు.
నిల్వ ద్వారా అధిక మెమరీ వినియోగానికి స్పష్టమైన కారణం కాని దీర్ఘకాలిక లావాదేవీలు కావచ్చు. ఈ రెండు దృగ్విషయాలు ఎలా అనుసంధానించబడి ఉన్నాయో అర్థం చేసుకోవడానికి, LMDB యొక్క మిగిలిన రెండు స్తంభాలను పరిగణనలోకి తీసుకోవడం ద్వారా మాకు సహాయం చేయబడుతుంది.
3.2 వేల్ #2. B+ చెట్టు
కీ-విలువ నిల్వ పైన పట్టికలను అనుకరించడానికి, దాని APIలో కింది కార్యకలాపాలు తప్పనిసరిగా ఉండాలి:
కొత్త మూలకాన్ని చొప్పించడం.
ఇచ్చిన కీతో మూలకం కోసం శోధించండి.
ఒక మూలకాన్ని తీసివేయడం.
కీలు క్రమబద్ధీకరించబడిన క్రమంలో విరామాలపై మళ్ళించండి.
నాలుగు కార్యకలాపాలను సులభంగా అమలు చేయగల సరళమైన డేటా నిర్మాణం బైనరీ శోధన చెట్టు. దానిలోని ప్రతి నోడ్లు చైల్డ్ కీల యొక్క మొత్తం ఉపసమితిని రెండు సబ్ట్రీలుగా విభజించే కీని సూచిస్తాయి. ఎడమవైపు తల్లిదండ్రుల కంటే చిన్నవి మరియు కుడివైపు పెద్దవి ఉన్నాయి. ఆర్డర్ చేయబడిన కీల సెట్ను పొందడం అనేది క్లాసిక్ ట్రీ ట్రావర్సల్స్లో ఒకదాని ద్వారా సాధించబడుతుంది
బైనరీ ట్రీలు డిస్క్-ఆధారిత డేటా స్ట్రక్చర్గా ప్రభావవంతంగా ఉండకుండా నిరోధించే రెండు ప్రాథమిక లోపాలను కలిగి ఉన్నాయి. మొదట, వారి సంతులనం యొక్క డిగ్రీ అనూహ్యమైనది. చెట్లను పొందే గణనీయమైన ప్రమాదం ఉంది, దీనిలో వివిధ శాఖల ఎత్తులు చాలా భిన్నంగా ఉంటాయి, ఇది ఊహించిన దానితో పోలిస్తే శోధన యొక్క అల్గోరిథమిక్ సంక్లిష్టతను గణనీయంగా దిగజారుస్తుంది. రెండవది, నోడ్ల మధ్య క్రాస్-లింక్ల సమృద్ధి బైనరీ ట్రీలను మెమరీలో స్థానికతను కోల్పోతుంది.మూసి నోడ్లు (వాటి మధ్య కనెక్షన్ల పరంగా) వర్చువల్ మెమరీలో పూర్తిగా భిన్నమైన పేజీలలో ఉంటాయి. పర్యవసానంగా, చెట్టులోని అనేక పొరుగు నోడ్ల యొక్క సాధారణ ట్రావెర్సల్కు కూడా పోల్చదగిన సంఖ్యలో పేజీలను సందర్శించడం అవసరం కావచ్చు. ప్రాసెసర్ కాష్లో పేజీలను నిరంతరం తిప్పడం చౌకైన ఆనందం కాదు కాబట్టి, బైనరీ ట్రీల ప్రభావాన్ని ఇన్-మెమరీ డేటా స్ట్రక్చర్గా మాట్లాడేటప్పుడు కూడా ఇది సమస్యగా ఉంటుంది. డిస్క్ నుండి నోడ్లతో అనుబంధించబడిన పేజీలను తరచుగా తిరిగి పొందడం విషయానికి వస్తే, పరిస్థితి పూర్తిగా మారుతుంది దుర్భరమైన.
B-ట్రీలు, బైనరీ ట్రీల యొక్క పరిణామం, మునుపటి పేరాలో గుర్తించబడిన సమస్యలను పరిష్కరిస్తాయి. మొదట, వారు స్వీయ-సమతుల్యతను కలిగి ఉంటారు. రెండవది, వారి నోడ్లలో ప్రతి ఒక్కటి చైల్డ్ కీల సమితిని 2గా కాకుండా M ఆర్డర్ చేసిన ఉపసమితులుగా విభజిస్తుంది మరియు అనేక వందల లేదా వేల సంఖ్యలో కూడా M సంఖ్య చాలా పెద్దదిగా ఉంటుంది.
తద్వారా:
ప్రతి నోడ్లో పెద్ద సంఖ్యలో ఇప్పటికే ఆర్డర్ చేయబడిన కీలు ఉన్నాయి మరియు చెట్లు చాలా తక్కువగా ఉంటాయి.
విలువకు దగ్గరగా ఉండే కీలు సహజంగా ఒకే లేదా పొరుగు నోడ్లలో ఒకదానికొకటి పక్కన ఉన్నందున, చెట్టు మెమరీలో స్థానం యొక్క ప్రాపర్టీని పొందుతుంది.
శోధన ఆపరేషన్ సమయంలో చెట్టు దిగేటప్పుడు రవాణా నోడ్ల సంఖ్య తగ్గించబడుతుంది.
శ్రేణి ప్రశ్నల సమయంలో చదవబడిన లక్ష్య నోడ్ల సంఖ్య తగ్గించబడింది, ఎందుకంటే వాటిలో ప్రతి ఒక్కటి ఇప్పటికే పెద్ద సంఖ్యలో ఆర్డర్ చేసిన కీలను కలిగి ఉన్నాయి.
LMDB డేటాను నిల్వ చేయడానికి B+ చెట్టు అని పిలువబడే B-ట్రీ యొక్క వైవిధ్యాన్ని ఉపయోగిస్తుంది. పైన ఉన్న రేఖాచిత్రం దానిలో ఉన్న మూడు రకాల నోడ్లను చూపుతుంది:
పైభాగంలో రూట్ ఉంది. ఇది గిడ్డంగిలో ఉన్న డేటాబేస్ భావన కంటే మరేమీ కాదు. ఒక LMDB ఉదాహరణలో, మీరు మ్యాప్ చేయబడిన వర్చువల్ అడ్రస్ స్పేస్ను పంచుకునే అనేక డేటాబేస్లను సృష్టించవచ్చు. వాటిలో ప్రతి ఒక్కటి దాని స్వంత మూలం నుండి ప్రారంభమవుతుంది.
అత్యల్ప స్థాయిలో ఆకులు ఉంటాయి. అవి మరియు అవి మాత్రమే డేటాబేస్లో నిల్వ చేయబడిన కీ-విలువ జతలను కలిగి ఉంటాయి. మార్గం ద్వారా, ఇది B+-చెట్ల విశిష్టత. ఒక సాధారణ B-ట్రీ అన్ని స్థాయిల నోడ్లలో విలువైన భాగాలను నిల్వ చేస్తే, B+ వైవిధ్యం అత్యల్పంగా మాత్రమే ఉంటుంది. ఈ వాస్తవాన్ని పరిష్కరించిన తర్వాత, మేము LMDBలో ఉపయోగించిన చెట్టు యొక్క ఉప రకాన్ని కేవలం B-ట్రీ అని పిలుస్తాము.
రూట్ మరియు ఆకుల మధ్య నావిగేషనల్ (బ్రాంచ్) నోడ్లతో 0 లేదా అంతకంటే ఎక్కువ సాంకేతిక స్థాయిలు ఉన్నాయి. ఆకుల మధ్య క్రమబద్ధీకరించబడిన కీల సమితిని విభజించడం వారి పని.
భౌతికంగా, నోడ్లు ముందుగా నిర్ణయించిన పొడవు యొక్క మెమరీ బ్లాక్లు. వాటి పరిమాణం ఆపరేటింగ్ సిస్టమ్లోని మెమరీ పేజీల పరిమాణంలో బహుళంగా ఉంటుంది, మేము పైన చర్చించాము. నోడ్ నిర్మాణం క్రింద చూపబడింది. హెడర్ మెటా సమాచారాన్ని కలిగి ఉంది, ఉదాహరణకు చెక్సమ్లో అత్యంత స్పష్టమైనది. డేటా ఉన్న సెల్లు ఉన్న ఆఫ్సెట్ల గురించి తదుపరి సమాచారం వస్తుంది. మేము నావిగేషన్ నోడ్ల గురించి మాట్లాడుతున్నట్లయితే డేటా కీలు కావచ్చు లేదా ఆకుల విషయంలో మొత్తం కీ-విలువ జంటలు కావచ్చు. మీరు పనిలోని పేజీల నిర్మాణం గురించి మరింత చదవవచ్చు "అధిక పనితీరు కీ-విలువ దుకాణాల మూల్యాంకనం".
పేజీ నోడ్ల అంతర్గత కంటెంట్తో వ్యవహరించిన తర్వాత, మేము ఈ క్రింది రూపంలో LMDB B-ట్రీని సరళీకృత పద్ధతిలో మరింతగా సూచిస్తాము.
నోడ్లతో కూడిన పేజీలు డిస్క్లో వరుసగా ఉంటాయి. అధిక సంఖ్యలో ఉన్న పేజీలు ఫైల్ చివరిలో ఉన్నాయి. మెటా పేజీ అని పిలవబడేది అన్ని చెట్ల మూలాలను కనుగొనగల ఆఫ్సెట్ల గురించి సమాచారాన్ని కలిగి ఉంటుంది. ఫైల్ను తెరిచేటప్పుడు, చెల్లుబాటు అయ్యే మెటా పేజీని వెతకడానికి LMDB ఫైల్ను పేజీలవారీగా చివరి నుండి మొదటి వరకు స్కాన్ చేస్తుంది మరియు దాని ద్వారా ఇప్పటికే ఉన్న డేటాబేస్లను కనుగొంటుంది.
ఇప్పుడు, డేటా సంస్థ యొక్క తార్కిక మరియు భౌతిక నిర్మాణం గురించి ఒక ఆలోచన కలిగి, మేము LMDB యొక్క మూడవ స్తంభాన్ని పరిగణలోకి తీసుకోవచ్చు. దాని సహాయంతో అన్ని స్టోరేజ్ సవరణలు లావాదేవీలపరంగా మరియు ఒకదానికొకటి ఒంటరిగా జరుగుతాయి, మొత్తంగా డేటాబేస్ మల్టీవర్షన్ ఆస్తిని ఇస్తుంది.
3.3 వేల్ #3. కాపీ-ఆన్-రైట్
కొన్ని B-ట్రీ కార్యకలాపాలు దాని నోడ్లకు వరుస మార్పులను కలిగి ఉంటాయి. ఇప్పటికే గరిష్ట సామర్థ్యాన్ని చేరుకున్న నోడ్కి కొత్త కీని జోడించడం ఒక ఉదాహరణ. ఈ సందర్భంలో, ముందుగా, నోడ్ను రెండుగా విభజించడం మరియు రెండవది, దాని పేరెంట్లోని కొత్త బడ్డింగ్ చైల్డ్ నోడ్కు లింక్ను జోడించడం అవసరం. ఈ విధానం చాలా ప్రమాదకరమైనది. కొన్ని కారణాల వల్ల (క్రాష్, విద్యుత్తు అంతరాయం మొదలైనవి) సిరీస్ నుండి మార్పులలో కొంత భాగం మాత్రమే సంభవిస్తే, అప్పుడు చెట్టు అస్థిరమైన స్థితిలో ఉంటుంది.
డేటాబేస్ తప్పు-తట్టుకునేలా చేయడానికి ఒక సాంప్రదాయిక పరిష్కారం ఏమిటంటే, B-ట్రీకి ప్రక్కన అదనపు ఆన్-డిస్క్ డేటా నిర్మాణాన్ని జోడించడం - లావాదేవీ లాగ్, దీనిని రైట్-ఎహెడ్ లాగ్ (WAL) అని కూడా పిలుస్తారు. ఇది బి-ట్రీని సవరించడానికి ముందు ఉద్దేశించిన ఆపరేషన్ ఖచ్చితంగా వ్రాయబడిన ఒక ఫైల్. ఈ విధంగా, స్వీయ-నిర్ధారణ సమయంలో డేటా అవినీతిని గుర్తించినట్లయితే, డేటాబేస్ లాగ్ను క్రమంలో ఉంచడానికి సంప్రదిస్తుంది.
LMDB కాపీ-ఆన్-రైట్ అని పిలవబడే తప్పు సహనం మెకానిజం వలె వేరే పద్ధతిని ఎంచుకుంది. దీని సారాంశం ఏమిటంటే, ఇప్పటికే ఉన్న పేజీలో డేటాను నవీకరించడానికి బదులుగా, ఇది మొదట దాన్ని పూర్తిగా కాపీ చేస్తుంది మరియు కాపీలో అన్ని మార్పులను చేస్తుంది.
తరువాత, నవీకరించబడిన డేటా అందుబాటులో ఉండాలంటే, దాని పేరెంట్ నోడ్లో ప్రస్తుత నోడ్కు లింక్ను మార్చడం అవసరం. దీని కోసం అది కూడా సవరించాలి కాబట్టి, అది కూడా ముందే కాపీ చేయబడింది. ప్రక్రియ రూట్ వరకు పునరావృతంగా కొనసాగుతుంది. మార్చవలసిన చివరి విషయం మెటా పేజీలోని డేటా.
అప్డేట్ ప్రక్రియలో అకస్మాత్తుగా ప్రక్రియ క్రాష్ అయినట్లయితే, కొత్త మెటా పేజీ సృష్టించబడదు లేదా పూర్తిగా డిస్క్కి వ్రాయబడదు మరియు దాని చెక్సమ్ తప్పుగా ఉంటుంది. ఈ రెండింటిలో దేనిలోనైనా, కొత్త పేజీలు అందుబాటులో ఉండవు, కానీ పాతవి ప్రభావితం కావు. ఇది డేటా అనుగుణ్యతను నిర్వహించడానికి LMDB ముందు లాగ్ను వ్రాయవలసిన అవసరాన్ని తొలగిస్తుంది. వాస్తవంగా, పైన వివరించిన డిస్క్లోని డేటా నిల్వ నిర్మాణం ఏకకాలంలో దాని పనితీరును తీసుకుంటుంది. స్పష్టమైన లావాదేవీ లాగ్ లేకపోవడం అనేది అధిక డేటా రీడింగ్ వేగాన్ని అందించే LMDB లక్షణాలలో ఒకటి.
అనుబంధం-మాత్రమే B-ట్రీ అని పిలువబడే ఫలిత రూపకల్పన సహజంగా లావాదేవీల ఐసోలేషన్ మరియు బహుళ-వెర్షనింగ్ను అందిస్తుంది. LMDBలో, ప్రతి బహిరంగ లావాదేవీ ప్రస్తుతం సంబంధిత ట్రీ రూట్తో అనుబంధించబడుతుంది. లావాదేవీ పూర్తయ్యే వరకు, దానితో అనుబంధించబడిన చెట్టు యొక్క పేజీలు ఎప్పటికీ మార్చబడవు లేదా డేటా యొక్క కొత్త వెర్షన్ల కోసం మళ్లీ ఉపయోగించబడవు. కాబట్టి, మీరు ఆ సమయంలో సంబంధిత డేటా సెట్తో మీకు నచ్చినంత కాలం పని చేయవచ్చు. ఈ సమయంలో నిల్వ చురుకుగా నవీకరించబడటం కొనసాగించినప్పటికీ, లావాదేవీ తెరవబడింది. ఇది మల్టీవర్షన్ యొక్క సారాంశం, LMDBని మన ప్రియమైనవారికి ఆదర్శవంతమైన డేటా మూలంగా మారుస్తుంది UICollectionView. లావాదేవీని తెరిచిన తర్వాత, ఏమీ లేకుండా పోతుందనే భయంతో, ప్రస్తుత డేటాను కొన్ని ఇన్-మెమరీ నిర్మాణంలోకి పంపింగ్ చేయడం ద్వారా అప్లికేషన్ యొక్క మెమరీ పాదముద్రను పెంచాల్సిన అవసరం లేదు. ఈ ఫీచర్ LMDBని అదే SQLite నుండి వేరు చేస్తుంది, ఇది అటువంటి మొత్తం ఐసోలేషన్ గురించి గొప్పగా చెప్పుకోదు. రెండవదానిలో రెండు లావాదేవీలను తెరిచి, వాటిలో ఒకదానిలో నిర్దిష్ట రికార్డును తొలగించిన తర్వాత, మిగిలిన రెండవ దానిలో అదే రికార్డును పొందడం సాధ్యం కాదు.
నాణెం యొక్క ఫ్లిప్ సైడ్ అనేది వర్చువల్ మెమరీ యొక్క అధిక వినియోగం. డేటాబేస్ యొక్క విభిన్న సంస్కరణలను చూసే 3 ఓపెన్ రీడ్ లావాదేవీలతో ఏకకాలంలో సవరించబడినట్లయితే, డేటాబేస్ నిర్మాణం ఎలా ఉంటుందో స్లయిడ్ చూపిస్తుంది. ప్రస్తుత లావాదేవీలతో అనుబంధించబడిన రూట్ల నుండి రీచ్ అయ్యే నోడ్లను LMDB మళ్లీ ఉపయోగించదు కాబట్టి, స్టోర్కు మెమరీలో మరో నాల్గవ రూట్ను కేటాయించడం మరియు దాని కింద సవరించిన పేజీలను మరోసారి క్లోన్ చేయడం తప్ప వేరే మార్గం లేదు.
ఇక్కడ మెమొరీ-మ్యాప్ చేసిన ఫైల్ల విభాగాన్ని రీకాల్ చేయడం ఉపయోగకరంగా ఉంటుంది. వర్చువల్ మెమరీ యొక్క అదనపు వినియోగం మనల్ని పెద్దగా చింతించనవసరం లేదు, ఎందుకంటే ఇది అప్లికేషన్ యొక్క మెమరీ పాదముద్రకు దోహదం చేయదు. అయితే, అదే సమయంలో, iOS దానిని కేటాయించడంలో చాలా మొండిగా వ్యవహరిస్తుందని గుర్తించబడింది మరియు మేము సర్వర్ లేదా డెస్క్టాప్లో వలె, 1 టెరాబైట్ LMDB ప్రాంతాన్ని అందించలేము మరియు ఈ ఫీచర్ గురించి అస్సలు ఆలోచించలేము. వీలైతే, మీరు లావాదేవీల జీవితకాలం సాధ్యమైనంత తక్కువగా చేయడానికి ప్రయత్నించాలి.
4. కీ-విలువ API పైన డేటా స్కీమా రూపకల్పన
LMDB అందించిన ప్రాథమిక సారాంశాలను చూడటం ద్వారా మా API విశ్లేషణను ప్రారంభిద్దాం: పర్యావరణం మరియు డేటాబేస్లు, కీలు మరియు విలువలు, లావాదేవీలు మరియు కర్సర్లు.
కోడ్ జాబితాల గురించి ఒక గమనిక
పబ్లిక్ LMDB APIలోని అన్ని ఫంక్షన్లు తమ పని ఫలితాన్ని ఎర్రర్ కోడ్ రూపంలో అందజేస్తాయి, అయితే అన్ని తదుపరి జాబితాలలో సంక్షిప్తత కోసం దాని ధృవీకరణ విస్మరించబడింది. ఆచరణలో, మేము రిపోజిటరీతో పరస్పర చర్య చేయడానికి మా స్వంతాన్ని కూడా ఉపయోగించాము. ఫోర్క్ C++ రేపర్లు lmdbxx, దీనిలో లోపాలు C++ మినహాయింపులుగా వర్తిస్తాయి.
IOS లేదా macOS కోసం ప్రాజెక్ట్కి LMDBని కనెక్ట్ చేయడానికి వేగవంతమైన మార్గంగా, నేను నా CocoaPodని సూచిస్తున్నాను POSLMDB.
4.1. ప్రాథమిక సంగ్రహణలు
పర్యావరణం
నిర్మాణం MDB_env LMDB యొక్క అంతర్గత స్థితి యొక్క రిపోజిటరీ. ఉపసర్గ ఫంక్షన్ కుటుంబం mdb_env దాని కొన్ని లక్షణాలను కాన్ఫిగర్ చేయడానికి మిమ్మల్ని అనుమతిస్తుంది. సరళమైన సందర్భంలో, ఇంజిన్ ప్రారంభించడం ఇలా కనిపిస్తుంది.
Mail.ru క్లౌడ్ అప్లికేషన్లో, మేము రెండు పారామితుల డిఫాల్ట్ విలువలను మాత్రమే మార్చాము.
మొదటిది స్టోరేజ్ ఫైల్ మ్యాప్ చేయబడిన వర్చువల్ అడ్రస్ స్పేస్ పరిమాణం. దురదృష్టవశాత్తూ, అదే పరికరంలో కూడా, నిర్దిష్ట విలువ రన్ నుండి రన్ వరకు గణనీయంగా మారవచ్చు. iOS యొక్క ఈ లక్షణాన్ని పరిగణనలోకి తీసుకోవడానికి, గరిష్ట నిల్వ వాల్యూమ్ డైనమిక్గా ఎంచుకోబడుతుంది. నిర్దిష్ట విలువ నుండి ప్రారంభించి, ఇది ఫంక్షన్ వరకు వరుసగా సగానికి తగ్గించబడుతుంది mdb_env_open నుండి భిన్నమైన ఫలితాన్ని అందించదు ENOMEM. సిద్ధాంతంలో, వ్యతిరేక మార్గం కూడా ఉంది - మొదట ఇంజిన్కు కనీస మెమరీని కేటాయించండి, ఆపై, లోపాలు వచ్చినప్పుడు, MDB_MAP_FULL, పెంచండి. అయితే, ఇది చాలా ముళ్లతో కూడుకున్నది. కారణం ఏమిటంటే, ఫంక్షన్ని ఉపయోగించి మెమరీని (రీమ్యాప్) తిరిగి కేటాయించే విధానం mdb_env_set_map_size ఇంజిన్ నుండి గతంలో స్వీకరించిన అన్ని ఎంటిటీలను (కర్సర్లు, లావాదేవీలు, కీలు మరియు విలువలు) చెల్లుబాటు కాకుండా చేస్తుంది. కోడ్లో ఈ సంఘటనల టర్న్ను పరిగణనలోకి తీసుకుంటే దాని ముఖ్యమైన సంక్లిష్టతకు దారి తీస్తుంది. అయితే, వర్చువల్ మెమరీ మీకు చాలా ముఖ్యమైనది అయితే, ఇది చాలా ముందుకు వెళ్లిన ఫోర్క్ను నిశితంగా పరిశీలించడానికి కారణం కావచ్చు. MDBX, ప్రకటించిన ఫీచర్లలో “ఆటోమేటిక్ ఆన్-ది-ఫ్లై డేటాబేస్ సైజు సర్దుబాటు” ఉంది.
రెండవ పరామితి, డిఫాల్ట్ విలువ మాకు సరిపోదు, థ్రెడ్ భద్రతను నిర్ధారించే మెకానిక్లను నియంత్రిస్తుంది. దురదృష్టవశాత్తూ, కనీసం iOS 10 థ్రెడ్ స్థానిక నిల్వకు మద్దతుతో సమస్యలను కలిగి ఉంది. ఈ కారణంగా, పై ఉదాహరణలో, రిపోజిటరీ ఫ్లాగ్తో తెరవబడుతుంది MDB_NOTLS. దీనికి తోడు అవసరం కూడా వచ్చింది ఫోర్క్ C++ రేపర్ lmdbxxఈ లక్షణం మరియు దానిలోని వేరియబుల్స్ను కత్తిరించడానికి.
డేటాబేస్లు
డేటాబేస్ అనేది మేము పైన చర్చించిన ఒక ప్రత్యేక B-ట్రీ ఉదాహరణ. లావాదేవీ లోపల దాని తెరవడం జరుగుతుంది, ఇది మొదట కొంచెం వింతగా అనిపించవచ్చు.
నిజానికి, LMDBలో లావాదేవీ అనేది స్టోరేజ్ ఎంటిటీ, నిర్దిష్ట డేటాబేస్ ఎంటిటీ కాదు. విభిన్న డేటాబేస్లలో ఉన్న ఎంటిటీలపై అణు కార్యకలాపాలను నిర్వహించడానికి ఈ భావన మిమ్మల్ని అనుమతిస్తుంది. సిద్ధాంతంలో, ఇది వేర్వేరు డేటాబేస్ల రూపంలో మోడలింగ్ పట్టికల అవకాశాన్ని తెరుస్తుంది, కానీ ఒక సమయంలో నేను వేరే మార్గాన్ని తీసుకున్నాను, క్రింద వివరంగా వివరించబడింది.
కీలు మరియు విలువలు
నిర్మాణం MDB_val కీ మరియు విలువ రెండింటి భావనను మోడల్ చేస్తుంది. రిపోజిటరీకి వాటి అర్థశాస్త్రం గురించి తెలియదు. ఆమె కోసం, మరేదైనా ఇవ్వబడిన పరిమాణంలోని బైట్ల శ్రేణి మాత్రమే. గరిష్ట కీ పరిమాణం 512 బైట్లు.
కంపారిటర్ని ఉపయోగించి, స్టోర్ కీలను ఆరోహణ క్రమంలో క్రమబద్ధీకరిస్తుంది. మీరు దానిని మీ స్వంతదానితో భర్తీ చేయకుంటే, డిఫాల్ట్ ఒకటి ఉపయోగించబడుతుంది, ఇది వాటిని బైట్-బైట్గా నిఘంటువు క్రమంలో క్రమబద్ధీకరిస్తుంది.
లావాదేవీలు
లావాదేవీ నిర్మాణం వివరంగా వివరించబడింది మునుపటి అధ్యాయం, ఇక్కడ నేను వారి ప్రధాన లక్షణాలను క్లుప్తంగా పునరావృతం చేస్తాను:
అన్ని ప్రాథమిక లక్షణాలకు మద్దతు ఇస్తుంది ACID: పరమాణుత్వం, స్థిరత్వం, ఐసోలేషన్ మరియు విశ్వసనీయత. MacOS మరియు iOSలో మన్నిక పరంగా MDBXలో పరిష్కరించబడిన బగ్ ఉందని నేను గమనించలేను. మీరు వాటిలో మరింత చదవవచ్చు README.
మల్టీథ్రెడింగ్ విధానం "సింగిల్ రైటర్ / మల్టిపుల్ రీడర్స్" పథకం ద్వారా వివరించబడింది. రచయితలు ఒకరినొకరు నిరోధించుకుంటారు, కానీ పాఠకులను నిరోధించరు. పాఠకులు రచయితలను లేదా ఒకరినొకరు అడ్డుకోరు.
సమూహ లావాదేవీలకు మద్దతు.
మల్టీవర్షన్ మద్దతు.
LMDBలో మల్టీవర్షన్ చాలా బాగుంది కాబట్టి నేను దానిని చర్యలో ప్రదర్శించాలనుకుంటున్నాను. దిగువ కోడ్ నుండి మీరు ప్రతి లావాదేవీ తెరిచిన సమయంలో ప్రస్తుత డేటాబేస్ వెర్షన్తో సరిగ్గా పని చేస్తుందని, అన్ని తదుపరి మార్పుల నుండి పూర్తిగా వేరుచేయబడిందని మీరు చూడవచ్చు. నిల్వను ప్రారంభించడం మరియు దానికి టెస్ట్ రికార్డ్ను జోడించడం ఆసక్తికరంగా ఏదైనా ప్రాతినిధ్యం వహించదు, కాబట్టి ఈ ఆచారాలు స్పాయిలర్ కింద వదిలివేయబడతాయి.
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-ట్రీ ట్రావర్సల్ ద్వారా కీ-వాల్యూ జతలపై క్రమబద్ధంగా పునరావృతం చేయడానికి ఒక యంత్రాంగాన్ని అందిస్తాయి. అవి లేకుండా, డేటాబేస్లోని పట్టికలను సమర్థవంతంగా మోడల్ చేయడం అసాధ్యం, ఇప్పుడు మనం ఆశ్రయిస్తాము.
4.2 టేబుల్ మోడలింగ్
కీ ఆర్డరింగ్ యొక్క ఆస్తి ప్రాథమిక సంగ్రహాల పైన పట్టిక వంటి ఉన్నత-స్థాయి సంగ్రహణను నిర్మించడానికి మిమ్మల్ని అనుమతిస్తుంది. క్లౌడ్ క్లయింట్ యొక్క ప్రధాన పట్టిక యొక్క ఉదాహరణను ఉపయోగించి ఈ ప్రక్రియను పరిశీలిద్దాం, ఇది వినియోగదారు యొక్క అన్ని ఫైల్లు మరియు ఫోల్డర్ల గురించి సమాచారాన్ని కాష్ చేస్తుంది.
టేబుల్ స్కీమా
ఫోల్డర్ ట్రీతో కూడిన టేబుల్ స్ట్రక్చర్ను రూపొందించాల్సిన సాధారణ దృశ్యాలలో ఒకటి, ఇచ్చిన డైరెక్టరీలో ఉన్న అన్ని ఎలిమెంట్ల ఎంపిక. ఈ రకమైన సమర్థవంతమైన ప్రశ్నల కోసం మంచి డేటా ఆర్గనైజేషన్ మోడల్ అనుబంధ జాబితా. కీ-విలువ నిల్వ పైన దీన్ని అమలు చేయడానికి, ఫైల్లు మరియు ఫోల్డర్ల కీలను పేరెంట్ డైరెక్టరీలో వాటి సభ్యత్వం ఆధారంగా సమూహం చేసే విధంగా క్రమబద్ధీకరించడం అవసరం. అదనంగా, డైరెక్టరీలోని కంటెంట్లను Windows వినియోగదారుకు (మొదటి ఫోల్డర్లు, తర్వాత ఫైల్లు, రెండూ అక్షర క్రమంలో క్రమబద్ధీకరించబడతాయి) తెలిసిన రూపంలో ప్రదర్శించడానికి, కీలో సంబంధిత అదనపు ఫీల్డ్లను చేర్చడం అవసరం.
క్రింద ఉన్న చిత్రం, చేతిలో ఉన్న టాస్క్ ఆధారంగా, బైట్ అర్రే రూపంలో కీల ప్రాతినిధ్యం ఎలా ఉంటుందో చూపిస్తుంది. పేరెంట్ డైరెక్టరీ (ఎరుపు) ఐడెంటిఫైయర్తో బైట్లు మొదటగా ఉంచబడతాయి, తర్వాత రకం (ఆకుపచ్చ) మరియు టెయిల్లో పేరు (నీలం)తో ఉంటాయి. డిఫాల్ట్ LMDB కంపారిటర్ ద్వారా నిఘంటువు క్రమంలో క్రమబద్ధీకరించబడి, అవి అవసరమైన పద్ధతి. అదే ఎరుపు ఉపసర్గతో కీలను సీక్వెన్షియల్గా ట్రావెసింగ్ చేయడం వలన అదనపు పోస్ట్-ప్రాసెసింగ్ అవసరం లేకుండా వినియోగదారు ఇంటర్ఫేస్లో (కుడివైపు) ప్రదర్శించబడే క్రమంలో వాటి అనుబంధిత విలువలను మాకు అందిస్తుంది.
సీరియలైజింగ్ కీలు మరియు విలువలు
వస్తువులను సీరియల్గా మార్చడానికి అనేక పద్ధతులు ప్రపంచంలో కనుగొనబడ్డాయి. మాకు వేగం తప్ప మరే ఇతర అవసరం లేనందున, మేము మనకు సాధ్యమైనంత వేగవంతమైనదాన్ని ఎంచుకున్నాము - C లాంగ్వేజ్ స్ట్రక్చర్ యొక్క ఉదాహరణ ద్వారా ఆక్రమించబడిన మెమరీ యొక్క డంప్. ఆ విధంగా, డైరెక్టరీ మూలకం యొక్క కీని క్రింది నిర్మాణంతో రూపొందించవచ్చు. NodeKey.
కాపాడడానికి NodeKey వస్తువులో అవసరమైన నిల్వలో MDB_val డేటా పాయింటర్ను నిర్మాణం యొక్క ప్రారంభ చిరునామాకు ఉంచండి మరియు ఫంక్షన్తో వాటి పరిమాణాన్ని లెక్కించండి sizeof.
డేటాబేస్ ఎంపిక ప్రమాణాలపై మొదటి అధ్యాయంలో, CRUD కార్యకలాపాలలో డైనమిక్ కేటాయింపులను ఒక ముఖ్యమైన ఎంపిక అంశంగా తగ్గించడాన్ని నేను ప్రస్తావించాను. ఫంక్షన్ కోడ్ serialize LMDB విషయంలో డేటాబేస్లో కొత్త రికార్డులను చొప్పించేటప్పుడు వాటిని పూర్తిగా ఎలా నివారించవచ్చో చూపిస్తుంది. సర్వర్ నుండి ఇన్కమింగ్ బైట్ శ్రేణి మొదట స్టాక్ స్ట్రక్చర్లుగా రూపాంతరం చెందుతుంది, ఆపై అవి తృణప్రాయంగా నిల్వలోకి డంప్ చేయబడతాయి. LMDB లోపల డైనమిక్ కేటాయింపులు కూడా లేవని పరిగణనలోకి తీసుకుంటే, మీరు iOS ప్రమాణాల ద్వారా అద్భుతమైన పరిస్థితిని పొందవచ్చు - నెట్వర్క్ నుండి డిస్క్కు మొత్తం మార్గంలో డేటాతో పని చేయడానికి స్టాక్ మెమరీని మాత్రమే ఉపయోగించండి!
బైనరీ కంపారిటర్తో కీలను ఆర్డర్ చేయడం
కీ ఆర్డర్ సంబంధం కంపారిటర్ అని పిలువబడే ప్రత్యేక ఫంక్షన్ ద్వారా పేర్కొనబడింది. ఇంజిన్కు అవి కలిగి ఉన్న బైట్ల సెమాంటిక్స్ గురించి ఏమీ తెలియదు కాబట్టి, డిఫాల్ట్ కంపారిటర్కి కీలను లెక్సికోగ్రాఫిక్ క్రమంలో అమర్చడం తప్ప వేరే మార్గం లేదు, బైట్-బై-బైట్ పోలికను ఆశ్రయిస్తుంది. నిర్మాణాలను నిర్వహించడానికి దీనిని ఉపయోగించడం అనేది గొడ్డలితో షేవింగ్ చేయడం లాంటిది. అయితే, సాధారణ సందర్భాలలో నేను ఈ పద్ధతి ఆమోదయోగ్యమైనదిగా భావిస్తున్నాను. ప్రత్యామ్నాయం క్రింద వివరించబడింది, కానీ ఇక్కడ నేను ఈ మార్గంలో చెల్లాచెదురుగా ఉన్న రెండు రేక్లను గమనిస్తాను.
గుర్తుంచుకోవలసిన మొదటి విషయం ఆదిమ డేటా రకాల మెమరీ ప్రాతినిధ్యం. అందువలన, అన్ని Apple పరికరాలలో, పూర్ణాంక వేరియబుల్స్ ఫార్మాట్లో నిల్వ చేయబడతాయి లిటిల్ ఎండియన్. దీని అర్థం తక్కువ ముఖ్యమైన బైట్ ఎడమవైపు ఉంటుంది మరియు బైట్-బై-బైట్ పోలికను ఉపయోగించి పూర్ణాంకాలను క్రమబద్ధీకరించడం సాధ్యం కాదు. ఉదాహరణకు, 0 నుండి 511 వరకు ఉన్న సంఖ్యల సమితితో దీన్ని చేయడానికి ప్రయత్నిస్తే కింది ఫలితం వస్తుంది.
ఈ సమస్యను పరిష్కరించడానికి, పూర్ణాంకాలు తప్పనిసరిగా బైట్-బైట్ కంపారిటర్కు తగిన ఆకృతిలో కీలో నిల్వ చేయబడాలి. కుటుంబం నుండి వచ్చే విధులు అవసరమైన పరివర్తనను నిర్వహించడానికి మీకు సహాయపడతాయి hton* (ముఖ్యంగా htons ఉదాహరణ నుండి డబుల్-బైట్ సంఖ్యల కోసం).
ప్రోగ్రామింగ్లో స్ట్రింగ్లను సూచించే ఫార్మాట్, మీకు తెలిసినట్లుగా, మొత్తం కథ. స్ట్రింగ్ల సెమాంటిక్స్, అలాగే వాటిని మెమరీలో సూచించడానికి ఉపయోగించే ఎన్కోడింగ్, ఒక్కో అక్షరానికి ఒకటి కంటే ఎక్కువ బైట్లు ఉండవచ్చని సూచిస్తే, డిఫాల్ట్ కంపారిటర్ను ఉపయోగించాలనే ఆలోచనను వెంటనే వదిలివేయడం మంచిది.
గుర్తుంచుకోవలసిన రెండవ విషయం అమరిక సూత్రాలు నిర్మాణం ఫీల్డ్ కంపైలర్. వాటి కారణంగా, ఫీల్డ్ల మధ్య మెమరీలో చెత్త విలువలతో కూడిన బైట్లు ఏర్పడతాయి, ఇది బైట్-బైట్ సార్టింగ్ను విచ్ఛిన్నం చేస్తుంది. చెత్తను తొలగించడానికి, మీరు ఖచ్చితంగా నిర్వచించిన క్రమంలో ఫీల్డ్లను డిక్లేర్ చేయాలి, అమరిక నియమాలను దృష్టిలో ఉంచుకోవాలి లేదా నిర్మాణ ప్రకటనలోని లక్షణాన్ని ఉపయోగించాలి packed.
బాహ్య కంపారిటర్తో కీలను ఆర్డర్ చేయడం
బైనరీ కంపారిటర్కి కీ పోలిక తర్కం చాలా క్లిష్టంగా ఉండవచ్చు. నిర్మాణాలలో సాంకేతిక రంగాల ఉనికి అనేక కారణాలలో ఒకటి. మనకు ఇప్పటికే తెలిసిన డైరెక్టరీ ఎలిమెంట్ కోసం కీ యొక్క ఉదాహరణను ఉపయోగించి వాటి సంభవాన్ని నేను వివరిస్తాను.
దాని సరళత ఉన్నప్పటికీ, చాలా సందర్భాలలో ఇది చాలా మెమరీని వినియోగిస్తుంది. పేరు కోసం బఫర్ 256 బైట్లను తీసుకుంటుంది, అయితే సగటు ఫైల్ మరియు ఫోల్డర్ పేర్లు అరుదుగా 20-30 అక్షరాలను మించి ఉంటాయి.
రికార్డ్ పరిమాణాన్ని ఆప్టిమైజ్ చేయడానికి ప్రామాణిక పద్ధతుల్లో ఒకటి దానిని వాస్తవ పరిమాణానికి "ట్రిమ్" చేయడం. దీని సారాంశం ఏమిటంటే, అన్ని వేరియబుల్-పొడవు ఫీల్డ్ల కంటెంట్లు నిర్మాణం చివరిలో బఫర్లో నిల్వ చేయబడతాయి మరియు వాటి పొడవులు ప్రత్యేక వేరియబుల్స్లో నిల్వ చేయబడతాయి. ఈ విధానం ప్రకారం, కీ NodeKey క్రింది విధంగా రూపాంతరం చెందింది.
ఇంకా, సీరియల్ చేస్తున్నప్పుడు, డేటా పరిమాణం పేర్కొనబడలేదు sizeof మొత్తం నిర్మాణం, మరియు అన్ని ఫీల్డ్ల పరిమాణం స్థిర పొడవు మరియు బఫర్లో వాస్తవంగా ఉపయోగించిన భాగం యొక్క పరిమాణం.
రీఫ్యాక్టరింగ్ ఫలితంగా, కీలు ఆక్రమించిన స్థలంలో మేము గణనీయమైన పొదుపులను పొందాము. అయితే, సాంకేతిక రంగాల కారణంగా nameLength, డిఫాల్ట్ బైనరీ కంపారిటర్ ఇకపై కీ పోలికకు తగినది కాదు. మేము దానిని మా స్వంతదానితో భర్తీ చేయకపోతే, పేరు యొక్క పొడవు పేరు కంటే క్రమబద్ధీకరణలో అధిక ప్రాధాన్యత కారకంగా ఉంటుంది.
LMDB ప్రతి డేటాబేస్ దాని స్వంత కీ పోలిక ఫంక్షన్ను కలిగి ఉండటానికి అనుమతిస్తుంది. ఇది ఫంక్షన్ ఉపయోగించి చేయబడుతుంది mdb_set_compare ఖచ్చితంగా తెరవడానికి ముందు. స్పష్టమైన కారణాల వల్ల, డేటాబేస్ జీవితాంతం మార్చబడదు. కంపారిటర్ బైనరీ ఫార్మాట్లో ఇన్పుట్గా రెండు కీలను స్వీకరిస్తుంది మరియు అవుట్పుట్ వద్ద అది పోలిక ఫలితాన్ని అందిస్తుంది: (-1) కంటే తక్కువ), (1) కంటే ఎక్కువ లేదా (0)కి సమానం. కోసం సూడోకోడ్ NodeKey అన్నట్లుంది.
int compare(MDB_val * const a, MDB_val * const b) {
NodeKey * const aKey = (NodeKey * const)a->mv_data;
NodeKey * const bKey = (NodeKey * const)b->mv_data;
return // ...
}
డేటాబేస్లోని అన్ని కీలు ఒకే రకంగా ఉన్నంత వరకు, బేషరతుగా అప్లికేషన్ కీ నిర్మాణం యొక్క రకానికి వాటి బైట్ ప్రాతినిధ్యాన్ని ప్రసారం చేయడం చట్టబద్ధం. ఇక్కడ ఒక స్వల్పభేదం ఉంది, కానీ ఇది "రీడింగ్ రికార్డ్స్" ఉపవిభాగంలో క్రింద చర్చించబడుతుంది.
ధారావాహిక విలువలు
LMDB నిల్వ చేయబడిన రికార్డుల కీలతో చాలా ఇంటెన్సివ్గా పనిచేస్తుంది. ఒకదానికొకటి వారి పోలిక ఏదైనా అనువర్తిత ఆపరేషన్ యొక్క ఫ్రేమ్వర్క్లో సంభవిస్తుంది మరియు మొత్తం పరిష్కారం యొక్క పనితీరు కంపారిటర్ యొక్క వేగంపై ఆధారపడి ఉంటుంది. ఆదర్శవంతమైన ప్రపంచంలో, డిఫాల్ట్ బైనరీ కంపారిటర్ కీలను సరిపోల్చడానికి సరిపోతుంది, కానీ మీరు మీ స్వంతంగా ఉపయోగించాల్సి వస్తే, దానిలోని కీలను డీరియలైజ్ చేసే విధానం వీలైనంత వేగంగా ఉండాలి.
డేటాబేస్ రికార్డ్ (విలువ) యొక్క విలువ భాగంపై ప్రత్యేకించి ఆసక్తిని కలిగి ఉండదు. బైట్ ప్రాతినిధ్యం నుండి ఆబ్జెక్ట్గా మార్చడం అనేది అప్లికేషన్ కోడ్ ద్వారా ఇప్పటికే అవసరమైనప్పుడు మాత్రమే జరుగుతుంది, ఉదాహరణకు, దాన్ని స్క్రీన్పై ప్రదర్శించడానికి. ఇది చాలా అరుదుగా జరుగుతుంది కాబట్టి, ఈ విధానానికి వేగ అవసరాలు అంత క్లిష్టమైనవి కావు మరియు దీని అమలులో మేము సౌలభ్యంపై దృష్టి సారించడానికి చాలా స్వేచ్ఛగా ఉన్నాము ఉదాహరణకు, ఇంకా డౌన్లోడ్ చేయని ఫైల్ల గురించి మెటాడేటాను సీరియల్ చేయడానికి, మేము ఉపయోగిస్తాము NSKeyedArchiver.
అయినప్పటికీ, పనితీరు ఇప్పటికీ ముఖ్యమైన సందర్భాలు ఉన్నాయి. ఉదాహరణకు, వినియోగదారు క్లౌడ్ యొక్క ఫైల్ నిర్మాణం గురించి మెటైన్ఫర్మేషన్ను సేవ్ చేస్తున్నప్పుడు, మేము ఆబ్జెక్ట్ల యొక్క అదే మెమరీ డంప్ని ఉపయోగిస్తాము. వాటి యొక్క క్రమబద్ధమైన ప్రాతినిధ్యాన్ని రూపొందించే పని యొక్క ముఖ్యాంశం ఏమిటంటే, డైరెక్టరీ యొక్క మూలకాలు తరగతుల సోపానక్రమం ద్వారా రూపొందించబడ్డాయి.
సి భాషలో దీన్ని అమలు చేయడానికి, వారసుల నిర్దిష్ట ఫీల్డ్లు ప్రత్యేక నిర్మాణాలలో ఉంచబడతాయి మరియు బేస్ వన్తో వారి కనెక్షన్ టైప్ యూనియన్ ఫీల్డ్ ద్వారా పేర్కొనబడుతుంది. యూనియన్ యొక్క వాస్తవ విషయాలు సాంకేతిక లక్షణం రకం ద్వారా పేర్కొనబడ్డాయి.
సీరియలైజ్ చేయబడిన కీ మరియు విలువను స్టోర్కు జోడించవచ్చు. దీన్ని చేయడానికి, ఫంక్షన్ ఉపయోగించండి mdb_put.
// key и value имеют тип MDB_val
mdb_put(..., &key, &value, MDB_NOOVERWRITE);
కాన్ఫిగరేషన్ దశలో, ఒకే కీతో బహుళ రికార్డ్లను నిల్వ చేయకుండా నిల్వ అనుమతించబడుతుంది లేదా నిషేధించబడుతుంది. కీల నకిలీ నిషేధించబడితే, రికార్డ్ను చొప్పించేటప్పుడు, ఇప్పటికే ఉన్న రికార్డ్ను నవీకరించడం అనుమతించబడుతుందో లేదో మీరు నిర్ణయించవచ్చు. కోడ్లోని లోపం వల్ల మాత్రమే ఫ్రేయింగ్ జరిగితే, మీరు జెండాను పేర్కొనడం ద్వారా దాని నుండి మిమ్మల్ని మీరు రక్షించుకోవచ్చు NOOVERWRITE.
ఎంట్రీలను చదవడం
LMDBలో రికార్డులను చదవడానికి, ఫంక్షన్ని ఉపయోగించండి mdb_get. కీ-విలువ జత గతంలో డంప్ చేయబడిన నిర్మాణాల ద్వారా సూచించబడితే, ఈ విధానం ఇలా కనిపిస్తుంది.
సమర్పించబడిన జాబితా స్ట్రక్చర్ డంప్ ద్వారా సీరియలైజేషన్ మిమ్మల్ని వ్రాసేటప్పుడు మాత్రమే కాకుండా డేటాను చదివేటప్పుడు కూడా డైనమిక్ కేటాయింపులను వదిలించుకోవడానికి ఎలా అనుమతిస్తుంది అని చూపిస్తుంది. ఫంక్షన్ నుండి ఉద్భవించింది mdb_get పాయింటర్ ఖచ్చితంగా వర్చువల్ మెమరీ చిరునామాను చూస్తుంది, ఇక్కడ డేటాబేస్ ఆబ్జెక్ట్ యొక్క బైట్ ప్రాతినిధ్యాన్ని నిల్వ చేస్తుంది. వాస్తవానికి, మేము చాలా ఎక్కువ డేటా రీడింగ్ వేగాన్ని దాదాపు ఉచితంగా అందించే ఒక రకమైన ORMని పొందుతాము. విధానం యొక్క అన్ని అందం ఉన్నప్పటికీ, దానితో అనుబంధించబడిన అనేక లక్షణాలను గుర్తుంచుకోవడం అవసరం.
చదవడానికి మాత్రమే లావాదేవీ కోసం, విలువ ఆకృతికి సంబంధించిన పాయింటర్ లావాదేవీ మూసివేయబడే వరకు మాత్రమే చెల్లుబాటులో ఉంటుందని హామీ ఇవ్వబడుతుంది. ముందుగా గుర్తించినట్లుగా, ఒక వస్తువు ఉన్న B-ట్రీ పేజీలు, కాపీ-ఆన్-రైట్ సూత్రానికి ధన్యవాదాలు, అవి కనీసం ఒక లావాదేవీ ద్వారా సూచించబడినంత వరకు మారవు. అదే సమయంలో, వాటితో అనుబంధించబడిన చివరి లావాదేవీ పూర్తయిన వెంటనే, కొత్త డేటా కోసం పేజీలను మళ్లీ ఉపయోగించుకోవచ్చు. వస్తువులు వాటిని రూపొందించిన లావాదేవీని మనుగడ సాగించడానికి అవసరమైతే, వాటిని ఇప్పటికీ కాపీ చేయవలసి ఉంటుంది.
రీడ్రైట్ లావాదేవీ కోసం, ఫలిత విలువ ఆకృతికి సంబంధించిన పాయింటర్ మొదటి సవరణ ప్రక్రియ (డేటా రాయడం లేదా తొలగించడం) వరకు మాత్రమే చెల్లుబాటు అవుతుంది.
నిర్మాణం అయినప్పటికీ NodeValue పూర్తి స్థాయి కాదు, కానీ కత్తిరించబడింది ("బాహ్య కంపారిటర్ని ఉపయోగించి కీలను ఆర్డర్ చేయడం" అనే ఉపవిభాగం చూడండి), మీరు పాయింటర్ ద్వారా దాని ఫీల్డ్లను సురక్షితంగా యాక్సెస్ చేయవచ్చు. ప్రధాన విషయం ఏమిటంటే దానిని నిర్లక్ష్యం చేయడం కాదు!
ఎటువంటి పరిస్థితుల్లోనూ స్వీకరించిన పాయింటర్ ద్వారా నిర్మాణాన్ని సవరించకూడదు. అన్ని మార్పులు పద్ధతి ద్వారా మాత్రమే చేయాలి mdb_put. అయితే, ఈ నిర్మాణం ఉన్న మెమరీ ప్రాంతం రీడ్ఓన్లీ మోడ్లో మ్యాప్ చేయబడినందున మీరు దీన్ని ఎంత కష్టతరం చేయాలనుకున్నా, అది సాధ్యం కాదు.
ఫంక్షన్ని ఉపయోగించి గరిష్ట నిల్వ పరిమాణాన్ని పెంచడం కోసం ఫైల్ను ప్రాసెస్ అడ్రస్ స్పేస్కి రీమాప్ చేయండి 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లో మీరు అదే ప్రభావాన్ని కలిగి ఉండవచ్చు సాధించడానికి మరియు ప్యాక్ చేయబడిన లక్షణాన్ని ఉపయోగించడం. నిర్మాణం ద్వారా ఆక్రమించబడిన స్థలాన్ని ఆప్టిమైజ్ చేయడానికి కూడా ఇది సహాయపడుతుందని పరిగణనలోకి తీసుకుంటే, ఈ పద్ధతి నాకు ప్రాధాన్యతనిస్తుంది, అయినప్పటికీ приводит డేటా యాక్సెస్ కార్యకలాపాల ఖర్చు పెరుగుదలకు.
రికార్డుల సమూహాన్ని మళ్ళించడానికి, LMDB కర్సర్ సంగ్రహాన్ని అందిస్తుంది. మనకు ఇప్పటికే తెలిసిన వినియోగదారు క్లౌడ్ మెటాడేటాతో పట్టిక యొక్క ఉదాహరణను ఉపయోగించి దానితో ఎలా పని చేయాలో చూద్దాం.
డైరెక్టరీలో ఫైల్ల జాబితాను ప్రదర్శించడంలో భాగంగా, దాని చైల్డ్ ఫైల్లు మరియు ఫోల్డర్లు అనుబంధించబడిన అన్ని కీలను కనుగొనడం అవసరం. మునుపటి ఉపవిభాగాలలో మేము కీలను క్రమబద్ధీకరించాము NodeKey అవి ప్రాథమికంగా పేరెంట్ డైరెక్టరీ ID ద్వారా ఆర్డర్ చేయబడినవి. అందువల్ల, సాంకేతికంగా, ఫోల్డర్లోని కంటెంట్లను తిరిగి పొందే పని, ఇచ్చిన ఉపసర్గతో కీల సమూహం యొక్క ఎగువ సరిహద్దులో కర్సర్ను ఉంచడం మరియు దిగువ సరిహద్దుకు మళ్ళించడం వరకు వస్తుంది.
సీక్వెన్షియల్ శోధన ద్వారా ఎగువ సరిహద్దును నేరుగా కనుగొనవచ్చు. దీన్ని చేయడానికి, కర్సర్ డేటాబేస్లోని మొత్తం కీల జాబితా ప్రారంభంలో ఉంచబడుతుంది మరియు దాని క్రింద పేరెంట్ డైరెక్టరీ యొక్క ఐడెంటిఫైయర్తో కూడిన కీ కనిపించే వరకు మరింత పెంచబడుతుంది. ఈ విధానం 2 స్పష్టమైన ప్రతికూలతలను కలిగి ఉంది:
సరళ శోధన సంక్లిష్టత, అయినప్పటికీ, సాధారణంగా చెట్లలో మరియు ప్రత్యేకించి B-ట్రీలో ఇది లాగరిథమిక్ సమయంలో నిర్వహించబడుతుంది.
ఫలించలేదు, కోరిన పేజీకి ముందు ఉన్న అన్ని పేజీలు ఫైల్ నుండి ప్రధాన మెమరీకి ఎత్తివేయబడతాయి, ఇది చాలా ఖరీదైనది.
అదృష్టవశాత్తూ, LMDB API కర్సర్ను ప్రారంభంలో ఉంచడానికి సమర్థవంతమైన మార్గాన్ని అందిస్తుంది. దీన్ని చేయడానికి, మీరు విరామం ఎగువ సరిహద్దులో ఉన్న కీ కంటే స్పష్టంగా తక్కువగా లేదా సమానంగా ఉండే కీని రూపొందించాలి. ఉదాహరణకు, పై చిత్రంలో ఉన్న జాబితాకు సంబంధించి, మేము ఫీల్డ్లో ఒక కీని తయారు చేయవచ్చు parentId 2కి సమానంగా ఉంటుంది మరియు మిగిలినవన్నీ సున్నాలతో నిండి ఉంటాయి. అటువంటి పాక్షికంగా నింపబడిన కీ ఫంక్షన్ ఇన్పుట్కు సరఫరా చేయబడుతుంది mdb_cursor_get ఆపరేషన్ సూచిస్తుంది MDB_SET_RANGE.
కీల సమూహం యొక్క ఎగువ సరిహద్దు కనుగొనబడితే, మనం కలిసే వరకు లేదా కీ మరొకదానిని కలిసే వరకు మేము దానిపై పునరావృతం చేస్తాము parentId, లేదా కీలు అస్సలు అయిపోవు.
do {
rc = mdb_cursor_get(cursor, &key, &value, MDB_NEXT);
// processing...
} while (MDB_NOTFOUND != rc && // check end of table
IsTargetKey(key)); // check end of keys group
మంచి విషయం ఏమిటంటే, mdb_cursor_get ఉపయోగించి పునరావృతంలో భాగంగా, మేము కీని మాత్రమే కాకుండా విలువను కూడా పొందుతాము. ఒకవేళ, నమూనా షరతులను నెరవేర్చడానికి, మీరు ఇతర విషయాలతోపాటు, రికార్డ్లోని విలువ భాగం నుండి ఫీల్డ్లను తనిఖీ చేయాల్సి ఉంటే, అదనపు సంజ్ఞలు లేకుండా అవి చాలా అందుబాటులో ఉంటాయి.
4.3 పట్టికల మధ్య మోడలింగ్ సంబంధాలు
ఇప్పటికి, మేము ఒకే టేబుల్ డేటాబేస్ రూపకల్పన మరియు పని యొక్క అన్ని అంశాలను పరిగణనలోకి తీసుకోగలిగాము. ఒకే రకమైన కీ-విలువ జతలతో కూడిన క్రమబద్ధీకరించబడిన రికార్డుల సమితిని టేబుల్ అని చెప్పవచ్చు. మీరు ఒక కీని దీర్ఘచతురస్రం వలె మరియు అనుబంధిత విలువను సమాంతర పైప్గా ప్రదర్శిస్తే, మీరు డేటాబేస్ యొక్క దృశ్యమాన రేఖాచిత్రాన్ని పొందుతారు.
అయినప్పటికీ, నిజ జీవితంలో చాలా తక్కువ రక్తపాతంతో పొందడం చాలా అరుదుగా సాధ్యమవుతుంది. తరచుగా డేటాబేస్లో, మొదట, అనేక పట్టికలను కలిగి ఉండటం మరియు రెండవది, ప్రాథమిక కీకి భిన్నమైన క్రమంలో వాటిలో ఎంపికలు చేయడం అవసరం. ఈ చివరి విభాగం వారి సృష్టి మరియు పరస్పర అనుసంధాన సమస్యలకు అంకితం చేయబడింది.
సూచిక పట్టికలు
క్లౌడ్ అప్లికేషన్లో "గ్యాలరీ" విభాగం ఉంది. ఇది తేదీ ప్రకారం క్రమబద్ధీకరించబడిన మొత్తం క్లౌడ్ నుండి మీడియా కంటెంట్ను ప్రదర్శిస్తుంది. అటువంటి ఎంపికను ఉత్తమంగా అమలు చేయడానికి, ప్రధాన పట్టిక పక్కన మీరు కొత్త రకం కీలతో మరొకదాన్ని సృష్టించాలి. అవి ఫైల్ సృష్టించబడిన తేదీతో ఫీల్డ్ను కలిగి ఉంటాయి, ఇది ప్రాథమిక క్రమబద్ధీకరణ ప్రమాణంగా పని చేస్తుంది. కొత్త కీలు ప్రధాన పట్టికలోని కీల వలె అదే డేటాను సూచిస్తాయి కాబట్టి, వాటిని ఇండెక్స్ కీలు అంటారు. దిగువ చిత్రంలో అవి నారింజ రంగులో హైలైట్ చేయబడ్డాయి.
ఒకే డేటాబేస్లో వివిధ టేబుల్ల కీలను ఒకదానికొకటి వేరు చేయడానికి, వాటన్నింటికీ అదనపు సాంకేతిక ఫీల్డ్ టేబుల్ఐడి జోడించబడింది. క్రమబద్ధీకరించడానికి దీన్ని అత్యధిక ప్రాధాన్యతగా చేయడం ద్వారా, మేము ముందుగా పట్టికల వారీగా మరియు పట్టికలలోనే - మా స్వంత నిబంధనల ప్రకారం కీల సమూహాన్ని సాధిస్తాము.
ఇండెక్స్ కీ ప్రాథమిక కీ వలె అదే డేటాను సూచిస్తుంది. ప్రాథమిక కీ యొక్క విలువ భాగం యొక్క కాపీని దానితో అనుబంధించడం ద్వారా ఈ ఆస్తిని సూటిగా అమలు చేయడం అనేక దృక్కోణాల నుండి సరైనది కాదు:
తీసుకున్న స్థలం పరంగా, మెటాడేటా చాలా గొప్పగా ఉంటుంది.
పనితీరు దృక్కోణం నుండి, నోడ్ యొక్క మెటాడేటాను నవీకరించేటప్పుడు, మీరు దానిని రెండు కీలను ఉపయోగించి తిరిగి వ్రాయవలసి ఉంటుంది.
కోడ్ మద్దతు యొక్క కోణం నుండి, మేము కీలలో ఒకదానికి డేటాను నవీకరించడం మర్చిపోతే, నిల్వలో డేటా అస్థిరత యొక్క అంతుచిక్కని బగ్ని మేము పొందుతాము.
తరువాత, ఈ లోపాలను ఎలా తొలగించాలో మేము పరిశీలిస్తాము.
పట్టికల మధ్య సంబంధాలను నిర్వహించడం
సూచిక పట్టికను ప్రధాన పట్టికతో లింక్ చేయడానికి నమూనా బాగా సరిపోతుంది "కీలు విలువగా". దాని పేరు సూచించినట్లుగా, సూచిక రికార్డు యొక్క విలువ భాగం ప్రాథమిక కీ విలువ యొక్క కాపీ. ఈ విధానం ప్రాథమిక రికార్డు యొక్క విలువ భాగం యొక్క కాపీని నిల్వ చేయడంతో అనుబంధించబడిన పైన పేర్కొన్న అన్ని ప్రతికూలతలను తొలగిస్తుంది. ఇండెక్స్ కీ ద్వారా విలువను పొందాలంటే, మీరు డేటాబేస్లో ఒకదానికి బదులుగా 2 ప్రశ్నలు వేయాలి. క్రమపద్ధతిలో, ఫలితంగా డేటాబేస్ స్కీమా ఇలా కనిపిస్తుంది.
పట్టికల మధ్య సంబంధాలను నిర్వహించడానికి మరొక నమూనా "నిరుపయోగ కీ". కీకి అదనపు లక్షణాలను జోడించడం దీని సారాంశం, ఇది క్రమబద్ధీకరించడానికి కాదు, అనుబంధిత కీని పునఃసృష్టించడానికి అవసరం. Mail.ru క్లౌడ్ అప్లికేషన్లో దాని ఉపయోగం యొక్క నిజమైన ఉదాహరణలు ఉన్నాయి, అయితే, లోతైన డైవ్ను నివారించడానికి నిర్దిష్ట iOS ఫ్రేమ్వర్క్ల సందర్భం, నేను ఒక కల్పిత, కానీ స్పష్టమైన ఉదాహరణ ఇస్తాను
క్లౌడ్ మొబైల్ క్లయింట్లు వినియోగదారు ఇతర వ్యక్తులతో భాగస్వామ్యం చేసిన అన్ని ఫైల్లు మరియు ఫోల్డర్లను ప్రదర్శించే పేజీని కలిగి ఉంటాయి. సాపేక్షంగా చాలా తక్కువ ఫైల్లు ఉన్నాయి మరియు వాటితో అనుబంధించబడిన పబ్లిసిటీ గురించి అనేక రకాల నిర్దిష్ట సమాచారం (ఎవరికి యాక్సెస్ మంజూరు చేయబడింది, ఏ హక్కులతో మొదలైనవి) ఉన్నందున, విలువ భాగాన్ని భారం చేయడం హేతుబద్ధమైనది కాదు. దానితో ప్రధాన పట్టికలో రికార్డ్ చేయండి. అయితే, మీరు అటువంటి ఫైల్లను ఆఫ్లైన్లో ప్రదర్శించాలనుకుంటే, మీరు దానిని ఇప్పటికీ ఎక్కడో నిల్వ చేయాలి. దాని కోసం ప్రత్యేక పట్టికను రూపొందించడం సహజ పరిష్కారం. దిగువ రేఖాచిత్రంలో, దాని కీ "P"తో ప్రిఫిక్స్ చేయబడింది మరియు ప్లేస్హోల్డర్ "ప్రాప్నేమ్" మరింత నిర్దిష్ట విలువ "పబ్లిక్ సమాచారం"తో భర్తీ చేయబడుతుంది.
కొత్త పట్టిక సృష్టించబడిన నిల్వ కోసం అన్ని ప్రత్యేకమైన మెటాడేటా రికార్డ్ యొక్క విలువ భాగంలో ఉంచబడుతుంది. అదే సమయంలో, మీరు ఇప్పటికే ప్రధాన పట్టికలో నిల్వ చేయబడిన ఫైల్లు మరియు ఫోల్డర్ల గురించిన డేటాను నకిలీ చేయకూడదు. బదులుగా, "నోడ్ ID" మరియు "టైమ్స్టాంప్" ఫీల్డ్ల రూపంలో "P" కీకి అనవసరమైన డేటా జోడించబడుతుంది. వారికి ధన్యవాదాలు, మీరు ఇండెక్స్ కీని నిర్మించవచ్చు, దాని నుండి మీరు ప్రాథమిక కీని పొందవచ్చు, దాని నుండి చివరకు, మీరు నోడ్ మెటాడేటాను పొందవచ్చు.
తీర్మానం
మేము LMDB అమలు ఫలితాలను సానుకూలంగా అంచనా వేస్తాము. దాని తరువాత, అప్లికేషన్ ఫ్రీజ్ల సంఖ్య 30% తగ్గింది.
చేసిన పని ఫలితాలు iOS బృందానికి మించి ప్రతిధ్వనించాయి. ప్రస్తుతం, ఆండ్రాయిడ్ అప్లికేషన్లోని ప్రధాన "ఫైల్స్" విభాగాలలో ఒకటి కూడా LMDBని ఉపయోగించేందుకు మార్చబడింది మరియు ఇతర భాగాలు కూడా అందుబాటులో ఉన్నాయి. కీ-విలువ స్టోర్ అమలు చేయబడిన C భాష, C++లో క్రాస్-ప్లాట్ఫారమ్ చుట్టూ అప్లికేషన్ ఫ్రేమ్వర్క్ను రూపొందించడానికి ప్రారంభంలో బాగా సహాయపడింది. ఆబ్జెక్టివ్-C మరియు కోట్లిన్లోని ప్లాట్ఫారమ్ కోడ్తో ఫలిత C++ లైబ్రరీని సజావుగా కనెక్ట్ చేయడానికి కోడ్ జనరేటర్ ఉపయోగించబడింది. జిన్ని డ్రాప్బాక్స్ నుండి, కానీ అది పూర్తిగా భిన్నమైన కథ.