lunedì 15 dicembre 2014

sabato 22 febbraio 2014

SHA e altri noti algoritmi Hash O(n) dove n dimensione input... se vuoi provare a tenere basse le collisioni...

Hash table - Worst case O(n) ecco perchè adoro gli indici ad albero :-D...

http://en.wikipedia.org/wiki/Hash_table

Chi gestisce il dato non si può permettere una tabella hash talmente grande da tenere il costo a O(1), per questo meglio mediare su strutture ad albero che garantiscono O(log n)

giovedì 7 novembre 2013

Un classico errore di cui è difficile trovare documentazione è il seguente; quando un modulo Managed (IHttpModule) intercetta una chiamata POST e tenta a recuperare informazione dalla Context.Request sembra che rimuova il body dalla Request stessa, questo causa un errore nella successiva pipeline Unmanaged (VBS context). L'errore viene causato dentro il modulo con un accesso del tipo: Request["chiave"] Semplicemente basta essere sicuri di accedere solo alla QueryString per risolvere l'errore: Request.QueryString["chiave"] In realtà come documentato in diversi post Request["chiave"] esegue una serie di probing tra cui in ordine QueryString e Form ecc...; quando avviene il probing su Form (utilizzato per recuperare i parametri POST) il modulo corrompe la request e quando da VBS si accede in modo diverso da QueryString. Riassumendo, se da un Modulo Http acceddi ai parametri del body della richiesta POST quando il modulo processa queste variabili altera la Request stessa rendendola non più valida per il contesto VBS; non usare mai Request["chiave"] ma sempre Request.QueryString["chiave"]; se il modulo deve valutare le variabili POST... Vedremo quando mi capiterà ;) Scrivo questo post principalmente come reminder personale ;) Essendo il mio il blog di riferimento.

mercoledì 1 ottobre 2008

Questo post riguarda l'integrazione tra Oracle, Access su una piattaforma a 64bit!
In tutti i post del mondo spiegano come utilizzare Access su una piattaforma a 64bit compilando il nostro Assembly in X86 in modo che il Framework al momento del RUN forza l'eseguzione in WOW64 dove il supporto a Jet di Access è ancora supportato. Evito le polemiche sul perchè Microsoft non abbia fornito un Jet a 64bit ma va be', ci saranno motivi.

Il problema si ha quando il vostro exe/webapplication vuole accedere simultaneamente ad Oracle utilizzando ODAC Oracle.DataAccess.Client, i problemi più frequenti li troverete con BadImageFormat (che capita molto spesso se mettete il client a 64bit e nella vostra soluzione lasciate nel riferimento copialocalmente=true) oppure vi capita che non trovi la versione dell'assembly (che capita molto spesso se lasciate versionespecifica=true)


Come ho risolto:
Ho installato entrambi le versioni dell'Oracle Client in due ORACLE_HOME diverse ad esempio:
D:\oracle\product\10.2.0\client_1       VERSIONE NATIVA A 64BIT
D:\oracle\product\10.2.0\client_x86   VERSIONE A 32BIT IN EMULAZIONE WOW

Ho installato entambi le versioni ODAC.NET facendo attenzione a selezionare l'ORACLE_HOME corretta per piattaforma
Alla fine dinalmente nella C:\WINDOWS\assembly mi trovo tutti i miei bellissimi Assembly

Se non utilizzo Access allora compilo con AnyCPU e nella soluzione il riferimento ad Oracle.DataAccess ha copialocalmente = FALSE e versionespecifica = FALSE in modo che anche se sviluppo su una piattaforma a 32bit quando viene eseguita a 64 usa la versione corretta (2.102.3.2)
Se voglio utilizzare Access allora sono costretto ad andare in emulazione (X86) quindi con versionespecifica = TRUE lo forzo alla versione a 32bit (2.102.2.20) con la quale è stato compilato.

Come si comporta adesso:
Se lo lascio ANYCPU prova ad andare a 64bit usa il client nativo 64bit per Oracle e si schianta sull'Access ma se non lo uso vado tutto nativo a 64bit :)
Se lo lancio compilato in X86 adesso grazie all'emulazione WOW64 riesce ad utilizzare correttamente sia il Driver Jet che l'Oracle.DataAccess a 32bit installato nella ORACLE_HOME client_x86\odp.net (Attenzione perchè l'assembly nella GAC lo ho inserito a mano!)

La soluzione mi piace... NO, ancora non mi spiego perchè devo lavorare in emulazione per il fatto che mi hanno tolto il supporto di JET, voi vi chiederete perchè usi ancora Access... Io vi risponderò perchè fa quello per cui mi serve...

Ciao

giovedì 13 dicembre 2007

Oggi sono molto contento e mi sento molto OCA...

Un saluto a tutti
Allino :)

