Равшанӣ ва камбизоатии пойгоҳи додаҳои калидӣ-арзиши LMDB дар замимаҳои iOS

Равшанӣ ва камбизоатии пойгоҳи додаҳои калидӣ-арзиши LMDB дар замимаҳои iOS

Тирамоҳи соли 2019 дар дастаи Mail.ru Cloud iOS як воқеаи деринтизор рӯй дод. Пойгоҳи асосӣ барои нигоҳдории доимии ҳолати барномаҳо барои ҷаҳони мобилӣ хеле экзотикӣ шудааст Пойгоҳи додаҳои хотираи Lightning (LMDB). Дар доираи буриш, диққати шумо ба баррасии муфассали он дар чор қисм даъват карда мешавад. Аввалан, биёед дар бораи сабабҳои чунин интихоби ғайриоддӣ ва душвор сӯҳбат кунем. Пас биёед ба баррасии се наҳанг дар маркази меъмории LMDB гузарем: файлҳои харитаи хотира, дарахти B +, равиши нусхабардорӣ дар навиштан барои татбиқи транзаксия ва мултипликатсия. Ниҳоят, барои шириниҳо - қисми амалӣ. Дар он мо дида мебароем, ки чӣ гуна тарҳрезӣ ва татбиқи схемаи асосиро бо якчанд ҷадвалҳо, аз ҷумла як индекс, дар болои API-и сатҳи пасти арзиши калидӣ дида мебароем.

Мундариҷа

  1. Ҳавасмандгардонии амалӣ
  2. Ҷойгиркунии LMDB
  3. Се наҳанг LMDB
    3.1. Наҳанг №1. Файлҳои харитаи хотира
    3.2. Наҳанг №2. B+-дарахт
    3.3. Наҳанг №3. нусхабардорӣ ба навиштан
  4. Тарҳрезии схемаи маълумот дар болои API-и арзиши калидӣ
    4.1. Абстраксияҳои асосӣ
    4.2. Моделсозии ҷадвал
    4.3. Моделсозии муносибатҳои байни ҷадвалҳо

1. Ҳавасмандгардонии амалӣ

Дар як сол як маротиба, дар соли 2015, мо ғамхорӣ мекардем, ки як метрика, ки интерфейси замимаи мо то чӣ андоза ақиб мемонад. Мо ин корро на танҳо кардем. Мо дар бораи он, ки баъзан барнома ҷавоб додан ба амалҳои корбарро қатъ мекунад: тугмаҳо пахш карда намешаванд, рӯйхатҳо ҳаракат намекунанд ва ғ. Дар бораи механикаи ченкунй гуфт дар AvitoTech, бинобар ин ман танҳо тартиби рақамҳоро медиҳам.

Равшанӣ ва камбизоатии пойгоҳи додаҳои калидӣ-арзиши LMDB дар замимаҳои iOS

Натичаи ченкунй барои мо души хунук гардид. Маълум шуд, ки мушкилиҳое, ки дар натиҷаи яхбандӣ ба вуҷуд меоянд, аз ҳама чизи дигар хеле зиёданд. Агар пеш аз фахмидани ин факт, нишондихандаи асосии техникии сифат рафъ бошад, пас пас аз фокус иваз кард дар яхдон озод.

Сохтмон панели асбобҳо бо яхбандӣ ва сарф карда миқдорӣ и сифат Таҳлили сабабҳои онҳо, душмани асосӣ маълум шуд - мантиқи вазнини тиҷоратӣ, ки дар риштаи асосии барнома иҷро мешавад. Вокуниши табиӣ ба ин нангин як хоҳиши сӯзон барои ба ҷараёнҳои корӣ андохтани он буд. Барои ҳалли муназзами ин мушкилот, мо ба меъмории бисёрсоҳавӣ, ки ба актёрҳои сабук асос ёфтааст, муроҷиат кардем. Ман мутобиқсозии ӯро барои ҷаҳони iOS бахшидам ду ришта дар твиттери коллективй ва мақола дар бораи Habre. Ҳамчун як қисми ҳикояи ҷорӣ, ман мехоҳам он ҷанбаҳои қарорро, ки ба интихоби пойгоҳи додаҳо таъсир расониданд, таъкид намоям.

Модели актёрии ташкили система тахмин мекунад, ки бисёрсоҳавӣ моҳияти дуюми он мегардад. Объектҳои модели дар он убур кардани сарҳадҳои риштаро дӯст медоранд. Ва ин корро на баъзан ва дар баъзе чойхо, балки кариб доимо ва дар хама чо мекунанд.

Равшанӣ ва камбизоатии пойгоҳи додаҳои калидӣ-арзиши LMDB дар замимаҳои iOS

Пойгоҳи додаҳо яке аз ҷузъҳои асосии диаграммаи пешниҳодшуда мебошад. Вазифаи асосии он татбиқи намунаи макро мебошад Пойгоҳи додаҳои муштарак. Агар дар ҷаҳони корхона он барои ташкили ҳамоҳангсозии додаҳо байни хидматҳо истифода шавад, пас дар мавриди меъмории актёр маълумот байни риштаҳо. Ҳамин тариқ, ба мо чунин базае лозим буд, ки кор бо он дар муҳити бисёрсоҳавӣ ҳатто душвориҳои камтаринро ба вуҷуд намеорад. Аз ҷумла, ин маънои онро дорад, ки объектҳои аз он гирифташуда бояд ҳадди аққал аз ришта бехатар бошанд ва идеалӣ тамоман тағирёбанда нестанд. Тавре ки шумо медонед, охирин метавонад дар як вақт аз якчанд риштаҳо бидуни муроҷиат ба ҳама гуна қулфҳо истифода шавад, ки ба иҷроиш таъсири судманд мерасонад.

Равшанӣ ва камбизоатии пойгоҳи додаҳои калидӣ-арзиши LMDB дар замимаҳои iOSОмили дуввуми муҳиме, ки ба интихоби пойгоҳи додаҳо таъсир расонд, API абрии мо буд. Он аз равиши git ба синхронизатсия илҳом гирифта шудааст. Монанди ӯ мо ҳадаф доштем офлайн аввалин API, ки барои муштариёни абрӣ бештар мувофиқ аст. Тахмин карда мешуд, ки онҳо танҳо як маротиба ҳолати пурраи абрро хориҷ мекунанд ва сипас ҳамоҳангсозӣ дар аксари ҳолатҳо тавассути тағирот ба амал меояд. Афсӯс, ки ин имкон танҳо дар минтақаи назариявӣ мавҷуд аст ва дар амал муштариён чӣ гуна кор карданро бо часпакҳо ёд нагирифтаанд. Ин як катор сабабхои объективй дорад, ки мо барои кашол надодан ба чорй намудани он аз кавс берун мемонем. Акнун хеле ҷолибтар натиҷаҳои дарс дар бораи он чӣ рӯй медиҳад, вақте ки API "A" гуфт ва истеъмолкунандаи он "B" нагуфт.

Ҳамин тавр, агар шумо git-ро тасаввур кунед, ки ҳангоми иҷрои фармони кашидан, ба ҷои татбиқи часпакҳо ба акси маҳаллӣ, ҳолати пурраи онро бо сервери пурра муқоиса мекунад, пас шумо дар бораи синхронизатсия тасаввуроти дақиқ хоҳед дошт. дар мизоҷони абрӣ рух медиҳад. Тахмин кардан осон аст, ки барои татбиқи он ду дарахти DOM-ро дар хотира бо мета-маълумот дар бораи ҳама сервер ва файлҳои маҳаллӣ ҷудо кардан лозим аст. Маълум мешавад, ки агар корбар 500 ҳазор файлро дар абр нигоҳ дорад, пас барои ҳамоҳангсозии он ду дарахти дорои 1 миллион гиреҳро аз нав сохтан ва нест кардан лозим аст. Аммо ҳар як гиреҳ маҷмӯи дорои графики зеробъектҳо мебошад. Дар ин замина, натиҷаҳои профилсозӣ интизор буданд. Маълум шуд, ки ҳатто бидуни ба назар гирифтани алгоритми муттаҳидшавӣ, худи тартиби эҷод ва сипас нобуд кардани миқдори зиёди объектҳои хурд як тини зеборо талаб мекунад.. Вазъият аз он сабаб бадтар мешавад, ки амалиёти асосии синхронизатсия ба миқдори зиёд дохил карда шудааст. аз скриптҳои корбар. Дар натиҷа, мо меъёри дуюми муҳимро ҳангоми интихоби пойгоҳи додаҳо муайян мекунем - қобилияти амалӣ кардани амалиёти CRUD бидуни тақсимоти динамикии объектҳо.

Талаботи дигар анъанавӣ буда, рӯйхати пурраи онҳо чунин аст.

  1. Бехатарии ришта.
  2. Коркарди бисёрҷониба. Бо хоҳиши истифодаи як мисоли пойгоҳи додаҳо барои ҳамоҳангсозии ҳолат на танҳо байни риштаҳо, балки байни замимаи асосӣ ва васеъшавии iOS.
  3. Имконияти муаррифии объектҳои захирашуда ҳамчун объектҳои ғайримуқаррарӣ
  4. Набудани тақсимоти динамикӣ дар амалиёти CRUD.
  5. Дастгирии транзаксия барои хосиятҳои асосӣ КислотаКалидвожаҳо: атомӣ, пайвастагӣ, ҷудошавӣ ва эътимоднокӣ.
  6. Суръат дар ҳолатҳои маъмултарин.

Бо ин маҷмӯи талабот, SQLite интихоби хуб буд ва ҳоло ҳам аст. Бо вуҷуди ин, дар доираи омӯзиши алтернативаҳо, ман китоберо пайдо кардам "Оғози кор бо LevelDB". Таҳти роҳбарии ӯ, меъёре навишта шудааст, ки суръати корро бо пойгоҳи додаҳои гуногун дар сенарияҳои воқеии абр муқоиса мекунад. Натиҷа аз интизориҳои ваҳшӣ зиёдтар буд. Дар ҳолатҳои маъмултарин - гирифтани курсор дар рӯйхати мураттабшудаи ҳамаи файлҳо ва рӯйхати мураттабшудаи ҳамаи файлҳо барои директорияи додашуда - LMDB нисбат ба SQLite 10 маротиба тезтар шуд. Интихоб маълум шуд.

