2.2.1 Nimeämismalli
On hyödyllistä, että meillä on malli siitä, miten nimet liittyvät tiettyihin objekteihin. Järjestelmäsuunnittelija luo nimeämismallin, joka koostuu kolmesta elementistä. Ensimmäinen elementti on nimiavaruus, joka koostuu symbolien aakkosista sekä syntaksisäännöistä, jotka määrittelevät, mitkä nimet ovat hyväksyttäviä. Toinen elementti on nimikartta-algoritmi, joka yhdistää joitakin (ei välttämättä kaikkia) nimiavaruuden nimiä joihinkin (ei taas välttämättä kaikkiin) arvoihin arvojen universumissa, joka on nimeämissuunnitelman kolmas ja viimeinen elementti. Arvo voi olla objekti tai se voi olla toinen nimi joko alkuperäisestä nimiavaruudesta tai jostain muusta nimiavaruudesta. Nimen ja arvon yhdistäminen on esimerkki sidonnasta, ja kun tällainen yhdistäminen on olemassa, nimen sanotaan olevan sidottu arvoon. Kuva 2.10 havainnollistaa.
Useimmissa järjestelmissä on tyypillisesti käytössä samanaikaisesti useita eri nimeämisjärjestelmiä. Järjestelmä voi esimerkiksi käyttää yhtä nimeämissuunnitelmaa sähköpostilaatikoiden nimiin, toista nimeämissuunnitelmaa Internet-isäntien nimiin, kolmatta tiedostojen nimiin ja neljättä virtuaalimuistiosoitteisiin. Kun ohjelman tulkki kohtaa nimen, sen on tiedettävä, mitä nimeämisjärjestelmää se käyttää. Nimen käyttöä ympäröivä ympäristö antaa yleensä riittävästi tietoa nimeämisjärjestelmän tunnistamiseksi. Esimerkiksi sovellusohjelmassa ohjelman tekijä tietää, että ohjelman pitäisi odottaa, että tiedostojen nimiä tulkitsee vain tiedostojärjestelmä ja Internet-isäntien nimiä vain jokin verkkopalvelu.
Nimen kohtaava tulkki suorittaa sopivan nimeämisjärjestelmän nimikartoitusalgoritmin. Nimikartoitusalgoritmi ratkaisee nimen, mikä tarkoittaa, että se löytää ja palauttaa siihen liittyvän arvon (tästä syystä nimikartoitusalgoritmia kutsutaan myös resolveriksi). Nimenmuodostusalgoritmia ohjataan yleensä lisäparametrilla, jota kutsutaan kontekstiksi. Tietylle nimijärjestelmälle voi olla useita eri konteksteja, ja nimiavaruuden yksi nimi voi vastata eri arvoja, kun resolveri käyttää eri konteksteja. Esimerkiksi tavallisessa keskustelussa, kun henkilö viittaa nimiin “sinä”, “täällä” tai “Alice”, kunkin nimen merkitys riippuu kontekstista, jossa henkilö sanoo sen. Toisaalta joillakin nimitysjärjestelmillä on vain yksi konteksti. Tällaiset nimijärjestelmät tarjoavat niin sanottuja universaaleja nimiavaruuksia, ja niillä on se mukava ominaisuus, että nimellä on aina sama merkitys kyseisessä nimijärjestelmässä riippumatta siitä, kuka sitä käyttää. Esimerkiksi Yhdysvalloissa sosiaaliturvatunnukset, joilla tunnistetaan valtion eläke- ja verotilit, muodostavat universaalin nimiavaruuden. Kun on olemassa useampi kuin yksi konteksti, tulkki voi kertoa resolverille, mitä kontekstia sen pitäisi käyttää, tai resolveri voi käyttää oletuskontekstia.
Voidaan tiivistää nimeämismalli määrittelemällä seuraava käsitteellinen operaatio nimille:
arvo ← resolve (nimi, konteksti)
Kun tulkki kohtaa nimen objektissa, se selvittää ensin, mikä nimeämismalli on kyseessä, ja näin ollen, mitä versiota resoluutiosta sen pitäisi käyttää. Sen jälkeen se tunnistaa sopivan kontekstin, ratkaisee nimen kyseisessä kontekstissa ja korvaa nimen ratkaistulla arvolla jatkaessaan tulkintaa. Muuttuja context kertoo resoluutiolle, mitä kontekstia käyttää. Kyseinen muuttuja sisältää nimen, jota kutsutaan kontekstiviitteeksi.
Prosessorissa rekisterinumerot ovat nimiä. Yksinkertaisessa prosessorissa rekisterinimien joukko ja rekisterit, joihin nämä nimet on sidottu, ovat molemmat kiinteitä suunnitteluhetkellä. Useimmissa muissa nimiä käyttävissä järjestelmissä (mukaan lukien joidenkin suuritehoisten prosessoreiden rekisterien nimeämisjärjestelmä) on mahdollista luoda uusia sidontoja ja poistaa vanhoja, luetella nimiavaruus saadakseen luettelon olemassa olevista sidonnoista ja vertailla kahta nimeä. Näitä tarkoituksia varten määrittelemme neljä muuta käsitteellistä operaatiota:
status ← bind (nimi, arvo, konteksti)
status ← unbind (nimi, konteksti)
list ← enumerate (konteksti)
result ← compare (nimi1, nimi2)
Ensimmäinen operaatio vaihtaa kontekstia lisäämällä uuden sidoksen; tilatulos ilmoittaa, onnistuiko muutos vai ei (se voi epäonnistua, jos ehdotettu nimi rikkoo nimiavaruuden syntaksisääntöjä). Onnistuneen bind-kutsun jälkeen resolve palauttaa uuden arvon nimelle.*Toinen operaatio, unbind, poistaa olemassa olevan sidoksen kontekstista, ja status ilmoittaa jälleen onnistumisesta tai epäonnistumisesta (ehkä siksi, että tällaista olemassa olevaa sidosta ei ollut). Onnistuneen unbind-kutsun jälkeen resolve ei enää palauta kyseistä arvoa nimelle. Bind- ja unbind-operaatiot mahdollistavat nimien käytön objektien välisten yhteyksien luomiseen ja näiden yhteyksien muuttamiseen myöhemmin. Käyttämällä nimeä viittaamaan komponenttiobjektiin objektin suunnittelija voi valita objektin, johon nimi on sidottu joko silloin tai myöhemmin kutsumalla bind-operaatiota, ja poistaa sidonnan, joka ei ole enää sopiva, kutsumalla unbind-operaatiota, muuttamatta nimeä käyttävää objektia. Tämä kyky viivyttää ja muuttaa sidontoja on tehokas työkalu, jota käytetään lähes kaikkien järjestelmien suunnittelussa. Jotkin nimeämistoteutukset tarjoavat enumerate-operaation, joka palauttaa luettelon kaikista nimistä, jotka voidaan ratkaista kontekstissa. Jotkin enumerate-toteutukset voivat myös palauttaa luettelon kaikista tällä hetkellä kontekstissa sidotuista arvoista. Lopuksi compare-operaatio ilmoittaa (true tai false), onko nimi1 sama kuin nimi2. “Saman” merkitys on mielenkiintoinen kysymys, jota käsitellään luvussa 2.2.5, ja se saattaa vaatia lisäargumenttien antamista kontekstissa.
Eroilla nimijärjestelmillä on erilaiset säännöt nimi-arvo-sovitusten yksikäsitteisyydestä. Joissakin nimeämisjärjestelmissä on sääntö, jonka mukaan nimen on vastattava täsmälleen yhtä arvoa tietyssä kontekstissa ja arvolla saa olla vain yksi nimi, kun taas toisissa nimeämisjärjestelmissä yksi nimi voi vastata useita arvoja tai yhdellä arvolla voi olla useita nimiä, jopa samassa kontekstissa. Toisenlainen yksikäsitteisyyssääntö on yksilöllisen tunnisteen nimiavaruus, joka tarjoaa joukon nimiä, joita ei koskaan käytetä uudelleen nimiavaruuden koko elinkaaren aikana ja jotka, kun ne on kerran sidottu, pysyvät aina sidottuina samaan arvoon. Tällaisella nimellä sanotaan olevan vakaa sidonta. Jos yksilöllisen tunnisteen nimiavaruudessa on myös sääntö, jonka mukaan arvolla voi olla vain yksi nimi, yksilöllisistä nimistä on hyötyä objektien seurannassa pitkän ajan kuluessa, viittausten vertailussa sen selvittämiseksi, viittaavatko ne samaan objektiin, ja useiden kopioiden koordinoinnissa järjestelmissä, joissa objekteja kopioidaan suorituskyvyn tai luotettavuuden vuoksi. Esimerkiksi useimpien laskutusjärjestelmien asiakastilin numero muodostaa yksilöllisen tunnistenimiavaruuden. Tilinumero viittaa aina samaan asiakastiliin niin kauan kuin tili on olemassa, vaikka asiakkaan osoitteessa, puhelinnumerossa tai jopa henkilökohtaisessa nimessä tapahtuisi muutoksia. Jos asiakkaan tili poistetaan, kyseisen asiakkaan tilinumeroa ei voida jonain päivänä käyttää uudelleen toisen asiakkaan tilille. Tilin sisällä olevat nimikentät, kuten erääntynyt saldo, voivat muuttua aika ajoin, mutta sidonnaisuus asiakkaan tilinumeron ja itse tilin välillä on vakaa.
Nimikartoitusalgoritmi sekä yksittäinen konteksti eivät välttämättä kartoita kaikkia nimiavaruuden nimiä arvoiksi. Näin ollen resoluution suorittamisen mahdollinen lopputulos voi olla ei löydy -tulos, jonka resoluutio voi ilmoittaa kutsujalle joko varattuna arvona tai poikkeuksena. Toisaalta, jos nimijärjestelmä sallii yhden nimen yhdistämisen useisiin arvoihin, mahdollinen lopputulos voi olla luettelo arvoista. Tällöin unbind-operaatio voi vaatia lisäargumentin, joka määrittää, mikä arvo irrotetaan. Lopuksi jotkin nimeämisjärjestelmät mahdollistavat käänteisen haun, mikä tarkoittaa, että kutsuja voi antaa arvon argumenttina nimikartoitusalgoritmille ja selvittää, mikä nimi tai mitkä nimet on sidottu kyseiseen arvoon.
Kuvassa 2.10 on esitetty nimeämismalli, jossa näkyy nimiavaruus, vastaava arvojen universumi, nimikartoitusalgoritmi ja konteksti, joka ohjaa nimikartoitusalgoritmia.
Käytännössä törmää kolmeen usein käytettyyn nimikartoitusalgoritmiin:
Taulukkohaku
■
Rekursiivinen haku
■
Moninkertainen haku
Yleisimmin käytetty konteksti on taulukko, jossa on {nimi, arvo}-parit. Kun kontekstin toteutus on taulukko, nimikartoitusalgoritmi on vain nimen haku kyseisestä taulukosta. Itse taulukko voi olla monimutkainen, sisältäen hashingia tai B-puita, mutta perusajatus on silti sama. Uuden nimen sitominen arvoon koostuu kyseisen {nimi, arvo}-parin lisäämisestä taulukkoon. Kuva 2.11 havainnollistaa tätä yleistä nimimallin toteutusta. Jokaista kontekstia varten on yksi tällainen taulukko, ja eri kontekstit voivat sisältää erilaisia sidontoja samalle nimelle.
Reaalimaailman esimerkkejä sekä yleisestä nimeämismallista että taulukkohakutoteutuksesta on runsaasti:
Puhelinluettelo on taulukkohakukonteksti, joka sitoo henkilöiden ja organisaatioiden nimet puhelinnumeroihin. Kuten tietoliikenneverkkoesimerkissä, puhelinnumerot ovat itse nimiä, jotka puhelinyhtiö ratkaisee fyysisiksi linjatunnuksiksi käyttämällä nimikartoitusalgoritmia, johon liittyy suuntanumeroita, keskuksia ja fyysisiä kytkinlaitteita. Bostonin ja San Franciscon puhelinluettelot ovat kaksi saman nimijärjestelmän kontekstia; jokin tietty nimi voi esiintyä molemmissa puhelinluetteloissa, mutta jos näin on, se on todennäköisesti sidottu eri puhelinnumeroihin.
Pienet kokonaisluvut nimeävät prosessorin rekisterit. Arvo on itse rekisteri, ja yhdistäminen nimestä arvoon tapahtuu johdotuksen avulla.
Muistisolut nimetään samalla tavalla numeroilla, joita kutsutaan osoitteiksi, ja yhdistäminen nimestä arvoon tapahtuu jälleen johdotuksen avulla. Luvussa 5 kuvataan virtuaalimuistiksi kutsuttu osoitteiden uudelleen nimeämismekanismi, joka sitoo virtuaaliosoitteiden lohkoja vierekkäisten muistisolujen lohkoihin. Kun järjestelmä toteuttaa useita virtuaalimuisteja, jokainen virtuaalimuisti on erillinen konteksti; tietty osoite voi viitata eri muistisoluun kussakin virtuaalimuistissa. Muistisoluja voidaan myös jakaa virtuaalimuistien kesken, jolloin samalla muistisolulla voi olla samat (tai eri) osoitteet eri virtuaalimuisteissa, kuten sidonnat määräävät.
Tyypillisessä tietokoneen tiedostojärjestelmässä käytetään useita nimi- ja kontekstikerroksia: levysektorit, levyosiot, tiedostot ja hakemistot ovat kaikki nimettyjä objekteja. Hakemistot ovat esimerkkejä taulukkokonteksteista. Tietyn tiedoston nimi voi esiintyä useissa eri hakemistoissa, jotka on sidottu joko samoihin tai eri tiedostoihin. Luvussa 2.5 esitellään tapaustutkimus nimeämisestä unix-tiedostojärjestelmässä.
Tietokoneet kytkeytyvät tietoliikenneverkkoihin paikoissa, joita kutsutaan verkon liitäntäpisteiksi. Verkon liitäntäpisteet nimetään yleensä kahdella eri nimeämisjärjestelmällä. Ensimmäisessä, verkon sisällä käytettävässä, käytetään nimiavaruutta, joka koostuu kiinteäpituisessa kentässä olevista numeroista. Nämä nimet on sidottu, joskus pysyvästi ja joskus vain lyhytaikaisesti, verkon fyysisiin tulo- ja lähtöpisteisiin. Toisessa, verkon asiakkaiden käyttämässä nimijärjestelmässä ensimmäisen nimiavaruuden nimiin liitetään käyttäjäystävällisempi merkkijonojen universaali nimiavaruus. Luvussa 4.4 tarkastellaan tapauskohtaisesti verkkotunnusjärjestelmää, joka tarjoaa käyttäjäystävällisen kiinnityspisteiden nimeämisen Internetissä.
Ohjelmoija yksilöi proseduurimuuttujat nimillä, ja jokainen proseduurin aktivointi tarjoaa erillisen kontekstin, jossa useimmat tällaiset nimet ratkaistaan. Jotkin “staattisina” tai “globaaleina” niminä tunnetut nimet voidaan sen sijaan ratkaista kontekstissa, joka on jaettu aktivointien tai eri proseduurien kesken. Kun proseduuri käännetään, osa muuttujien alkuperäisistä käyttäjäystävällisistä nimistä saatetaan korvata kokonaislukutunnisteilla, joita koneen on helpompi käsitellä, mutta nimeämismalli on edelleen voimassa.
World Wide Webin URL-osoite (Uniform Resource Locator) yhdistetään tiettyyn Web-sivuun suhteellisen monimutkaisella algoritmilla, joka pilkkoo URL-osoitteen useisiin osiin ja ratkaisee osat eri nimeämissuunnitelmien avulla; lopputulos tunnistaa lopulta tietyn Web-sivun. Luku 3.2 on tapaustutkimus tästä nimeämissuunnitelmasta.
Asiakaslaskutusjärjestelmässä ylläpidetään tyypillisesti vähintään kahdenlaisia nimiä kutakin asiakastiliä varten. Tilinumero nimeää tilin yksilöllisessä tunnistenimiavaruudessa, mutta on olemassa myös erillinen henkilökohtaisten nimien nimiavaruus, jota voidaan myös käyttää tilin tunnistamiseen. Molemmat näistä nimistä on tyypillisesti yhdistetty tilitietueisiin tietokantajärjestelmässä, jotta tilit voidaan hakea joko tilinumeron tai henkilökohtaisen nimen perusteella.
Näissä esimerkeissä korostuu myös ero “nimeämisen” ja sitomisen välillä. Jotkin, mutta eivät kaikki, asiayhteydet “nimeävät” asioita siinä mielessä, että ne yhdistävät nimen objektiin, jolla yleisesti ajatellaan olevan kyseinen nimi. Puhelinluettelo ei siis “nimeä” ihmisiä eikä puhelinlinjoja. Jossain muualla on konteksteja, jotka sitovat nimet ihmisiin ja jotka sitovat puhelinnumerot tiettyihin fyysisiin puhelimiin. Puhelinluettelo sitoo ihmisten nimet puhelimien nimiin.