martedì 19 giugno 2007

Sono veramente soddisfatto quando vedo che con una riga di codice si risolve uno dei problemi più macchinosi dell'informatica la gestione delle date rappresentate come stringhe, cambiare formati, validarne l'esattezza, il problema spinoso del cambio di formato; se fosse per me sarebbe tutto yyyyMMdd (ad esempio quando in SQL Server devi eseguire una Query su un campo Date puoi passarglielo come stringa racchiuso tra '' a patto di utilizzare il formato 'yyyyMMdd [HH:mm:ss[.millisecondi]]' ISO, attenzione alla precisione del campo Date con i millisecondi; invece guardando il Profiler quando usi il provider .NET con i Parameter le date vengono passate con un formato verboso ma avranno i loro motivi).

Siccome io non detto ancora gli standard :) viviamo immersi tra le più disparate rappresentazioni tutte magnificamente mappabili con la funzione statica ParseExact

Oggi mi sono trovato in uno dei casi di maggiore complessità (mesi scritti con lettere) ed ho pensato di fare questo post principalmente per promemoria

System.Globalization.CultureInfo dit = new System.Globalization.CultureInfo("it-IT");
DateTime dData = DateTime.ParseExact(sData, "dd MMMM yyyy", dit.DateTimeFormat, System.Globalization.DateTimeStyles.AllowInnerWhite);
sData = dData.ToString("yyyyMMdd");
sData = dData.ToString("dd/MM/yyyy");

Ad esempio con questi parametri ParseExact valida date
6 OttOBRE 1977
10       Aprile         1977

Si deve tenere presente le singole parti di questa funzione:
1) Specificare la Culture per la codifica dei mesi altrimenti utilizza quella di default del sistema (principale problema per cui sulla tua macchina(italiano) funziona e sui server(inglesi) no... Anche questo argomento meriterebbe un post... Mettiamo tutto in Inglese o tutto in Italiano :) e no... sarebbe tutto troppo facile)
2) System.Globalization.DateTimeStyles.AllowInnerWhite permette di validare date con spazi sistemati a caso nella data

Ciao
Allino

giovedì 7 giugno 2007

Ciao a tutti
Nella mia attuale esperienza lavorativa mi trovo a lavorare con file di dimensioni molto superiori ai 2GB e mi sono scontrato spesso con il limite dell'heap gestito dal .NET Framework; per ora ho sempre "brillantemente" aggirato il problema seguendo le linee guida per risolvere questo problema, cioè, utilizzando l'XmlReader invece dell'XmlDocument, bufferizzare le letture e le scritture su filesystem, utilizzando il Database o addirittura implementando logiche di swap a filesystem di parte di un DataSet.

Oramai mi ero rassegnato a questa situazione poi ho pensato di provare su una VM il Sistema Operativo a 64bit con 4GB di RAM. Il test che ho effettuato era un "fantastico :)" exe che riempiva 1000 DataSet fino al OutOfMemoryException, alla fine di questo while true mi setta la relativa label per vedere il limite di memoria raggiunta dal processo...

    try {
        while (true) {
            for (int i = 0; i < 1000; i++) {
                mMyData[i].MyDataTable.AddMyDataTableRow(sTesto, DateTime.Now);
            }
        }
    } catch (OutOfMemoryException exp) {
        lMemory = System.Diagnostics.Process.GetCurrentProcess().WorkingSet64;
       
        lblSize.Text = lMemory.ToString();
    }

I risultati sono stati per me molto significativi in quanto mentre sulla versione a 32bit l'eccezzione veniva generata intorno ai 1,6GB di memoria
sul sistema a 64 bit dopo aver allocato intorno ai 3,4GB sono dovuto intervenire manualmente per bloccarlo in quanto aveva iniziato a swappare mandando in crisi il povero HD; vedendo superare il precedente limite di oltre il doppio (1,6GB -> 3,4GB), dal mio punto di vista, il test aveva avuto esito positivo spostando in alto il limite della memoria allocabile...