Равшанӣ ва камбизоатии пойгоҳи додаҳои калидӣ-арзиши LMDB дар замимаҳои iOS

2. Ҷойгиркунии LMDB

LMDB китобхонаи хеле хурд (танҳо 10К сатр) мебошад, ки қабати пасттарини пойгоҳи додаҳо - анборро амалӣ мекунад.

Равшанӣ ва камбизоатии пойгоҳи додаҳои калидӣ-арзиши LMDB дар замимаҳои iOS

Диаграммаи дар боло зикршуда нишон медиҳад, ки муқоисаи LMDB бо SQLite, ки сатҳҳои боз ҳам баландтарро амалӣ мекунад, одатан нисбат ба SQLite бо Data Core дурусттар нест. Иқтибос овардан аз як муҳаррикҳои нигоҳдорӣ ҳамчун рақибони баробар - BerkeleyDB, LevelDB, Sophia, RocksDB ва ғайра одилонатар мебуд. Ҳатто пешрафтҳое ҳастанд, ки LMDB ҳамчун ҷузъи муҳаррики нигоҳдорӣ барои SQLite амал мекунад. Аввалин чунин таҷриба дар соли 2012 сарф карданд муаллиф LMDB Ховард Чу. натиҷаҳои чунон чолиби диккат гардид, ки ташаббуси уро дустдорони ОССС ба даст гирифта, идомаи худро дар назди LumoSQL. Дар моҳи январи соли 2020 муаллифи ин лоиҳа Ден Ширер мебошад муаррифӣ намуд он дар LinuxConfAu.

Истифодаи асосии LMDB ҳамчун муҳаррик барои пойгоҳи додаҳои барномаҳо мебошад. Китобхона аз намуди зоҳирии худ аз таҳиягарон қарздор аст OpenLDAP, ки аз BerkeleyDB ҳамчун асоси лоиҳаи худ сахт норозӣ буданд. Аз китобхонаи хоксор дур шудан бтре, Ховард Чу муяссар гардид, ки яке аз альтернативахои машхуртарини замони моро ба вучуд оварад. Вай гузориши хеле ҷолиби худро ба ин ҳикоя ва инчунин ба сохтори дохилии LMDB бахшид. "Базаи махзани хотираи Lightning". Леонид Юрьев (ака йлео) аз Positive Technologies дар суханронии худ дар Highload 2015 "Муҳаррики LMDB қаҳрамони махсус аст". Дар он, ӯ дар бораи LMDB дар заминаи як вазифаи шабеҳи татбиқи ReOpenLDAP сӯҳбат мекунад ва LevelDB аллакай мавриди интиқоди муқоисавӣ қарор гирифтааст. Дар натиҷаи татбиқ, Positive Technologies ҳатто як штангаи фаъолона инкишофёфтаро ба даст овард MDBX бо хусусиятҳои хеле болаззат, оптимизатсия ва ислоҳи хатогиҳо.

LMDB аксар вақт ҳамчун нигаҳдорӣ истифода мешавад. Масалан, браузери Mozilla Firefox интихоб кард он барои як қатор ниёзҳо ва аз версияи 9, Xcode афзалият дода мешавад SQLite он барои нигоҳ доштани индексатсия.

Муҳаррик инчунин дар ҷаҳони рушди мобилӣ ҷалб карда шуд. Осори истифодаи он метавонад бошад ёфтед дар муштарии iOS барои Telegram. LinkedIn як қадам пеш рафт ва LMDB-ро ҳамчун нигаҳдории пешфарз барои чаҳорчӯбаи кэшкунии маълумотҳои худ, Rocket Data интихоб кард, ки дар бораи он гуфт дар як мақола дар соли 2016.

LMDB барои ҷой дар офтоб дар чароғе, ки BerkeleyDB пас аз гузариш таҳти назорати Oracle гузоштааст, бомуваффақият мубориза мебарад. Китобхонаро барои суръат ва эътимоднокии худ, ҳатто дар муқоиса бо навъи худ дӯст медоранд. Тавре ки шумо медонед, хӯроки нисфирӯзии ройгон вуҷуд надорад ва ман мехостам қайд намоям, ки шумо ҳангоми интихоби LMDB ва SQLite бо он дучор мешавед. Диаграммаи боло равшан нишон медиҳад, ки суръати афзоиш чӣ гуна ба даст оварда мешавад. Аввалан, мо барои қабатҳои иловагии абстраксия дар болои нигаҳдории диск пардохт намекунем. Албатта, дар меъмории хуб, шумо то ҳол бе онҳо кор карда наметавонед ва онҳо ногузир дар коди барнома пайдо мешаванд, аммо онҳо хеле лоғартар хоҳанд шуд. Онҳо хусусиятҳое надоранд, ки аз ҷониби як барномаи мушаххас талаб карда намешаванд, масалан, дастгирии дархостҳо дар забони SQL. Дуюм, имкон медиҳад, ки харитасозии амалиёти барномаҳо ба дархостҳо ба нигаҳдории диск ба таври оптималӣ амалӣ карда шавад. Агар SQLite дар кори ман Аз эҳтиёҷоти миёнаи як барномаи миёна бармеояд, пас шумо ҳамчун як таҳиягари барнома аз сенарияҳои асосии сарборӣ хуб медонед. Барои ҳалли самараноктар, шумо бояд ҳам барои таҳияи ҳалли ибтидоӣ ва ҳам дастгирии минбаъдаи он нархи баланд пардохт кунед.

3. Се наҳанг LMDB

Пас аз дидани LMDB аз нуқтаи назари парранда, вақти амиқтар рафтан аст. Се фасли оянда ба таҳлили китҳои асосӣ, ки меъмории нигаҳдорӣ ба он такя мекунад, бахшида мешавад:

  1. Файлҳои харитаи хотира ҳамчун механизми кор бо диск ва ҳамоҳангсозии сохторҳои дохилии додаҳо.
  2. B+-tree ҳамчун ташкилоти сохтори додаҳои захирашуда.
  3. Copy-on-write ҳамчун равиш барои таъмини хосиятҳои транзаксионии ACID ва мултипликатсия.

3.1. Наҳанг №1. Файлҳои харитаи хотира

Файлҳои харитаи хотира чунон унсури муҳими меъморӣ мебошанд, ки онҳо ҳатто дар номи анбор пайдо мешаванд. Масъалаҳои кэшкунӣ ва ҳамоҳангсозии дастрасӣ ба маълумоти захирашуда комилан ба ихтиёри системаи оператсионӣ мебошанд. LMDB дар дохили худ ягон кэш надорад. Ин як қарори бошууронаи муаллиф аст, зеро хондани маълумот бевосита аз файлҳои хариташуда ба шумо имкон медиҳад, ки дар татбиқи муҳаррик гӯшаҳои зиёдеро буред. Дар зер рӯйхати пурраи баъзе аз онҳо дур аст.

  1. Нигоҳ доштани мутобиқати маълумот дар анбор ҳангоми кор бо он аз якчанд равандҳо масъулияти системаи амалиётӣ мегардад. Дар фасли оянда ин механизатор муфассал ва бо расмҳо сухан меравад.
  2. Набудани кэшҳо LMDB-ро аз хароҷоти марбут ба тақсимоти динамикӣ комилан озод мекунад. Хондани маълумот дар амал ин гузоштани нишоннамо ба суроғаи дуруст дар хотираи виртуалӣ аст ва чизи дигар. Мисли фантазия ба назар мерасад, аммо дар манбаи анбор, ҳама зангҳои calloc дар функсияи конфигуратсияи анбор мутамарказ шудаанд.
  3. Набудани кэш инчунин маънои мавҷуд набудани қулфҳои марбут ба синхронизатсияро барои дастрасӣ ба онҳо дорад. Хонандагон, ки шумораи худсарона дар як вақт вуҷуд дошта метавонад, дар роҳи худ ба маълумот бо ягон мутекс дучор намеояд. Аз ин рӯ, суръати хониш аз рӯи шумораи CPUҳо миқёси беҳтарини хаттӣ дорад. Дар LMDB, танҳо амалиёти тағирдиҳӣ ҳамоҳанг карда мешаванд. Дар як вақт танҳо як нависанда буда метавонад.
  4. Ҳадди ақали мантиқи кэш ва ҳамоҳангсозӣ кодро аз як намуди бениҳоят мураккаби хатогиҳое, ки бо кор дар муҳити бисёр ришта алоқаманданд, наҷот медиҳад. Дар конфронси Usenix OSDI 2014 ду омӯзиши ҷолиби пойгоҳи додаҳо вуҷуд доштанд: "Ҳама системаҳои файлӣ баробар сохта нашудаанд: дар бораи мураккабии таҳияи барномаҳои ба таври қатъӣ мувофиқ" и Шиканҷаи пойгоҳи додаҳо барои масхара ва фоида. Аз онҳо шумо метавонед дар бораи ҳам эътимоднокии бесобиқаи LMDB ва ҳам татбиқи қариб бенуқсони хосиятҳои ACID транзаксияҳо, ки аз он дар ҳамон SQLite зиёдтар аст, маълумот гиред.
  5. Минимализми LMDB имкон медиҳад, ки тасвири мошини рамзи он пурра дар кэши L1 протсессори бо хусусиятҳои суръати натиҷавӣ ҷойгир карда шавад.

Мутаассифона, дар iOS, файлҳои харитаи хотира он қадар рангин нестанд, ки мо мехоҳем. Барои ҳарф задан дар бораи камбудиҳои бо онҳо алоқаманд, бояд принсипҳои умумии татбиқи ин механизмро дар системаҳои оператсионӣ ба ёд орем.

Маълумоти умумӣ дар бораи файлҳои харитаи хотира

