Archive for the ‘Code’ Category

e-voting system

Friday, July 12th, 2013

Estonia just opensourced their e-voting system… written in Python!

Happiness

Friday, June 7th, 2013

Šodien esmu priecīgs divu iemeslu dēļ:

Ir publicēta grāmata par Oracle Tuxedo, kurai es biju recenzents, un es beidzot saņemšu dažas izdevniecības grāmatas par citiem tematiem kā “samaksu”.

Mans risinājums uzvarēja pirmajā Rubylight/JUG konkursā. Tas mani uzjautrina dēļ “es un Java” (Java man nav ne primārā, ne sekundārā valoda) un fakta, ka šo risinājumu sāku rakstīju ap 3iem naktī pirms deadline, pēc dārza svētkiem ar viskiju. Dažādus risinājumus un testus gan biju uzrakstījis pirms tam, kā arī pirms vairākiem gadiem gnome-terminal taisīju Trie struktūru optimizāciju. kods

Programming Languages for BIND 10

Wednesday, February 27th, 2013

If you learned C++ a while ago, but haven’t worked with a modern C++ environment, you probably have the wrong idea about programming with it.

Source code comment of the night

Wednesday, January 9th, 2013

/* XXX: This is not elegant, is it efficient ? */

Who am I?

Thursday, January 3rd, 2013

Ļoti izteikta “kas es esmu” problēma Oracle RDBMS lietojumā. Šāds jautājums lietojumu moka apmēram 1300 reizes sekundē. Vismaz tekošais laiks interesē tikai 700 reizes sekundē.

              Snap Id     Snap Time      Sessions Curs/Sess Comment
            --------- ------------------ -------- --------- -------------------
Begin Snap:     38473 02-Jan-13 13:57:27    1,696      23.5
  End Snap:     38475 02-Jan-13 14:27:34    1,649      24.7
   Elapsed:               30.12 (mins)
                                                CPU per    Elap per
 Executions   Rows Processed   Rows per Exec    Exec (s)   Exec (s)  Hash Value
------------ --------------- ---------------- ----------- ---------- ----------
   2,454,655       2,453,967              1.0       0.00        0.00 2403185938
Module: C:\whatever
SELECT USER FROM SYS.DUAL

   1,335,087       1,335,041              1.0       0.00        0.00 3588513883
Module: C:\whatever
SELECT SYSTIMESTAMP FROM SYS.DUAL

SQL is slow, lets use NoSQL! LOL!

All your core dumps are belong to us

Friday, May 18th, 2012

Gatavojot apmācību par atkļūdošanu unix vidē, iedomājos, ka ar šādu virsraksta frāzi varētu raksturot Oracle ADR – ja kādai programmai pietika nekaunības pieslēgties pie Oracle datubāzes, ADR klusiņām savāks pie sevis visus core dump. Varbūt Oracle uzskata, ka vairākums kritisko kļūdu ir viņu, nevis aplikācijas kodā.

C (and C++) backtraces

Thursday, May 10th, 2012

Lai gan C un C++ nav iebūvētu iespēju stack trace iegūšanai kā interpretējamās valodās, GLIBC bibliotēkā ir backtrace() funkcija, kas māk izdarīt ko līdzīgu. Tomēr, lai to pilnvērtīgi izmantotu, viss kods ir jākompilē ar GCC parametru -rdynamic: rezultātā visas funkcijas tiek eksportētas un dinamiski resolvētas, kas palielina programmas izmēru un samazina ātrdarbību. Faila nosaukumu un koda rindiņu tādā veidā nevar iegūt.

Bet mazliet pacīnoties var izdarīt labāk. Komplektā ar GCC kompilatoru nāk header fails unwind.h ar vairākām noderīgām funkcijām. Viena no tām ir _Unwind_Backtrace, kas māk apstaigāt steku un katrā freimā izsaukt programmētāja norādīto funkciju. Ar _Unwind_GetIP var iegūt instrukcijas rādītāju. Programmas adreses var iegūt, bet ko tālāk?

Ja programma ir kompilēta ar debug informāciju, tad GDB kaut kādā veidā māk pa soļiem izpildīt programmu un izdrukāt atbilstošās koda rindiņas. Par laimi ir maza programmiņa addr2line, kas māk nolasīt debug informāciju no izpildfailiem un izdrukāt konkrētai adresei atbilstošo funkcijas nosaukumu, failu un rindiņu tajā.

Tas strādā mazām demo programmām, bet reālā dzīvē programma parasti izmanto bibliotēkas, pie tam daļu no bibliotēkām var ielādēt un izlādēt programmas izpildes laikā. Kā saprast kura adrese atbilst kurai bibliotēkai programmas izpildes laikā?

Te nāk palīgā Linux /proc failu sistēma: /proc/<PID>/exe var atrast saiti uz pašu izpildfailu, bet /proc/<PID>/maps var atrast dotajā brīdī lietotās bibliotēka ar adrešu intervālu, kas tām piešķirts (un nobīdi bibliotēkas failā, jo viena bibliotēka tiek ielādēta dažādos adrešu intervālos). Tālāk mazliet aritmētikas un addr2line var norādīt pareizo izpildfailu un pareizo adresi.

Saliekot visas šīs lietas kopā, var iegūt strādājošu backtrace() analogu ar detalizētāku informāciju. Kā iegūt C++ izņēmumu stack trace arī ir interesants temats, bet to vēlāk.

