Hlavní navigace

GLib: Kvarky

Michal Burda

Kvarky (Quarks) je nástroj umožňující oboustranné spojení řetězce s jednoznačnou přirozenou konstantou. Znáte-li řetězec, lze z něj určit jeho číslo a naopak, z konstanty můžete získat odpovídající řetězec.

Motivace aneb vykonstruovaný příklad ne nepodobný klíčovaným seznamům dat knihovny GLib

Představte si, že máte v paměti nějaký seznam dat, jejichž prvkem je mimo jiné i jakýsi klíč, který je v podstatě jen nějaký řetězec, a že tento seznam velmi často prohledáváte. Porovnání jedné položky s hledaným klíčem tedy znamená porovnávat řetězce – a to není zrovna dvakrát efektivní. Jak algoritmus zrychlit?

Pokud říkáte, že použijete hash tabulku, máte patrně pravdu. Co když ale takových seznamů budete mít desítky nebo stovky a každý bude udržovat jen několik málo záznamů?

Potřebujeme se přece zbavit jen zdlouhavého porovnávání řetězců. Co kdyby existoval způsob, jak řetězec „přeložit“ na číselnou konstantu, se kterou pracovat by už byla jedna radost? – Přesně k tomu jsou kvarky (quarks).

Co jsou to kvarky

Kvarky je mechanizmus obousměrné asociace mezi řetězcem a jednoznačným přirozeným kladným číslem. Máte-li k dispozici číselnou konstantu, můžete z ní odvodit přiřazený řetězec a naopak, podle řetězce lze zjistit jeho identifikační čís­lo.

Kvarky jsou tedy jakési dvojice řetězec – přirozené číslo.

Jednoznačné integerové konstantě je přiřazen speciální typ – GQuark. Jeho přesná definice zní:

typedef guint32 GQuark;

Kvůli maximální rychlosti jsou kvarky vnitřně v paměti uchovávány nadvakrát. Pro snazší konverzi z řetězce na číslo se ukládají do hash tabulky a pro převod z  GQuark u na řetězec do pole řetězců, jehož indexem je právě ona jednoznačná celočíselná konstanta.

V celém programu je vždy jen jedno pole a jedna hash tabulka uchovávající všechny kvarky. Knihovna GLib si pro tyto účely (a není to poprvé ani naposled) zakládá vnitřní globální pole a hash tabulku, ke kterým není z vnějšku přístup.

Kvarky se používají při práci s některými dalšími mechanizmy knihovny GLib, o kterých bude řeč v příštích článcích. Konkrétně to jsou klíčované seznamy dat (Keyed Data Lists) a soupravy dat (Datasets).

Patrně by se dalo přijít i na další způsoby použití, nedomnívám se ale, že samostatné kvarky budete používat příliš často. Jejich nevýhodu spatřuji v tom, že nemáte kontrolu nad tím, jak se číselné konstanty řetězcům přiřazují. Je to sice popořadě vzestupně (1, 2, 3 atd.), nemůžete však explicitně přikázat, který řetězec má mít jaké číslo. Při troše smůly to může být při každém spuštění programu něco jiného. Ve většině případů si jistě vystačíte s klasickými konstantami a makry preprocesoru.

Práce s  GQuark y

GQuark g_quark_from_string(const gchar *string); 

…vrátí GQuark (jednoznačnou číselnou konstantu) řetězce string. Jestliže daný řetězec nemá ještě přiřazen žádný GQuark, vytvoří se nový kvark s kopií řetězce string (podrobněji: kopie řetězce string se uloží do výše zmíněného pole a hash tabulky). S původním string em si potom můžete dělat co chcete – asociace s kvarkem se nijak nenaruší.

GQuark g_quark_from_static_string(const gchar *string); 

…vrátí GQuark identifikující řetězec string. Jestliže string ještě není asociován s žádným GQuark em, vytvoří se nová dvojice s použitím řetězce string přímo. Do pole a hash tabulky se uloží rovnou řetězec string. Šetří se tím paměť, musíte však zaručit, že string bude existovat po celou dobu běhu programu (např. statický řetězec).

gchar* g_quark_to_string(GQuark quark); 

…vrátí řetězec, který je asociovaný s daným GQuark em quark. Pozor! S vráceným řetězcem byste měli pracovat obezřetně a používat ho raději jen ke čtení, protože je uložen přímo v poli i hash tabulce kvarků.

GQuark g_quark_try_string(const gchar *string); 