Равшанӣ ва камбизоатии пойгоҳи додаҳои калидӣ-арзиши LMDB дар замимаҳои iOSБо ҳар як замимаи иҷрошаванда, системаи оператсионӣ объектеро, ки раванд ном дорад, пайваст мекунад. Ҳар як раванд як қатор суроғаҳо ҷудо карда мешавад, ки дар он ҳама чизҳои барои кор заруриро ҷойгир мекунанд. Суроғаҳои пасттарин дорои бахшҳои дорои код ва маълумот ва захираҳои сахт кодшуда мебошанд. Минбаъд блоки боло афзояндаи фазои суроғаи динамикӣ меояд, ки ба мо ҳамчун тӯда маълум аст. Он суроғаҳои объектҳоеро дар бар мегирад, ки дар ҷараёни кори барнома пайдо мешаванд. Дар боло майдони хотираест, ки аз ҷониби стек барнома истифода мешавад. Он ё калон мешавад ё хурд мешавад, ба ибораи дигар, андозаи он низ хусусияти динамикӣ дорад. Барои он ки стек ва теппа ба якдигар тела надиҳанд ва ба ҳамдигар халал нарасонанд, онҳо дар канорҳои гуногуни фазои адрес ҷудо мешаванд.Дар байни ду қисмати динамикӣ дар боло ва поён сӯрох мавҷуд аст. Суроғаҳои ин қисмати миёна аз ҷониби системаи оператсионӣ барои пайвастан бо равандҳои объектҳои гуногун истифода мешаванд. Махсусан, он метавонад маҷмӯи муайяни доимии суроғаҳоро ба файли диск нишон диҳад. Чунин файл файли харитаи хотира номида мешавад

Фазои суроғае, ки ба раванд ҷудо карда шудааст, бузург аст. Аз ҷиҳати назариявӣ, шумораи суроғаҳо танҳо бо андозаи нишондиҳанда маҳдуд карда мешавад, ки аз рӯи умқи битҳои система муайян карда мешавад. Агар хотираи физикӣ ба он 1-дар-1 таъин карда мешуд, он гоҳ раванди аввал тамоми хотираи оперативиро фурӯ мебарад ва ҳеҷ саволе дар бораи бисёркорӣ вуҷуд надорад.

Бо вуҷуди ин, мо аз таҷрибаи худ медонем, ки системаҳои оператсионии муосир метавонанд дар як вақт ҳамон қадар равандҳоро иҷро кунанд, ки шумо мехоҳед. Ин аз он сабаб имконпазир аст, ки онҳо хотираи зиёдеро барои равандҳо танҳо дар рӯи коғаз ҷудо мекунанд, аммо дар асл онҳо ба хотираи асосии физикӣ танҳо ҳамон қисмеро бор мекунанд, ки дар ин ҷо ва ҳоло талаб карда мешавад. Аз ин рӯ, хотираи бо раванд алоқаманд виртуалӣ номида мешавад.

Равшанӣ ва камбизоатии пойгоҳи додаҳои калидӣ-арзиши LMDB дар замимаҳои iOS

Системаи оператсионӣ хотираи виртуалӣ ва физикиро ба саҳифаҳои андозаи муайян ташкил мекунад. Ҳамин ки саҳифаи муайяни хотираи виртуалӣ талаб карда мешавад, системаи оператсионӣ онро ба хотираи физикӣ бор мекунад ва мукотибаи байни онҳоро дар ҷадвали махсус мегузорад. Агар ягон слотҳои ройгон мавҷуд набошад, пас яке аз саҳифаҳои қаблан боршуда ба диск нусхабардорӣ карда мешавад ва саҳифаи дархостшуда ҷои онро мегирад. Ин тартиб, ки мо ба зудӣ ба он бармегардем, свопинг номида мешавад. Дар расми зер раванди тавсифшуда нишон дода шудааст. Дар он саҳифаи А бо суроғаи 0 бор карда шуда, дар саҳифаи хотираи асосӣ бо суроғаи 4 ҷойгир карда шудааст. Ин далел дар ҷадвали мукотибаи ҳуҷайраи рақами 0 инъикос ёфтааст.

Равшанӣ ва камбизоатии пойгоҳи додаҳои калидӣ-арзиши LMDB дар замимаҳои iOS

Бо файлҳои харитаи хотира, ҳикоя комилан якхела аст. Мантиқан, онҳо гӯё пайваста ва пурра дар фазои суроғаи виртуалӣ ҷойгир карда мешаванд. Аммо, онҳо ба хотираи ҷисмонӣ саҳифа ба саҳифа ворид мешаванд ва танҳо тибқи дархост. Тағир додани чунин саҳифаҳо бо файли дар диск буда ҳамоҳанг карда мешавад. Ҳамин тариқ, шумо метавонед файли I/O-ро иҷро кунед, танҳо бо байтҳо дар хотира кор кунед - ҳама тағиротҳо тавассути ядрои системаи оператсионӣ ба таври худкор ба файли аслӣ интиқол дода мешаванд.
"Озодӣ" дар мобил
Тасвири зер нишон медиҳад, ки чӣ тавр LMDB ҳолати худро ҳангоми кор бо пойгоҳи додаҳо аз равандҳои гуногун ҳамоҳанг месозад. Бо харитаи хотираи виртуалии равандҳои гуногун ба як файл, мо амалан системаи пардозандаро вазифадор менамоем, ки блокҳои муайяни фазои суроғаҳои онҳоро бо ҳамдигар ба таври гузаранда ҳамоҳанг созанд, ки LMDB дар он ҷо ба назар мерасад.
"Озодӣ" дар мобил

Равшанӣ ва камбизоатии пойгоҳи додаҳои калидӣ-арзиши LMDB дар замимаҳои iOS

Як нюанси муҳим он аст, ки LMDB файли маълумотро ба таври нобаёнӣ тавассути механизми занги системаи навиштан тағир медиҳад ва худи файл дар ҳолати танҳо барои хондан намоиш дода мешавад. Ин равиш ду таъсири муҳим дорад.

Натиҷаи аввал барои ҳама системаҳои оператсионӣ маъмул аст. Моҳияти он аз он иборат аст, ки муҳофизат аз зарари тасодуфӣ ба пойгоҳи додаҳо тавассути коди нодуруст илова карда шавад. Тавре ки шумо медонед, дастурҳои иҷрошавандаи раванд барои дастрасӣ ба маълумот аз ҳар ҷои фазои суроғаи он озоданд. Дар айни замон, чунон ки мо навакак дар хотир доштем, намоиш додани файл дар реҷаи хондан-навиштан маънои онро дорад, ки ҳама гуна дастур метавонад ба таври илова онро тағир диҳад. Агар вай ин корро иштибоҳан анҷом дода, масалан, кӯшиш кунад, ки воқеан як унсури массивиро дар индекси мавҷуда аз нав нависад, пас бо ин роҳ вай метавонад тасодуфан файли ба ин суроға нишондодашударо иваз кунад, ки ин боиси фасоди пойгоҳи додаҳо мегардад. Агар файл дар ҳолати танҳо барои хондан намоиш дода шавад, пас кӯшиши тағир додани фазои суроғаи ба он мувофиқ ба суқути барнома бо сигнал оварда мерасонад. SIGSEGV, ва файл бетағйир мемонад.

Натиҷаи дуюм аллакай ба iOS хос аст. На муаллиф ва на ягон сарчашмаи дигар онро ба таври возеҳ зикр накардаанд, аммо бидуни он, LMDB барои кор дар ин системаи оператсионии мобилӣ номувофиқ хоҳад буд. Бахши навбатӣ ба баррасии он бахшида шудааст.

Хусусиятҳои файлҳои харитаи хотира дар iOS

Дар соли 2018 дар WWDC як гузориши олиҷаноб буд IOS Memory Deep Dive. Дар он гуфта мешавад, ки дар iOS ҳамаи саҳифаҳои дар хотираи ҷисмонӣ ҷойгиршуда ба яке аз 3 намуд тааллуқ доранд: ифлос, фишурдашуда ва тоза.

Равшанӣ ва камбизоатии пойгоҳи додаҳои калидӣ-арзиши LMDB дар замимаҳои iOS

Хотираи тоза маҷмӯи саҳифаҳоест, ки метавонанд аз хотираи ҷисмонӣ бехатар иваз карда шаванд. Маълумоте, ки онҳо дар бар мегиранд, мумкин аст аз манбаъҳои аслии худ ҳангоми зарурат дубора бор карда шаванд. Файлҳои харитаи хотираи танҳо барои хондан ба ин категория дохил мешаванд. IOS аз бор кардани саҳифаҳои ба файл хариташуда ҳар вақт аз хотира наметарсад, зеро кафолат дода мешавад, ки онҳо бо файли диск ҳамоҳанг карда шаванд.
"Озодӣ" дар мобил
Ҳама саҳифаҳои тағирёфта ба хотираи ифлос дохил мешаванд, новобаста аз он ки онҳо дар ибтидо ҷойгиранд. Аз ҷумла, файлҳои харитаи хотира, ки тавассути навиштан ба хотираи виртуалии бо онҳо алоқаманд тағир дода шудаанд, низ бо ин роҳ тасниф карда мешаванд. Кушодани LMDB бо парчам MDB_WRITEMAP, пас аз ворид кардани тағйирот ба он, шумо метавонед худатон бубинед

Ҳамин ки барнома ба гирифтани хотираи аз ҳад зиёди ҷисмонӣ шурӯъ мекунад, iOS саҳифаҳои ифлоси худро фишурда мекунад. Маҷмӯи хотирае, ки аз ҷониби саҳифаҳои ифлос ва фишурда ишғол шудааст, изи хотираи барнома номида мешавад. Вақте ки он ба арзиши ҳадди муайян мерасад, демони системаи куштори OOM пас аз раванд меояд ва онро маҷбуран қатъ мекунад. Ин хусусияти iOS дар муқоиса бо системаҳои оператсионии мизи корӣ мебошад. Баръакс, кам кардани изофаи хотира тавассути иваз кардани саҳифаҳо аз хотираи физикӣ ба диск дар iOS пешбинӣ нашудааст.Танҳо сабабҳоро тахмин кардан мумкин аст. Шояд тартиби интиқоли пуршиддати саҳифаҳо ба диск ва қафо барои дастгоҳҳои мобилӣ аз ҳад зиёд энергия сарф мекунад ё iOS захираи азнавнависии ҳуҷайраҳоро дар дискҳои SSD сарфа мекунад ё шояд тарроҳон аз кори умумии система қаноатманд набошанд, ки дар он ҳама чиз мавҷуд аст. доимо иваз карда мешавад. Бо вуҷуди ин, воқеият боқӣ мемонад.