Per altro questo problema dei 2GB lo trovo molto spesso su Google a riguardo dell'argomento dei Reporting Services di SQL Server, sappiamo bene tutti che invece il motore relazionale di SQL Server ha una sua gestione a basso livello per indirizzare memoria oltre i limiti del Sistema Operativo (AWE memory, /3GB) e che comunque esistono versioni speciali "Data Center Edition" fatte su misura per gestire tutta la RAM, ma questi argomenti non fanno parte del mio post in quanto questo post riguarda il Framework.

Certo, mentre cercavo di risolvere il problema sul sistema a 32bit mi sono imbattuto in un forum dove si diceva che, comunque, si deve stare attenti in quanto anche nella versione a 64bit del Framework c'è un limite sugli array in quanto l'indice (dimensione max) è comunque rappresentato da un Int32, questo per dire che il limite probabilmente persiste ma di natura diversa.

Attenzione, con questo post non voglio assolutamente fare passare l'idea che adesso tutto può stare in memoria e quindi carichiamo rusco e brusco ma almeno adesso se vogliamo utilizzare XPathNavigator invece di XmlReader e il vosto XML è di 3GB almeno assicuratevi che giri su un 64bit :)
A parte gli scherzi il mio è stato un test per un caso molto particolare e ribadisco che un'attenzione all'utilizzo della memoria DEVE essere un punto fondamentale nella stesura di ogni applicativo.

Ciao a tutti
Allino :)

PS: E' da un po' che non posto in quanto mi ultimamente mi stò dedicando ad altro (Oracle in particolare) ma sappiate che seguo sempre con attenzione questo blog. Approfitto per constatare la scelta di alcune colonne portanti di questa comunità di non mettere i loro post sul "Muro"; mi riferisco in particolare a due colonne come Igor e Lorenzo e chiedergli di ripensarci, tutti riconoscono i vostri meriti nella crescita di UGI.

Alcuni link:
http://msdn.microsoft.com/msdnmag/issues/06/11/CLRInsideOut/default.aspx?loc=it
http://www.sql-server-performance.com/awe_memory.asp
http://support.microsoft.com/kb/909678

giovedì 28 dicembre 2006

Ciao a tutti

            Scrivo di un argomento di cui oramai si sa gia tutto ma serve soprattutto a me come promemoria; in particolare questa funzione serve per visualizzare un file CSV in pagina Web senza redirigere (Response.Redirect) la chiamata a un file CSV su FileSystem, ma leggendolo o scrivendolo direttamente in memoria per poi scriverlo sullo stream output della pagina ASPX (Page.Response).

           

            In particolare quando si adotta questa tecnica è fondamentale specificare il “MIME type”; per i file CSV è “text/csv”, aggiungendo l’Header (AddHeader) possiamo specificare se Explorer caricherà il documento come “attachment” (aprendolo in una nuova window) o “inline”, in questo caso Explorer lo aprirà nella pagina ASPX corrente associato al flusso Response.

 

MemoryStream ms = new MemoryStream();

TextWriter tw = new StreamWriter(ms);

 

foreach (DataRowView drv in dvRisulatiGrid) {

   DataRow dr = drv.Row;

 

   string A = (string)dr[“A”];

   string B = (string)dr[“B”];

   string C = (string)dr[“C”];

 

   tw.Write(A);

   tw.Write(";");

   tw.Write(B);

   tw.Write(";");

   tw.WriteLine(C);

   tw.Flush();

}

 

FlushOutput(ms, false);

 

            Naturalmente nel MemoryStream ci sarà il contentudo del file CSV che verrà interpretato da Excel (o da qualsiasi altro programma associato). Il CSV avrà il classico formato A;B;C;<CRLF>

 

private void FlushOutput(MemoryStream ms, bool bAttachment) {

    try{

        Response.Clear();

        Response.ClearContent();

        Response.ClearHeaders();

 

        BinaryWriter bwriter = new BinaryWriter(Response.OutputStream);

 

        Response.ContentType = "text/csv";

        Response.BufferOutput = true;

        if (bAttachment) {

            Response.AddHeader("Content-Disposition", "attachment; filename=\"ExportResult.csv\"");

        } else {

            Response.AddHeader("Content-Disposition", "inline; filename=\"ExportResult.csv\"");

        }

 

        bwriter.Write(ms.ToArray());

        bwriter.Close();

    } catch (Exception ex) {

        string Error = ex.ToString();

    } finally {

        Response.End();

    }

}

 

            Questo meccanismo ci consente di sostituire il normale flusso HTML con un qualsiasi flusso binario come PDF, DOC, RTF specificando per ogni documento il suo MIME corretto.

 

