Moje zdjęcie
Uczeń LO im. Ma­­ła­chow­skie­go w Płoc­ku. Lubi czy­tać książ­ki. Ma du­żo po­my­słów, jed­nak za­zwy­czaj ma­ło chę­ci lub nie­do­bór umie­jęt­no­ści na ich re­ali­za­cję. In­te­re­su­je się pro­gra­mo­wa­niem. Bie­rze udział w kon­kur­sie po to aby na­uczyć się cze­goś no­we­go. Ocze­ku­je na kon­struk­tyw­ną kry­ty­kę.

piątek, 17 września 2010

105: System tagów

Po dłuższej przerwie nastąpiła ostatnia szansa na zwarcie szyków i poświęcenie większości uwagi na rozwoju projektu konkursowego. W ramach tego zadania postanowiłem dokończyć system bazy danych maksymalnie w dwa tygodnie. Biorąc pod uwagę fakt, że system tagów powstał w trzy dni, wszystko wskazuje na to, że mi się uda i być może pod koniec przyszłego tygodnia zajmę się dużo bardziej ekscytującą częścią - interfejsem. Jeżeli jednak chodzi o tagi...

Rev 9

Obecna wersja systemu tagów powstawała w trzech revach. Mówię obecna, ponieważ nie jest ona ostatnią, gdyż wciąż nie ma obiecywanego dostosowania starego pomysłu do nowej struktury. Pojawi się ono później, prawdopodobnie podczas prac na GUI. Nie ma także możliwości usunięcia tagu - zostanie dodana niedługo. Wracając do wersji obecnej, poświęcone jej wprowadzaniu zostały wersje 9, 10 i 11.

W pierwszej z nich nieco wyczyściłem kod. Wyrzuciłem wersję indeksową, gdyż była zdecydowanie wolniejsza na dużych porcjach danych, natomiast na mniejszych różnica była niemal niezauważalna. Nie widziałem sensu dalszego rozwijania dwóch wersji, a wskaźnikowa po prostu jest przyjemniejsza w kodowaniu.

Jeżeli zaś chodzi o system tagów, to w tej rewizji powstał jego zalążek: klasa db::Tag, zawierająca łańcuch będący nazwą tagu oraz wektor wskaźników na wpisy, odpowiedzialny za przechowywanie wszystkich wystąpień etykiety. Klasa ta została wyposażona w niektóre operatory porównania (ostre nierówności i równość), aby umożliwić przeszukiwanie tabeli tagów przy pomocy wyszukiwania binarnego. Natomiast do klasy db::Base dodałem wektor przechowujący wszystkie tagi - jednak póki co bez możliwości ich dodawania.

Rev 10

Wraz z dziesiątą rewizją powstała metoda klasy db::Base będąca esencją całego systemu tagów. Chodzi o metodę Tag* db::Base::getTag(string name), która dla zadanego łańcucha zwraca wskaźnik do obiektu typu db::Tag. Jak ona działa?

Tag* Base::getTag(string tag)
{
  int p = 0, r = Tags.size()-1, q;
  while (p != r)
  {
    q = (p+r)/2;
    if (*Tags[q] < tag)
      p = q+1;
    else
      r = q;
  }
  
  if (*Tags[p] == tag)
    return Tags[p];
  else
  {
    Tag* t = new Tag(tag);
    if (*Tags[p] > tag)
      Tags.insert(Tags.begin()+p, t);
    else
      Tags.insert(Tags.begin()+p+1, t);
    return t;
  }  
}

Linie od 3 do 11 odpowiedzialne są za znalezienie istniejącego już tagu najbardziej zbliżonego do podanego jako argument metody. Używane jest wyszukiwanie binarne. Jest to możliwe dzięki dalszej części kodu tej funkcji, która powoduje, że tagi w wektorze uporządkowane są alfabetycznie rosnąco. Jeżeli okaże się, że znaleziony tag jest identyczny z podanym, to funkcja go zwraca (linie 13-14). Natomiast jeżeli jest różny, oznacza to, że podanej etykiety nie ma jeszcze w bazie, zatem należy takową dodać w odpowiednim miejscu (przed lub po wcześniej znalezionym tagu) i zwrócić wskaźnik do niego, za co odpowiadają linie 15-23. Metoda jest statyczna, zatem można odwoływać się do tagów bez pośrednictwa instancji klasy db::Base.

Reszta zmian w tej rewizji jest kosmetyczna i w większości służy testowaniu poprawności dotychczasowej implementacji, zatem pozwolę sobie pominąć ich omawianie.

Rev 11

Zmiany w jedenastej rewizji miały na celu połączenie wpisów z tagami. Do klasy db::TreeVertex dodany został wektor przechowujący wszystkie etykiety danego wpisu, a także metoda pozwalająca na ich dodawanie (i zapobiegająca powstawaniu duplikatów).

Istotną częścią tej rewizji było także powstanie metod pozwalających na dostęp do każdego tagu danego wpisu, każdego wystąpienia danego tagu i każdego tagu bazy danych z osobna. W każdym przypadku odpowiadały za to dwie dość proste metody: jedna zwracająca liczebność tych elementów w danej klasie, druga zwracająca wskaźnik na element o danym identyfikatorze.

Dodałem także do prowizorycznego TUI trochę kodu, odpowiedzialnego za wyświetlanie tagów danego wpisu oraz dodawanie nowych, a także polecenie służące do wypisania wszystkich tagów wraz z tytułami postów, które opatrują.

Rev 12?

Poświęcony będzie mało pasjonującemu usuwaniu tagów, co sprowadzi się do pięciu, może sześciu linii kodu. Następne rewizje to już zapisywanie bazy do pliku. Z racji tego, że ten etap jest dość obfity w tematy do opisania na blogu, postanowiłem dłużej nie oszczędzać wpisów i publikować je w takim tempie w jakim powstaje LogTree, zatem nie dwa na tydzień, tylko np. jeden na dwa dni. Jeżeli wszystko pójdzie dobrze, to takiego właśnie tempa publikacji wpisów możecie się spodziewać ;)

Brak komentarzy:

Prześlij komentarz