Хабари хуш, ки қаблан зикр шуда буд, ин аст, ки LMDB механизми mmap-ро барои навсозии файлҳо ба таври нобаёнӣ истифода намебарад. Аз ин бармеояд, ки маълумоти пешниҳодшуда аз ҷониби iOS ҳамчун хотираи тоза тасниф карда мешавад ва ба изофаи хотира мусоидат намекунад. Инро метавон бо истифода аз асбоби Xcode бо номи VM Tracker тафтиш кард. Намоиши зер ҳолати хотираи виртуалии замимаи iOS Cloud ҳангоми кор нишон медиҳад. Дар оғоз, дар он 2 мисоли LMDB оғоз карда шуданд. Ба аввал иҷозат дода шуд, ки файли худро ба 1GiB хотираи виртуалӣ харита кунад, дуюм - 512MiB. Сарфи назар аз он, ки ҳарду анборҳо миқдори муайяни хотираи доимиро ишғол мекунанд, ҳеҷ яке аз онҳо ба андозаи ифлос мусоидат намекунанд.

Равшанӣ ва камбизоатии пойгоҳи додаҳои калидӣ-арзиши LMDB дар замимаҳои iOS

Акнун вақти хабари бад аст. Бо шарофати механизми своп дар системаҳои оператсионии мизи кории 64-бит, ҳар як раванд метавонад фазои суроғаи виртуалиро ишғол кунад, зеро фазои холӣ дар диски сахт имкон медиҳад, ки свопи эҳтимолии он. Иваз кардани своп бо фишурда дар iOS ҳадди назариявиро ба таври назаррас коҳиш медиҳад. Акнун ҳама равандҳои зинда бояд ба хотираи асосӣ (хотираи RAM) мувофиқ бошанд ва ҳамаи онҳое, ки мувофиқ нестанд, маҷбуран қатъ карда мешаванд. Он тавре ки дар боло зикр шудааст хисобот, ва дар ҳуҷҷатҳои расмӣ. Дар натиҷа, iOS миқдори хотираро барои тақсимот тавассути mmap ба таври ҷиддӣ маҳдуд мекунад. Ин ҷо дар ин ҷо шумо метавонед ба маҳдудиятҳои таҷрибавӣ оид ба ҳаҷми хотирае, ки метавонанд дар дастгоҳҳои гуногун бо истифода аз ин занги система ҷудо карда шаванд, бубинед. Дар моделҳои муосиртарини смартфонҳо, iOS 2 гигабайт ва дар версияҳои болоии iPad - 4 саховатманд шудааст. Дар амал, албатта, шумо бояд ба ҷавонтарин моделҳои дастгоҳи дастгирӣшаванда диққат диҳед, ки ҳама чиз хеле ғамгин аст. Ҳатто бадтар, ба ҳолати хотираи барнома дар VM Tracker нигоҳ карда, шумо хоҳед дид, ки LMDB аз ягонае, ки хотираи харитаи хотираро талаб мекунад, дур аст. Қисмҳои хубро тақсимкунандагони система, файлҳои захиравӣ, чаҳорчӯбаи тасвирӣ ва дигар даррандаҳои хурдтар мехӯранд.

Дар натиҷаи таҷрибаҳо дар Абр, мо арзишҳои зерини компромиссии хотираи аз ҷониби LMDB ҷудошударо пайдо кардем: 384 мегабайт барои дастгоҳҳои 32-бит ва 768 барои дастгоҳҳои 64-бит. Пас аз тамом шудани ин ҳаҷм, ҳама гуна амалиёти тағирдиҳӣ бо рамз ба анҷом мерасад MDB_MAP_FULL. Мо дар мониторинги худ чунин хатогиҳоро мушоҳида мекунем, аммо онҳо ба қадри кофӣ хурд ҳастанд, ки дар ин марҳила беэътиноӣ карда шаванд.

Сабаби норавшани истеъмоли аз ҳад зиёди хотираи нигаҳдорӣ метавонад транзаксияҳои дарозмуддат бошад. Барои фаҳмидани он, ки ин ду падида чӣ гуна алоқаманданд, он ба мо кӯмак мекунад, ки ду наҳангҳои боқимондаи LMDB баррасӣ кунем.

3.2. Наҳанг №2. B+-дарахт

Барои тақлид кардани ҷадвалҳо дар болои мағозаи арзишҳо, амалиёти зерин бояд дар API-и он мавҷуд бошанд:

  1. Ворид кардани элементи нав.
  2. Ҷустуҷӯи элемент бо калиди додашуда.
  3. Нест кардани элемент.
  4. Дар фосилаҳои калидӣ бо тартиби навъашон такрор кунед.

Равшанӣ ва камбизоатии пойгоҳи додаҳои калидӣ-арзиши LMDB дар замимаҳои iOSСоддатарин сохтори додаҳо, ки метавонад ҳамаи чор амалиётро ба осонӣ иҷро кунад, дарахти ҷустуҷӯии бинарӣ мебошад. Ҳар як гиреҳи он калидест, ки тамоми зермаҷмӯи калидҳои кӯдакро ба ду зердарахт тақсим мекунад. Дар тарафи чап онҳое ҳастанд, ки аз волидайн хурдтаранд ва дар тарафи рост - онҳое, ки калонтаранд. Гирифтани маҷмӯи фармоишии калидҳо тавассути яке аз гузаришҳои классикии дарахт ба даст оварда мешавад

Дарахтони дуӣ ду камбудии асосӣ доранд, ки ба онҳо ҳамчун сохтори додаҳои диск таъсир намерасонанд. Аввалан, дараҷаи мувозинати онҳо пешгӯинашаванда аст. Хатари назарраси ба даст овардани дарахтҳо вуҷуд дорад, ки дар онҳо баландии шохаҳои гуногун метавонанд хеле фарқ кунанд, ки ин мураккабии алгоритмии ҷустуҷӯро нисбат ба он чизе, ки интизор меравад, ба таври назаррас бадтар мекунад. Сониян, фаровонии пайвандҳои байни гиреҳҳо дарахтони бинариро аз маҳалли ҷойгиршавӣ дар хотира маҳрум мекунад.Гиреҳҳои пӯшида (аз рӯи робитаи байни онҳо) метавонанд дар саҳифаҳои тамоман дигар дар хотираи виртуалӣ ҷойгир шаванд. Дар натиҷа, ҳатто гузариши оддии якчанд гиреҳҳои ҳамсоя дар дарахт метавонад дидани шумораи муқоисашавандаи саҳифаҳоро талаб кунад. Ҳатто вақте ки мо дар бораи самаранокии дарахтони бинарӣ ҳамчун сохтори маълумот дар хотира гап мезанем, ин мушкилот аст, зеро пайваста гардиши саҳифаҳо дар кэши протсессор арзон нест. Вақте ки сухан дар бораи зуд-зуд баланд бардоштани саҳифаҳои марбут ба гиреҳ аз диск меравад, кор воқеан бад мешавад. таассуфовар.

Равшанӣ ва камбизоатии пойгоҳи додаҳои калидӣ-арзиши LMDB дар замимаҳои iOSB-дарахтҳо, ки эволютсияи дарахтони бинарӣ мебошанд, мушкилоти дар параграфи қаблӣ зикршударо ҳал мекунанд. Аввалан, онҳо худтанзимкунанд. Сониян, ҳар як гиреҳи онҳо маҷмӯи калидҳои кӯдакиро на ба 2, балки ба зергурӯҳҳои фармоишии M тақсим мекунад ва адади М метавонад хеле калон бошад, бо тартиби чандсад ё ҳатто ҳазорҳо.

Ҳамин тариқ:

  1. Ҳар як гиреҳ шумораи зиёди калидҳои фармоишӣ дорад ва дарахтон хеле пастанд.
  2. Дарахт дар хотира моликияти маҳаллиро ба даст меорад, зеро калидҳои арзишашон наздик табиатан дар як гиреҳ ё гиреҳи ҳамсоя дар паҳлӯи ҳамдигар ҷойгиранд.
  3. Шумораи гиреҳҳои транзитӣ ҳангоми фуромадан аз дарахт ҳангоми амалиёти ҷустуҷӯ кам мекунад.
  4. Шумораи гиреҳҳои мавриди ҳадафро, ки барои дархостҳои диапазон хонда мешаванд, кам мекунад, зеро ҳар яки онҳо аллакай миқдори зиёди калидҳои фармоишӣ доранд.

Равшанӣ ва камбизоатии пойгоҳи додаҳои калидӣ-арзиши LMDB дар замимаҳои iOS

LMDB барои нигоҳ доштани маълумот варианти дарахти B-ро истифода мебарад, ки дарахти B+ ном дорад. Диаграммаи боло се намуди гиреҳҳоро нишон медиҳад, ки онҳо дар бар мегиранд:

  1. Дар боло реша аст. Он чизе ҷуз мафҳуми пойгоҳи додаҳо дар дохили анбор амалӣ намекунад. Дар дохили як мисоли LMDB, шумо метавонед якчанд пойгоҳи додаҳо эҷод кунед, ки фазои суроғаи виртуалии хариташударо мубодила мекунанд. Ҳар яке аз онҳо аз решаи худ оғоз меёбад.
  2. Дар сатҳи пасттарин баргҳо (барг) мебошанд. Маҳз онҳо ва танҳо онҳо ҷуфтҳои калид-арзишро дар пойгоҳи додаҳо нигоҳ медоранд. Дар омади гап, дар хамин аст хусусияти дарахтони В+. Агар дарахти муқаррарии B қисмҳои арзишро дар гиреҳҳои ҳама сатҳҳо нигоҳ дорад, пас тағирёбии B+ танҳо дар пасттарин аст. Пас аз ислоҳи ин далел, мо дар он чизе, ки дар оянда мо зернавъи дарахти дар LMDB истифодашавандаро танҳо як дарахти B меномем.
  3. Дар байни реша ва баргҳо 0 ё зиёда сатҳҳои техникӣ бо гиреҳҳои навигатсионӣ (шоха) мавҷуданд. Вазифаи онҳо тақсим кардани маҷмӯи мураттабшудаи калидҳо дар байни баргҳо мебошад.