Linux, 1333 un Oracle 11.2

Saturday, January 21st, 2012

Tabula:

CREATE TABLE testret(id VARCHAR2(4), data VARCHAR2(4000));

Un tad 4 INSERTi, kas atšķiras tikai ar varchar mainīgā izmēru, bet ne datu garumu.

EXEC SQL BEGIN DECLARE SECTION;
    varchar data1333[1333];
    varchar data1334[1334];

    varchar id1333[1333];
    varchar id1334[1334];
EXEC SQL END DECLARE SECTION;

memset(data1333.arr, 'X', 1);
data1333.len = 1;
memset(data1334.arr, 'X', 1);
data1334.len = 1;
id1333.len = 0;
id1334.len = 0;

EXEC SQL INSERT INTO testret (id, data) VALUES ('1', :data1333) RETURNING id INTO :id1333;
assert(SQLCODE == 0);
EXEC SQL INSERT INTO testret (id, data) VALUES ('2', :data1334) RETURNING id INTO :id1333;
assert(SQLCODE == 0);
EXEC SQL INSERT INTO testret (id, data) VALUES ('3', :data1333) RETURNING id INTO :id1334;
assert(SQLCODE == 0);
EXEC SQL INSERT INTO testret (id, data) VALUES ('4', :data1334) RETURNING id INTO :id1334;
assert(SQLCODE == 0);

Izpildot programmu pret Oracle 11.2 serveri UTF-8 kodējumā, kā jums liekas, kāds būs rezultāts šādam vaicājumam?

SELECT id, DECODE(data, NULL, 0, LENGTH(data)) data_length FROM testret;

Nepareizi! Pārsniedzot maģisko izmēru 1333, dati tiek pazaudēti:

ID   DATA_LENGTH
---- -----------
1	       1
2	       1
3	       1
4	       0

To pašu var uzrakstīt arī ar OCI, nevis PRO*C. Un binārais fails korekti strādā pret vecākām 10.x servera versijām.

Vispār, kopš redzēju kā Oracle 10.2 sajauca vietām kolonas, ja mainīgā izmērs pārsniedza kaut kādus 400x baitus, šajā gadījumā mani pārsteidz tikai maģiskais skaitlis 1333.

Belašu kods

Tuesday, November 29th, 2011

Ja tu redzēsi kā tas tiek rakstīts, vairs nekad negribēsi lietot programmu.
Un tamlīdzīgi.

Oracle LOB programmēšana

Wednesday, October 5th, 2011

Oracle API darbam ar LOB ir viens no nepārdomātākajiem API, ar ko nācies sastapties. Kā rezultātā naiva LOB pievienošana datu bāzei sastāv no 3 soļiem (un roundtrip):

  1. Pievieno tabulai rakstu ar tukšu LOB, piemēram, EMPTY_CLOB()
  2. Nolasa šo pašu lauku no tikko pievienotā ieraksta un iegūst LOB “lokatoru”
  3. Raksta datu porciju LOB-ā (“lokatorā”)

Par laimi, Oracle ir RETURNING INTO, kas ļauj apvienot 1. un 2. soli. Ja samierinās ar datu izmēra ierobežojumiem un šmaukšanos ar Oracle tipu konvertāciju (“data API”), tad to visu var izdarīt vienā solī.

Bet tas vēl ir ciešams, līdz LOB grib lietot Oracle rindās. Rindas būtībā ir viens abstrakcijas līmenis virs “parastajām” tabulām, tāpēc RETURNING INTO un “data API” izmantot nevar. Lai padarītu dzīvi interesantāku, “plikus” LOB, tāpat kā lielāko daļu pārējo datu tipu, rindās ielikt nevar. Ir jāveido objekts ar LOB atribūtu.

Oracle dokumentācija iesaka likt rindā tukšu objektu un iegūt ziņojuma identifikatoru rindā. Pēc tam jāpārkāpj pāri abstrakcijai (bvēēē) un rindai apakšā esošajā tabulā (papildus darbs noskaidrot nosaukumu) jāsameklē LOB “lokators” pēc ziņojuma identifikatora, utt. Tie paši 3 soļi, kas stāsta sākumā.

Un tā nepārdomāts LOB API ir izčakarējis rindu API, jo bija slinkums izdomāt kā izveidot LOB bez ieraksta pievienošanas tabulai.

Go fix your program!

Tuesday, May 31st, 2011

Valgrind apvainojās, LOL:

==4579== More than 1000 different errors detected. I’m not reporting any more.
==4579== Final error counts will be inaccurate. Go fix your program!

UML skices

Tuesday, February 1st, 2011

Tā kā neesmu peles klikšķināšanas fans un kodu pārsvarā rakstu lietojot vim, yUML atklāšana bija patīkams pārsteigums. Daļēji tāpēc, ka UML diagrammas var radīt rakstot īsu tekstu. Un daļēji tāpēc, ka patīk “scruffy” izskats. Mani jau sen interesē veids kā likt Graphviz diagrammām izskatīties kā zīmētām ar roku.

Atradis iedvesmu, pēc pāris vakariem un maziem Python skriptiem iemācījos uzražot jau kaut ko līdzīgu yUML:

Java: pass by reference or value?

Saturday, January 8th, 2011

Fakts, ka par šo tematu tiek diskutēts, neliecina neko labu par diskusijas dalībniekiem (vismaz daļu).