http://www.iana.org/assignments/media-types/

http://www.asahi-net.or.jp/en/guide/cgi/mimetype.html

http://www.ltsw.se/knbase/internet/mime.htp

 

            Grazie al MIME type Explorer sa a che applicativo associare lo stream binario per visualizzare correttamente il file dentro la nostra pagina di Explorer J.

 

Ciao a tutti.

Allino

lunedì 23 ottobre 2006

Ciao a tutti, facendo i complimenti a tutti gli oratori in quanto hanno reso interessante un argomento "astratto" che però risulta fondamentale per il "concreto" volevo chiedere dove posso trovare i lucidi delle presentazioni?.

Oggi stò combattendo una battaglia importante, la nuova ditta in cui lavoro come dipendente stà per scegliere se passare definitivamente a Java (già il 50% segue questo orientamento). Naturalmente io mi stò battendo per rimanere in .NET (le mie certificazioni MCAD stanno per suicidarsi nel bagno... ieri ho preso in mano un progetto Java con Eclipse e non esprimo commenti... e pensare che la mia carriera è iniziata come sviluppatore Java 8 anni fa e mai avrei pensato di diventare un 100% pure microsoft convinto, vada per Oracle ma riadottare Java sarebbe un vero castigo...)

Con questo Post chiedo anche un aiuto per trovare risorse che possano convincere i "capi" che la scelta di Java è quantomeno anacronistica... Certo alla domanda .NET va su qualsiasi piattaforma e qualsiasi HW posso solo argomentare con "nel futuro c'è MONO..." e in un mondo Enterprise... Chissà...

Ciao a tutti :)

Anche se passerò 100% Java e Oracle mi terrò comunque aggiornato e non vi lascierò...

 

mercoledì 6 settembre 2006

Preso dall'entusiasmo della nuova stagione ho iniziato a migrare me stesso verso i nuovi VS e SQL (2005, arrivo sempre dopo la puzza). Mentre sono entusiasto di VS che ha rispettato tutte le mie aspettative e forse anche di più (per ora non ho trovato rivoluzioni*) mi accingo a testare il nuovo tipo XML di SQLServer 2005, nella mia mente sono infuocatissimo perchè ora potrei (ma non dovrei) mettere tutti gli attributi in un unico campo XML, indicizzarlo e fare Query a manetta con XPath, che spettacolo, allora creo una tabella con un qualche attributo e il fantastico campo XML dove gli metto un grande indice.

SELECT COUNT(*) FROM dbo.TestXml WHERE TestXml2.value('declare namespace PD="http://tempuri.org/Test.xsd"; /PD:Test[1]/PD:TableTest[1]/PD:Cognome[1]', 'VARCHAR(50)') = 'VALENTI'

In una tabella con appena 200000 record e un XML del tipo


<Test xmlns="http://tempuri.org/Test.xsd">
 <TableTest>
  <Cognome>VALENTI</Cognome>
  <Nome>ALESSANDRO</Nome>
  <CognomeNome>VALENTI ALESSANDRO</CognomeNome>
  <DataNascita>19771006</DataNascita>
  <Attr1>0,389548152866563</Attr1>
  <Attr2>0,940962524125801</Attr2>
  <Attr3>0,616221261032029</Attr3>
 </TableTest>
</Test>

Per trovarmi 1500 recod che rispondono alla query ci impiega circa 4 minuti su una macchina virtuale; la mia impressione è che faccia qualcosa di peggio di un table scan nonostante il piano di esecuzione faccia vedere cose strane tipo Join su indici cluster... Mah...

Ora nel mio piano certificativo c'è come prossimo obiettivo SQL2005 (devo ancora iniziare a studiare); ma se nel mentre qualcuno conosce un modo intelligente per utilizzare le stringhe XPATH come parametro della WHERE (.value, .query) allora sarebbe bello se qualcuno mi rispondesse e magari scrivesse un articolo su questo argomento; invece ritengo performante utilizzare queste funzionalità nei parametri della SELECT.

* Per fortuna --> MSVS2005 non ci sono rivoluzioni ma solamente aggiunte :)

Un saluto a tutti
Allino