Аз ҷиҳати ҷисмонӣ, гиреҳҳо блокҳои хотираи дарозии пешакӣ муайяншуда мебошанд. Андозаи онҳо аз андозаи саҳифаҳои хотираи системаи оператсионӣ, ки мо дар бораи он дар боло гуфта будем, чанд баробар аст. Сохтори гиреҳ дар зер нишон дода шудааст. Сарлавҳа мета-маълумотро дар бар мегирад, ки равшантаринаш, масалан, маблағи назорат аст. Баъдан маълумот дар бораи офсетҳо меояд, ки дар он ҳуҷайраҳои дорои маълумот ҷойгиранд. Нақши маълумот метавонад ё калидҳо бошад, агар сухан дар бораи гиреҳҳои навигатсионӣ равад, ё тамоми ҷуфтҳои калид-арзиш дар мавриди баргҳо.Шумо метавонед бештар дар бораи сохтори саҳифаҳо дар кор хонед. "Арзёбии мағозаҳои баландсифати калидӣ".

Равшанӣ ва камбизоатии пойгоҳи додаҳои калидӣ-арзиши LMDB дар замимаҳои iOS

Бо мундариҷаи дохилии гиреҳҳои саҳифа сарукор дошта, мо минбаъд дарахти LMDB B-ро ба таври соддакардашуда дар шакли зерин муаррифӣ хоҳем кард.

Равшанӣ ва камбизоатии пойгоҳи додаҳои калидӣ-арзиши LMDB дар замимаҳои iOS

Саҳифаҳое, ки гиреҳ доранд, дар диск пайдарпай ҷойгир карда мешаванд. Саҳифаҳое, ки шумораи зиёдтар доранд, дар охири файл ҷойгиранд. Саҳифаи ба истилоҳ мета (мета саҳифа) дорои маълумот дар бораи офсетҳо мебошад, ки барои пайдо кардани решаҳои ҳамаи дарахтон истифода мешавад. Вақте ки файл кушода мешавад, LMDB саҳифа ба саҳифаи файлро аз охир то аввал дар ҷустуҷӯи метасаҳифаи дуруст скан мекунад ва тавассути он пойгоҳи додаҳои мавҷударо пайдо мекунад.

Равшанӣ ва камбизоатии пойгоҳи додаҳои калидӣ-арзиши LMDB дар замимаҳои iOS

Ҳоло, ки дар бораи сохтори мантиқӣ ва физикии ташкили додаҳо тасаввурот пайдо карда, мо метавонем ба баррасии наҳанги сеюми LMDB идома диҳем. Маҳз бо кӯмаки он ҳама тағиротҳои нигаҳдорӣ ба таври транзаксионӣ ва дар алоҳидагӣ аз ҳамдигар ба амал меоянд ва ба пойгоҳи додаҳо дар маҷмӯъ моликияти мултипликаториро медиҳад.

3.3. Наҳанг №3. нусхабардорӣ ба навиштан

Баъзе амалиётҳои дарахти B ворид кардани як қатор тағиротро дар гиреҳҳои он дар бар мегиранд. Як мисол ин илова кардани калиди нав ба гиреҳ аст, ки аллакай ба иқтидори максималии худ расидааст. Дар ин ҳолат, аввал, гиреҳро ба ду тақсим кардан лозим аст ва дуюм, ба гиреҳи кӯдаки нав дар волидайни он пайванд илова кардан лозим аст. Ин раванд эҳтимолан хеле хатарнок аст. Агар бо ягон сабаб (фалокат, қатъи барқ ​​ва ғайра) танҳо як қисми тағирот аз силсила рӯй диҳад, он гоҳ дарахт дар ҳолати номувофиқ боқӣ мемонад.

Як ҳалли анъанавӣ барои ба хатогиҳои пойгоҳи додаҳо таҳаммулпазир будан ин илова кардани сохтори иловагии маълумот дар асоси диск мебошад, ки гузориши транзаксия, ки инчунин бо номи сабти пеш аз навиштан (WAL) дар паҳлӯи дарахти B маълум аст. Ин файлест, ки дар охири он, ба таври қатъӣ пеш аз тағир додани худи дарахти B, амалиёти пешбинишуда навишта мешавад. Ҳамин тариқ, агар ҳангоми ташхиси худфаъолият фасоди маълумот ошкор карда шавад, пойгоҳи додаҳо ба гузориш муроҷиат мекунанд, то худро тоза кунад.

LMDB усули дигарро ҳамчун механизми таҳаммулпазирии хатогиҳои худ интихоб кардааст, ки онро нусхабардорӣ дар навиштан меноманд. Моҳияти он дар он аст, ки ба ҷои навсозии маълумот дар саҳифаи мавҷуда, он аввал онро пурра нусхабардорӣ мекунад ва ҳама тағиротҳоро аллакай дар нусхабардорӣ мекунад.

Равшанӣ ва камбизоатии пойгоҳи додаҳои калидӣ-арзиши LMDB дар замимаҳои iOS

Ғайр аз он, барои дастрас шудани маълумоти навшуда, зарур аст, ки пайвандро ба гиреҳе, ки дар гиреҳи волидайн нисбат ба он навсозӣ шудааст, тағир диҳед. Азбаски он низ бояд барои ин тағир дода шавад, он инчунин пешакӣ нусхабардорӣ карда мешавад. Раванд ба таври рекурсивӣ то реша идома меёбад. Маълумот дар саҳифаи мета охирин тағирёбанда аст

Равшанӣ ва камбизоатии пойгоҳи додаҳои калидӣ-арзиши LMDB дар замимаҳои iOS

Агар ногаҳон дар ҷараёни навсозӣ раванд вайрон шавад, он гоҳ ё мета-саҳифаи нав сохта намешавад, ё он то ба охир ба диск навишта намешавад ва маблағи назоратии он нодуруст хоҳад буд. Дар яке аз ин ду ҳолат, саҳифаҳои нав дастнорас хоҳанд буд ва ба саҳифаҳои кӯҳна таъсир намерасонад. Ин зарурати LMDB барои навиштани сабти пешакӣ барои нигоҳ доштани мутобиқати маълумотро аз байн мебарад. Воқеан, сохтори нигоҳдории маълумот дар диск, ки дар боло тавсиф шудааст, дар як вақт вазифаи худро мегирад. Набудани сабти муомилоти возеҳ яке аз хусусиятҳои LMDB мебошад, ки суръати баланди хондани маълумотро таъмин мекунад.

Равшанӣ ва камбизоатии пойгоҳи додаҳои калидӣ-арзиши LMDB дар замимаҳои iOS

Сохтмони натиҷавӣ, ки танҳо B-дарахти замима номида мешавад, табиатан ҷудокунии транзаксия ва мултипликатсияро таъмин мекунад. Дар LMDB, ҳар як амалиёти кушода дорои решаи дарахти муосири бо он алоқаманд аст. То он даме, ки транзаксия анҷом наёбад, саҳифаҳои дарахти бо он алоқаманд ҳеҷ гоҳ барои версияҳои нави додаҳо иваз карда намешаванд ё аз нав истифода намешаванд. Ҳамин тавр, шумо метавонед то он даме, ки ба шумо маҳз бо маҷмӯи маълумоте, ки дар он мувофиқ буд, кор кунед. вақте ки транзаксия кушода шуд, ҳатто агар нигоҳдорӣ дар айни замон фаъолона нав карда шавад. Ин моҳияти мултипликатсия аст, ки LMDB-ро ба манбаи беҳтарини маълумот барои маҳбуби мо табдил медиҳад UICollectionView. Пас аз кушодани транзаксия, ба шумо лозим нест, ки изофаи хотираи барномаро зиёд кунед, маълумоти ҷорӣро ба ягон сохтори хотира шитобон интиқол диҳед ва метарсанд, ки ҳеҷ чиз намемонад. Ин хусусият LMDB-ро аз ҳамон SQLite фарқ мекунад, ки бо чунин изолятсияи умумӣ фахр карда наметавонад. Пас аз кушодани ду транзаксия дар охирин ва нест кардани сабти муайян дар яке аз онҳо, ҳамон сабтро дигар дар дохили дуюми боқимонда гирифтан мумкин нест.

Ҷониби паҳлӯи танга ин истеъмоли эҳтимолан баландтари хотираи виртуалӣ мебошад. Слайд нишон медиҳад, ки сохтори пойгоҳи додаҳо чӣ гуна хоҳад буд, агар он дар як вақт бо 3 амалиёти хониши кушод ба версияҳои гуногуни пойгоҳи додаҳо тағир дода шавад. Азбаски LMDB гиреҳҳоеро, ки аз решаҳои марбут ба транзаксияҳои воқеӣ дастрасанд, дубора истифода бурда наметавонад, анбор ҷуз ҷудо кардани решаи чоруми дигар дар хотира ва бори дигар саҳифаҳои тағирёфтаро дар зери он клон кардан илоҷ надорад.

Равшанӣ ва камбизоатии пойгоҳи додаҳои калидӣ-арзиши LMDB дар замимаҳои iOS

Дар ин ҷо ба ёд овардани қисмат оид ба файлҳои хариташудаи хотира зиёдатӣ нахоҳад буд. Чунин ба назар мерасад, ки истеъмоли иловагии хотираи виртуалӣ набояд моро зиёд ташвиш диҳад, зеро он ба изофаи хотираи барнома мусоидат намекунад. Аммо, дар баробари ин қайд карда шуд, ки iOS дар тақсими он хеле хасис аст ва мо наметавонем минтақаи 1 терабайтии LMDB-ро дар сервер ё мизи корӣ аз китфи устод таъмин кунем ва дар бораи ин хусусият умуман фикр накунем. Агар имконпазир бошад, шумо бояд кӯшиш кунед, ки мӯҳлати транзаксияҳоро то ҳадди имкон кӯтоҳ нигоҳ доред.

4. Тарҳрезии схемаи додаҳо дар болои API-и арзиши калидӣ

Биёед таҳлили API-ро бо дидани абстраксияҳои асосии аз ҷониби LMDB пешниҳодшуда оғоз кунем: муҳити зист ва пойгоҳи додаҳо, калидҳо ва арзишҳо, транзаксияҳо ва курсорҳо.

Қайд дар бораи рӯйхати кодҳо