Tato funkce se pokusí najít GQuark asociovaný s řetezcem string. V případě úspěchu jej použije jako návratovou hodnotu. Nemá-li string asociovaný ještě žádný GQuark, vrátí 0. Tuto funkci použijte, chcete-li zjistit, jestli už je řetězec string „očíslován“. Chcete-li, aby byla v případě nenalezení GQuark u vytvořena nová asociace, použijte raději funkci g_quark_from_string() nebo  g_quark_from_static_string().

Jelikož kvarky existují po celou dobu běhu programu a není možné je nijak zničit, s jejich dealokováním si nelamte hlavu. Obstará to za vás operační systém při ukončení aplikace.

Příklad:

/* Priklad pouziti GQuark */
#include <glib.h>
/* Nejaka struktura (uchovava pohlavi a vek) */
typedef struct {
  GQuark sex;
  guint age;
} MyStruct;

gint main(void)
{
  MyStruct item1, item2, item3;
  GQuark male, female;
  gchar *female_str;

  /* Vytvoreni kvarku ze statickeho retezce */
  male = g_quark_from_static_string("Male");

  /* Vytvoreni kvarku z dynamickeho retezce */
  female_str = g_strdup("Female");
  female = g_quark_from_string(female_str);
  g_free(female_str);

  /* Pouziti kvarku */
  item1.sex = male;
  item2.sex = g_quark_from_string("Male");
    /* (hodnoty item1.sex i item2.sex se rovnaji) */
  item3.sex = g_quark_from_string("Female");

  /* Ziskani retezce z kvarku */
  printf("item1 ma pohlavi: %s\n", g_quark_to_string(item1.sex));
  printf("item2 ma pohlavi: %s\n", g_quark_to_string(item2.sex));
  printf("item3 ma pohlavi: %s\n", g_quark_to_string(item3.sex));
}

Uvedený příklad by měl po spuštění vypsat:

item1 ma pohlavi: Male
item2 ma pohlavi: Male
item3 ma pohlavi: Female

Tímto máme „předsíň“ ke klíčovaným seznamům a soupravám dat za sebou. V příštím díle se do nich pustíme a GQuark y s úspěchem použijeme.

Našli jste v článku chybu?
Vitalia.cz: Taky věříte na pravidlo 5 sekund?

Taky věříte na pravidlo 5 sekund?

Měšec.cz: Sleva na dítě a manželku pro OSVČ je zpět. Ale..

Sleva na dítě a manželku pro OSVČ je zpět. Ale..

120na80.cz: 5 nejčastějších mýtů o kondomech

5 nejčastějších mýtů o kondomech

Podnikatel.cz: Přehledná titulka, průvodci, responzivita

Přehledná titulka, průvodci, responzivita

Lupa.cz: Kdo pochopí vtip, může jít do ČT vyvíjet weby

Kdo pochopí vtip, může jít do ČT vyvíjet weby

Vitalia.cz: Paštiky plné masa ho zatím neuživí

Paštiky plné masa ho zatím neuživí

120na80.cz: Co všechno ovlivňuje ženskou plodnost?

Co všechno ovlivňuje ženskou plodnost?

Vitalia.cz: Pamlsková vyhláška bude platit jen na základkách

Pamlsková vyhláška bude platit jen na základkách

Vitalia.cz: Jmenuje se Janina a žije bez cukru

Jmenuje se Janina a žije bez cukru

Podnikatel.cz: Udávání kvůli EET začalo

Udávání kvůli EET začalo

120na80.cz: Pánové, pečujte o svoje přirození a prostatu

Pánové, pečujte o svoje přirození a prostatu

Vitalia.cz: Mondelez stahuje rizikovou čokoládu Milka

Mondelez stahuje rizikovou čokoládu Milka

Vitalia.cz: Spor o mortadelu: podle Lidlu falšovaná nebyla

Spor o mortadelu: podle Lidlu falšovaná nebyla

Měšec.cz: Jak vymáhat výživné zadarmo?

Jak vymáhat výživné zadarmo?

Podnikatel.cz: Udávání a účtenková loterie, hloupá komedie

Udávání a účtenková loterie, hloupá komedie

Vitalia.cz: Nejlepší obranou při nachlazení je útok

Nejlepší obranou při nachlazení je útok

Vitalia.cz: Jsou čajové sáčky toxické?

Jsou čajové sáčky toxické?

Vitalia.cz: Láska na vozíku: Přitažliví jsme pro tzv. pečovatelky

Láska na vozíku: Přitažliví jsme pro tzv. pečovatelky

Podnikatel.cz: Chtějte údaje k dani z nemovitostí do mailu

Chtějte údaje k dani z nemovitostí do mailu

Root.cz: Certifikáty zadarmo jsou horší než za peníze?

Certifikáty zadarmo jsou horší než za peníze?