Ҳама функсияҳо дар API оммавии LMDB натиҷаи кори худро дар шакли коди хато бармегардонанд, аммо дар ҳама рӯйхатҳои минбаъда санҷиши он ба хотири мухтасар нест.Дар амал мо коди худро барои ҳамкорӣ бо анбор истифода бурдем. чангак Рамзҳои C++ 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, зиёд кунед. Бо вуҷуди ин, он хеле сахттар аст. Сабаб дар он аст, ки тартиби remapping хотира бо истифода аз функсия mdb_env_set_map_size ҳамаи объектҳоро (курсорҳо, транзаксияҳо, калидҳо ва арзишҳо) аз муҳаррик қаблан гирифташударо беэътибор мекунад. Баҳисобгирии чунин гардиши ҳодисаҳо дар кодекс боиси мушкилии назарраси он мегардад. Агар, ба ҳар ҳол, хотираи виртуалӣ барои шумо хеле азиз аст, пас ин метавонад як сабаби назар кардан ба форте, ки хеле пеш рафтааст, бошад. MDBX, ки дар байни хусусиятҳои эълоншуда "тасҳеҳи автоматии андозаи пойгоҳи додаҳо" мавҷуд аст.

Параметри дуюм, ки арзиши пешфарз ба мо мувофиқ набуд, механизми таъмини бехатарии риштаро танзим мекунад. Мутаассифона, ҳадди аққал дар iOS 10, мушкилот бо дастгирии нигаҳдории маҳаллӣ вуҷуд доранд. Аз ин сабаб, дар мисоли боло, анбор бо парчам кушода мешавад MDB_NOTLS. Илова бар ин, он низ талаб карда мешавад чангак Сарпӯши C++ lmdbxxбарои буридани тағирёбандаҳо бо ва дар ин атрибут.

Департаментҳо

Пойгоҳи маълумот як мисоли алоҳидаи дарахти B мебошад, ки мо дар бораи он дар боло гуфта будем. Ифтитоҳи он дар дохили транзаксия рух медиҳад, ки дар аввал метавонад каме аҷиб ба назар расад.

MDB_txn *txn;​
MDB_dbi dbi;​
mdb_txn_begin(env, NULL, MDB_RDONLY, &txn);​
mdb_dbi_open(txn, NULL, MDB_CREATE, &dbi);​
mdb_txn_abort(txn);

Дарвоқеъ, транзаксия дар LMDB объекти нигоҳдорӣ аст, на пойгоҳи додаҳои мушаххас. Ин консепсия ба шумо имкон медиҳад, ки амалиёти атомиро дар объектҳое, ки дар пойгоҳи додаҳои гуногун ҷойгиранд, анҷом диҳед. Дар назария, ин имкони моделсозии ҷадвалҳоро дар шакли пойгоҳи додаҳои гуногун мекушояд, аммо дар як вақт ман бо роҳи дигар рафтам, ки дар зер муфассал тавсиф шудааст.

Калидҳо ва арзишҳо

сохтори MDB_val консепсияи ҳам калид ва ҳам арзишро модел мекунад. Анбор дар бораи семантикаи онҳо тасаввуроте надорад. Барои вай чизе, ки гуногун аст, танҳо массиви байтҳои андозаи додашуда аст. Андозаи максималии калид 512 байт аст.

typedef struct MDB_val {​
    size_t mv_size;​
    void *mv_data;​
} MDB_val;​​

Мағоза барои мураттаб кардани калидҳо бо тартиби афзоиш аз муқоисакунанда истифода мебарад. Агар шумо онро бо худатон иваз накунед, он гоҳ пешфарз истифода мешавад, ки онҳоро байт ба байт аз рӯи тартиби лексикографӣ ҷудо мекунад.

Амалиётҳо

Дастгоҳи транзаксия дар муфассал тавсиф карда шудааст боби гузашта, бинобар ин ман хосиятҳои асосии онҳоро дар хати кӯтоҳ такрор мекунам:

  1. Дастгирии ҳама хусусиятҳои асосӣ КислотаКалидвожаҳо: атомӣ, пайвастагӣ, ҷудошавӣ ва эътимоднокӣ. Ман наметавонам қайд кунам, ки аз ҷиҳати устуворӣ дар macOS ва iOS хатогие дар MDBX ислоҳ шудааст. Шумо метавонед бештар дар онҳо хонед README.
  2. Муносибат ба чанд ришта аз ҷониби нақшаи "нависандаи якка/хонандаҳои сершумор" тавсиф карда мешавад. Нависандагон якдигарро манъ мекунанд, аммо хонандагонро намебанданд. Хонандагон нависандагон ё якдигарро манъ намекунанд.
  3. Дастгирии амалиёти лона.
  4. Дастгирии бисёрсоҳавӣ.

Мултиверсионӣ дар LMDB он қадар хуб аст, ки ман мехоҳам онро дар амал нишон диҳам. Рамзи дар поён овардашуда нишон медиҳад, ки ҳар як транзаксия маҳз бо версияи махзани маълумот кор мекунад, ки ҳангоми кушодани он мувофиқ буд ва аз ҳама тағйироти минбаъда комилан ҷудо карда шудааст. Оғоз кардани анбор ва илова кардани сабти санҷиш ба он таваҷҷӯҳе надорад, аз ин рӯ ин расму оинҳо дар зери спойлер гузошта мешаванд.

Илова кардани вуруди санҷишӣ

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 санҷед ва бубинед, ки чӣ мешавад.

Multiversioning ба ҳаёти як таҳиягари iOS манфиатҳои хеле хуб меорад. Бо истифода аз ин амвол, шумо метавонед ба осонӣ ва табиатан суръати навсозии манбаи маълумотро барои шаклҳои экран дар асоси мулоҳизаҳои таҷрибаи корбар танзим кунед. Масалан, биёед чунин хусусияти замимаи Mail.ru Cloud-ро ба мисли худборкунии мундариҷа аз галереяи медиаи система гирем. Бо пайвасти хуб, муштарӣ метавонад дар як сония ба сервер якчанд акс илова кунад. Агар шумо пас аз ҳар боргирӣ навсозӣ кунед UICollectionView бо мундариҷаи медиавӣ дар абри корбар, шумо метавонед дар бораи 60 fps ва ҳаракати ҳамвор дар ин раванд фаромӯш кунед. Барои пешгирӣ кардани навсозии зуд-зуд экран, шумо бояд суръати тағири маълумотро дар асос маҳдуд кунед UICollectionViewDataSource.

Агар базаи маълумот мултипликатсияро дастгирӣ накунад ва ба шумо имкон диҳад, ки танҳо бо ҳолати кунунӣ кор кунед, пас барои эҷоди як акси маълумот дар вақти мӯътадил, шумо бояд онро ба ягон сохтори маълумот дар хотира ё ба ҷадвали муваққатӣ нусхабардорӣ кунед. Ҳар яке аз ин равишҳо хеле гарон аст. Дар ҳолати нигоҳдории хотира, мо ҳам хароҷоти хотираро, ки аз нигоҳдории объектҳои сохташуда ба вуҷуд омадаанд ва хароҷоти вақти марбут ба тағирёбии зиёдатии ORM мегирем. Дар мавриди мизи муваққатӣ, ин як лаззати боз ҳам гаронтар аст, ки танҳо дар ҳолатҳои ночиз маъно дорад.

Multiversioning LMDB масъалаи нигоҳ доштани манбаи устувори маълумотро ба таври хеле шево ҳал мекунад. Танҳо кушодани транзаксия ва voila кифоя аст - то он даме, ки мо онро ба анҷом расонем, маҷмӯи маълумот кафолат дода мешавад, ки собит карда шавад. Мантиқи суръати навсозии он ҳоло комилан дар дасти қабати муаррифӣ аст ва бидуни сарбории захираҳои назаррас.

Курсорҳо

Курсорҳо механизми такрори муташаккилро аз рӯи ҷуфтҳои калид-арзиш тавассути убури дарахти B таъмин мекунанд. Бе онҳо, ба таври муассир моделсозии ҷадвалҳо дар базаи маълумот имконнопазир мебуд, ки мо ҳоло ба онҳо муроҷиат мекунем.

4.2. Моделсозии ҷадвал

Амволи фармоишии калидӣ ба шумо имкон медиҳад, ки абстраксияи сатҳи олиро ба мисли ҷадвал дар болои абстраксияҳои асосӣ созед. Биёед ин равандро дар мисоли ҷадвали асосии муштарии абр баррасӣ кунем, ки дар он маълумот дар бораи ҳама файлҳо ва ҷузвдонҳои корбар кэш карда мешавад.

Схемаи ҷадвал

Яке аз сенарияҳои маъмуле, ки барои он сохтори ҷадвал бо дарахти ҷузвдонҳо равшан карда мешавад, ин интихоби ҳамаи унсурҳои дар дохили директорияи додашуда мебошад.Модели хуби ташкили додаҳо барои пурсишҳои самараноки ин гуна аст. Рӯйхати ҳамҷоягӣ. Барои татбиқи он дар болои захираи арзишҳои калидӣ, калидҳои файлҳо ва ҷузвдонҳоро тавре ҷудо кардан лозим аст, ки онҳо аз рӯи мансубият ба директорияи волидайн гурӯҳбандӣ карда шаванд. Илова бар ин, барои намоиш додани мундариҷаи директория дар шакле, ки ба корбари Windows шинос аст (аввал ҷузвдонҳо, баъд файлҳо, ҳарду аз рӯи алифбо мураттаб карда мешаванд) дар калид майдонҳои иловагии мувофиқро дохил кардан лозим аст.

Дар расми зер нишон дода шудааст, ки дар асоси вазифа чӣ гуна муаррифии калидҳо ҳамчун массиви байтҳо ба назар мерасад. Аввалан, байтҳо бо идентификатори директорияи волидайн (сурх), баъд бо навъи (сабз) ва аллакай дар дум бо ном (кабуд) ҷойгир карда мешаванд. Бо муқоисаи пешфарзи LMDB аз рӯи тартиби лексикографӣ мураттаб карда мешаванд. роҳи зарурӣ. Пайдарпай гузариши калидҳо бо ҳамон префикси сурх ба мо арзишҳои бо онҳо алоқамандро бо тартибе медиҳад, ки онҳо бояд дар интерфейси корбар (аз рост) бидуни коркарди минбаъдаи иловагӣ талаб карда шаванд.

Равшанӣ ва камбизоатии пойгоҳи додаҳои калидӣ-арзиши LMDB дар замимаҳои iOS

Сериализатсияи калидҳо ва арзишҳо

Дар саросари ҷаҳон усулҳои сериализатсияи объектҳо мавҷуданд. Азбаски мо ба ҷуз суръат талаби дигаре надоштем, мо барои худамон зудтаринтаринро интихоб кардем - партови хотира, ки онро намунаи сохтори забони Си ишғол кардааст.Пас, калиди элементи директорияро метавон бо сохтори зерин модел кард. 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 вазъияти афсонавӣ ба даст оред - танҳо хотираи стекро барои кор бо маълумот аз шабака то диск истифода баред!

Фармоиши калидҳо бо муқоисаи дуӣ

Муносибати тартиби калидӣ бо функсияи махсус дода мешавад, ки муқоисакунанда номида мешавад. Азбаски муҳаррик дар бораи семантикаи байтҳои дар онҳо мавҷудбуда чизе намедонад, муқоисакунандаи пешфарз чорае надорад, ки калидҳоро бо тартиби лексикографӣ ҷойгир кунад ва ба муқоисаи байт ба байт муроҷиат кунад. Истифодаи он барои тартиб додани сохторҳо ба риштарошӣ бо табар кандакорӣ монанд аст. Аммо, дар ҳолатҳои оддӣ, ман ин усулро қобили қабул меҳисобам. Алтернатива дар зер тавсиф карда мешавад, аммо дар ин ҷо ман якчанд ракеро, ки дар роҳ парокандаанд, қайд мекунам.

Аввалин чизе, ки бояд дар хотир дошт, ин намоиши хотираи намудҳои ибтидоии додаҳо мебошад. Ҳамин тавр, дар ҳама дастгоҳҳои Apple, тағирёбандаҳои бутун дар формат нигоҳ дошта мешаванд Endian хурд. Ин маънои онро дорад, ки байти камтарин дар тарафи чап хоҳад буд ва шумо наметавонед ададҳои бутунро бо истифода аз муқоисаи байт ба байт ҷудо кунед. Масалан, кӯшиши ин корро бо маҷмӯи рақамҳои аз 0 то 511 натиҷаи зерин меорад.

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

Барои ҳалли ин масъала, ададҳои бутун бояд дар калид дар формате нигоҳ дошта шаванд, ки барои муқоисаи байт мувофиқ аст. Функсияҳои оилавӣ барои анҷом додани тағироти зарурӣ кӯмак мекунанд. hton* (алалхусус htons барои рақамҳои дубайтӣ аз мисол).

Формат барои муаррифии сатрҳо дар барномасозӣ, чунон ки шумо медонед, як кулл аст таърих. Агар семантикаи сатрҳо, инчунин рамзгузории барои муаррифии онҳо дар хотира истифодашаванда нишон диҳад, ки метавонад дар як аломат зиёда аз як байт мавҷуд бошад, пас беҳтар аст, ки аз идеяи истифодаи муқоисакунандаи пешфарз фавран даст кашед.

Чизи дуюм, ки бояд дар хотир дошта бошад Принсипҳои ҳамоҳангсозӣ компилятори соҳаи сохтор. Ба шарофати онҳо, байтҳоро бо арзишҳои партов дар хотира байни майдонҳо ташкил кардан мумкин аст, ки албатта ҷудокунии байтҳоро вайрон мекунад. Барои нест кардани партовҳо, шумо бояд майдонҳоро бо тартиби ба таври қатъӣ муайяншуда эълон кунед, ки қоидаҳои ҳамоҳангиро дар хотир нигоҳ доред ё атрибутро дар эъломияи сохтор истифода баред packed.

Фармоиши калидҳо аз ҷониби муқоисакунандаи беруна

Мантиқи муқоисаи калидӣ метавонад барои муқоисаи дуӣ хеле мураккаб бошад. Яке аз сабабҳои зиёд мавҷудияти майдонҳои техникӣ дар дохили сохторҳо мебошад. Ман пайдоиши онҳоро дар мисоли калиди барои элементи директория аллакай ба мо шинос нишон медиҳам.

typedef struct NodeKey {​
    EntityId parentId;​
    uint8_t type;​
    uint8_t nameBuffer[256];​
} NodeKey;

Бо тамоми соддагии он, дар аксари ҳолатҳо он хотираи аз ҳад зиёдро истеъмол мекунад. Буфери унвон 256 байт аст, гарчанде ки ба ҳисоби миёна номи файлҳо ва ҷузвдонҳо аз 20-30 аломат кам зиёд мешавад.

Яке аз усулҳои стандартии оптимизатсияи андозаи сабт ин буридани он ба андозаи воқеии он мебошад. Мохияти он аз он иборат аст, ки мазмуни хамаи майдонхои дарози тагйирёбанда дар буфер дар охири сохтор ва дарозии онхо дар тагйирёбандахои алохида нигох дошта мешаванд.Мувофики ин равиш калид NodeKey ба таври зерин табдил дода мешавад.

typedef struct NodeKey {​
    EntityId parentId;​
    uint8_t type;​
    uint8_t nameLength;​
    uint8_t nameBuffer[256];​
} NodeKey;

Ғайр аз он, ҳангоми сериализатсия, ҳамчун андозаи маълумот муайян карда нашудааст sizeof тамоми сохтор ва андозаи ҳамаи майдонҳо дарозии собит плюс андозаи қисми воқеан истифодашудаи буфер аст.

MDB_val serialize(NodeKey * const key) {
    return MDB_val {
        .mv_size = offsetof(NodeKey, nameBuffer) + key->nameLength,
        .mv_data = (void *)key
    };
}

Дар натиҷаи рефакторинг мо дар фазои ишғолкардаи калидҳо сарфаи назаррас ба даст овардем. Бо вучуди ин, аз сабаби сохаи техникй nameLength, муқоисакунандаи пешфарзии дуӣ дигар барои муқоисаи калид мувофиқ нест. Агар мо онро бо номи худамон иваз накунем, пас дарозии ном дар навъбандӣ нисбат ба худи ном авлавиятноктар хоҳад буд.

LMDB имкон медиҳад, ки ҳар як пойгоҳи додаҳо вазифаи муқоисавии калидии худро дошта бошад. Ин бо истифода аз функсия анҷом дода мешавад mdb_set_compare ба таври қатъӣ пеш аз кушодан. Бо сабабҳои маълум, пойгоҳи додаҳоро дар тӯли тамоми умри худ тағир додан мумкин нест. Дар вуруд, муқоисакунанда ду калидро дар формати дуӣ қабул мекунад ва дар баромад натиҷаи муқоисаро бармегардонад: камтар аз (-1), бузургтар аз (1) ё баробар (0). Pseudocode барои NodeKey ба назар чунин менамояд.

int compare(MDB_val * const a, MDB_val * const b) {​
    NodeKey * const aKey = (NodeKey * const)a->mv_data;​
    NodeKey * const bKey = (NodeKey * const)b->mv_data;​
    return // ...
}​

То он даме, ки ҳамаи калидҳои пойгоҳи додаҳо як навъанд, бечунучаро интиқол додани намоиши байтҳои онҳо ба намуди сохтори барномаи калид қонунист. Дар ин ҷо як нозуки вуҷуд дорад, аммо он дар зербахши "Сабти хониш" каме поёнтар баррасӣ хоҳад шуд.

Сериализатсияи арзиш

Бо калидҳои сабтҳои захирашуда, LMDB хеле пуршиддат кор мекунад. Онҳо дар доираи ҳама гуна амалиёти барномавӣ бо ҳамдигар муқоиса карда мешаванд ва иҷрои тамоми ҳалли он аз суръати муқоисакунанда вобаста аст. Дар ҷаҳони идеалӣ, муқоисакунандаи пешфарзии дуӣ бояд барои муқоисаи калидҳо кифоя бошад, аммо агар шумо воқеан лозим буд, ки худатонро истифода баред, пас тартиби бесериализатсияи калидҳо дар он бояд ҳарчи зудтар бошад.

Махзани маълумот махсусан ба арзиши-қисми сабт (арзиш) манфиатдор нест. Табдили он аз тасвири байт ба объект танҳо вақте сурат мегирад, ки он аллакай аз ҷониби коди барнома, масалан, дар экран намоиш додани он талаб карда мешавад. Азбаски ин нисбатан кам рух медиҳад, талабот ба суръати ин тартиб чандон муҳим нест ва ҳангоми татбиқи он мо ба роҳат таваҷҷӯҳи бештар дорем.Масалан, барои сериализатсия кардани метамаълумот дар бораи файлҳое, ки ҳанӯз бор карда нашудаанд, мо истифода мебарем. NSKeyedArchiver.

NSData *data = serialize(object);​
MDB_val value = {​
    .mv_size = data.length,​
    .mv_data = (void *)data.bytes​
};

Бо вуҷуди ин, вақтҳое ҳастанд, ки иҷрои он муҳим аст. Масалан, ҳангоми нигоҳ доштани мета-маълумот дар бораи сохтори файлии абри корбар, мо ҳамон партови хотираи объектро истифода мебарем. Барҷастаи вазифаи тавлиди намоиши силсилавии онҳо он аст, ки унсурҳои директория аз рӯи иерархияи синф модел карда шудаанд.

Равшанӣ ва камбизоатии пойгоҳи додаҳои калидӣ-арзиши LMDB дар замимаҳои iOS

Барои татбиқи он дар забони Си, соҳаҳои мушаххаси ворисон ба сохторҳои алоҳида гирифта мешаванд ва иртиботи онҳо бо асос тавассути майдони навъи иттифоқ муайян карда мешавад. Мазмуни воқеии иттиҳодия тавассути атрибути техникии намуд муайян карда мешавад.

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. Барои амалиёти танҳо барои хондан, нишондод ба сохтори арзиш кафолат дода мешавад, ки танҳо то баста шудани транзаксия эътибор дорад. Тавре ки қаблан зикр гардид, саҳифаҳои дарахти В, ки объект дар он ҷойгир аст, ба туфайли принсипи нусхабардорӣ дар навиштан, то даме ки ҳадди аққал як транзаксия ба онҳо дахл дорад, бетағйир мемонанд. Ҳамзамон, ҳамин ки амалиёти охирини марбут ба онҳо анҷом ёфт, саҳифаҳоро барои маълумоти нав дубора истифода бурдан мумкин аст. Агар зарур бошад, ки объектҳо аз муомилае, ки онҳоро офаридааст, зинда монад, пас онҳо бояд ба ҳар ҳол нусхабардорӣ карда шаванд.
  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 директорияи волидайнашон фармоиш дода шаванд. Ҳамин тариқ, аз ҷиҳати техникӣ, вазифаи ба даст овардани мундариҷаи ҷузвдон то ҷойгир кардани курсор дар сарҳади болоии гурӯҳи калидҳо бо префикси додашуда ва пас аз такрор ба сарҳади поёнӣ кам карда мешавад.

Равшанӣ ва камбизоатии пойгоҳи додаҳои калидӣ-арзиши LMDB дар замимаҳои iOS

Шумо метавонед сарҳади болоии "дар пешонӣ" -ро тавассути ҷустуҷӯи пайдарпай пайдо кунед. Барои ин курсор дар аввали тамоми рӯйхати калидҳо дар базаи маълумот ҷойгир карда мешавад ва сипас то он даме, ки калид бо идентификатори директорияи волидайн дар зер пайдо шавад, афзоиш меёбад. Ин равиш ду камбудии ошкоро дорад:

  1. Мушкилии хаттии ҷустуҷӯ, гарчанде ки шумо медонед, дар маҷмӯъ дар дарахтон ва махсусан дар дарахти B, он метавонад дар вақти логарифмӣ анҷом дода шавад.
  2. Беҳуда, ҳамаи саҳифаҳои пеш аз саҳифаи дилхоҳ аз файл ба хотираи асосӣ бардошта мешаванд, ки ин хеле гарон аст.

Хушбахтона, API-и LMDB роҳи самараноки ҷойгиркунии курсорро пешкаш мекунад.Барои ин, шумо бояд калидеро ташкил кунед, ки арзиши он аз калиди дар ҳудуди болоии фосила ҷойгиршуда камтар ё баробар аст. Масалан, дар робита ба рӯйхат дар расми боло, мо метавонем калидеро, ки дар он майдон ҷойгир аст, созем 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. Моделсозии муносибатҳои байни ҷадвалҳо

То имрӯз, мо тавонистем, ки тамоми ҷанбаҳои тарҳрезӣ ва кор бо базаи як ҷадвалро баррасӣ кунем. Мо гуфта метавонем, ки ҷадвал маҷмӯи сабтҳои мураттабшуда мебошад, ки аз ҷуфтҳои калид-арзишҳои як навъ иборат аст. Агар шумо калидро ҳамчун росткунҷа ва арзиши алоқаманди онро ҳамчун қуттӣ нишон диҳед, шумо диаграммаи визуалии пойгоҳи додаҳоро мегиред.

"Озодӣ" дар мобил

Равшанӣ ва камбизоатии пойгоҳи додаҳои калидӣ-арзиши LMDB дар замимаҳои iOS

Бо вуҷуди ин, дар ҳаёти воқеӣ бо хуни кам ба даст овардан хеле кам имконпазир аст. Аксар вақт дар базаи маълумотҳо, аввалан, доштани якчанд ҷадвалҳо ва дуюм, дар онҳо бо тартиби аз калиди ибтидоӣ фарқкунанда анҷом додани интихобҳо талаб карда мешавад. Ин бахши охирин ба масъалаҳои эҷод ва пайвастагии онҳо бахшида шудааст.

Ҷадвалҳои индекс

Барномаи абрӣ бахши "Галерея" дорад. Он мундариҷаи медиаро аз тамоми абр, ки аз рӯи сана мураттаб шудаанд, нишон медиҳад. Барои татбиқи оптималии чунин интихоб, дар паҳлӯи ҷадвали асосӣ, шумо бояд дигареро бо навъи нави калидҳо эҷод кунед. Онҳо майдонеро дар бар мегиранд, ки санаи эҷоди файлро дорад, ки ҳамчун меъёри асосии ҷудокунӣ амал мекунад. Азбаски калидҳои нав ба ҳамон маълумоте, ки калидҳои ҷадвали асосӣ доранд, ишора мекунанд, онҳо калидҳои индекс номида мешаванд. Онҳо дар расми зер бо ранги норанҷӣ нишон дода шудаанд.

Равшанӣ ва камбизоатии пойгоҳи додаҳои калидӣ-арзиши LMDB дар замимаҳои iOS

Барои аз ҳам ҷудо кардани калидҳои ҷадвалҳои гуногун дар дохили як пойгоҳи додаҳо, ба ҳамаи онҳо tableId майдони иловагии техникӣ илова карда шудааст. Бо афзалияти баландтарин барои навъбандӣ, мо калидҳоро аввал аз рӯи ҷадвалҳо гурӯҳбандӣ мекунем ва аллакай дар дохили ҷадвалҳо - мувофиқи қоидаҳои худамон.

Калиди индекс ба ҳамон маълумоте, ки калиди ибтидоӣ дорад, ишора мекунад. Татбиқи бевоситаи ин амвол тавассути пайваст кардани нусхаи қисми арзиши калиди ибтидоӣ аз якчанд нуқтаи назар якбора ғайриоддӣ аст:

  1. Аз нуқтаи назари фазои ишғол, метамаълумот метавонад хеле бой бошад.
  2. Аз нуқтаи назари кор, зеро ҳангоми навсозии метамаълумоти гиреҳ, шумо бояд ду калидро аз нав нависед.
  3. Аз нуқтаи назари дастгирии код, дар ниҳоят, агар мо навсозии маълумотро барои яке аз калидҳо фаромӯш кунем, мо хатои нозуки номутобиқатии маълумотро дар анбор мегирем.

Минбаъд мо дида мебароем, ки ин камбудихоро чй тавр бартараф кунем.

Ташкили муносибатҳои байни ҷадвалҳо

Намуна барои пайваст кардани ҷадвали индекс бо ҷадвали асосӣ мувофиқ аст "калид ҳамчун арзиш". Тавре ки аз номаш бармеояд, қисми арзиши сабти индекс нусхаи арзиши асосии калидӣ мебошад. Ин равиш ҳама камбудиҳои дар боло номбаршударо, ки бо нигоҳ доштани нусхаи арзиши қисми сабти ибтидоӣ алоқаманданд, бартараф мекунад. Ягона пардохт ин аст, ки барои ба даст овардани арзиш аз рӯи калиди индекс, шумо бояд ба пойгоҳи додаҳо ба ҷои як дархост 2 дархост кунед. Ба таври схематикӣ, схемаи пойгоҳи додаҳо чунин аст.

Равшанӣ ва камбизоатии пойгоҳи додаҳои калидӣ-арзиши LMDB дар замимаҳои iOS

Намунаи дигари ташкили муносибатҳои байни ҷадвалҳо ин аст "калиди зиёдатӣ". Моҳияти он илова кардани атрибутҳои иловагӣ ба калид аст, ки на барои навъбандӣ, балки барои аз нав сохтани калиди алоқаманд лозиманд.Аммо дар замимаи Mail.ru Cloud мисолҳои воқеии истифодаи он вуҷуд доранд, то ба он ғарқ нашавед. дар заминаи чаҳорчӯбаҳои мушаххаси iOS, ман як мисоли афсонавӣ, вале фаҳмотар медиҳам.

Мизоҷони мобилии абрӣ саҳифае доранд, ки ҳамаи файлҳо ва ҷузвдонҳоеро, ки корбар бо одамони дигар мубодила кардааст, нишон медиҳад. Азбаски чунин файлҳо нисбатан каманд ва дар бораи таблиғоти бо онҳо алоқаманд маълумоти зиёди мушаххас вуҷуд дорад (ба кӣ дастрасӣ дорад, бо кадом ҳуқуқҳо ва ғайра), ба он бор кардан бо қисми арзиши файлҳо оқилона нест. сабт дар ҷадвали асосӣ. Аммо, агар шумо хоҳед, ки ин гуна файлҳоро офлайн нишон диҳед, пас шумо бояд ба ҳар ҳол онро дар ҷое нигоҳ доред. Як ҳалли табии он аст, ки барои он ҷадвали алоҳида эҷод кунед. Дар диаграммаи зер калиди он бо пешванди "P" гузошта шудааст ва ҷойнишини "propname" метавонад бо арзиши мушаххастари "маълумоти ҷамъиятӣ" иваз карда шавад.

Равшанӣ ва камбизоатии пойгоҳи додаҳои калидӣ-арзиши LMDB дар замимаҳои iOS

Ҳама метамаълумоти беназир, ки ба хотири онҳо ҷадвали нав сохта шудааст, ба қисми арзиши сабт интиқол дода мешавад. Дар айни замон ман намехоҳам маълумотро дар бораи файлҳо ва ҷузвдонҳое, ки аллакай дар ҷадвали асосӣ нигоҳ дошта мешаванд, такрор кунам. Ба ҷои ин, маълумоти зиёдатӣ ба калиди "P" дар шакли майдонҳои "ID гиреҳ" ва "тамғаи вақт" илова карда мешавад. Ба шарофати онҳо, шумо метавонед калиди индексро созед, ки тавассути он шумо калиди ибтидоиро ба даст оварда метавонед, ки дар ниҳоят метамаълумоти гиреҳро ба даст оред.

Хулоса

Мо ба натиҷаҳои татбиқи LMDB мусбат баҳо медиҳем. Пас аз он, шумораи яхкунии барномаҳо 30% кам шуд.

Равшанӣ ва камбизоатии пойгоҳи додаҳои калидӣ-арзиши LMDB дар замимаҳои iOS

Натичахои кори ичрошуда берун аз командаи iOS чавоб пайдо карданд. Дар айни замон, яке аз бахшҳои асосии "Файлҳо" дар замимаи Android низ ба истифодаи LMDB гузаштааст ва қисматҳои дигар дар роҳ ҳастанд. Забони Си, ки дар он нигаҳдории арзишҳои калидӣ амалӣ карда мешавад, кӯмаки хубе буд, то дар аввал барномаро дар атрофи платформаи кросс-платформа дар забони C ++ пайваст кунад. Барои пайвасти бефосилаи китобхонаи C++ бо рамзи платформа дар Objective-C ва Kotlin, генератори код истифода шуд Ҷиннӣ аз Dropbox, аммо ин як ҳикояи дигар аст.

Манбаъ: will.com

Илова Эзоҳ