Az előző kitérő után most térjünk vissza egy kis kocka témához. A minap érdekes felfedezést tettem, miközben véletlenül a GEF belső kódjába tévedtem debug közben. Alapvetően egyébként meg vagyok elégedve a GEF és általában az eclipse platform minőségével, ritka az az eset, hogy a fejemet fogom egy-egy megoldás láttán.

A következő kódrészlet ugyan működik és mivel a publikus api elrejti, az átlag fejlesztő nem találkozik vele, mégis érdemes rávetni egy pillantást. További szócséplés helyett következzék a kód, szerintem magáért beszél:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
//AbstractEditPart.class

private Object[] policies;

//...

/**
 * @see EditPart#installEditPolicy(Object, EditPolicy)
 */

public void installEditPolicy(Object key, EditPolicy editPolicy) {
    Assert.isNotNull(key, "Edit Policies must be installed with keys");//$NON-NLS-1$
    if (policies == null) {
        policies = new Object[2];
        policies[0] = key;
        policies[1] = editPolicy;
    } else {
        int index = 0;
        while (index < policies.length && !key.equals(policies[index]))
            index += 2;
        if (index < policies.length) {
            index++;
            EditPolicy old = (EditPolicy)policies[index];
            if (old != null && isActive())
                old.deactivate();
            policies[index] = editPolicy;
        } else {
            Object newPolicies[] = new Object[policies.length + 2];
            System.arraycopy(policies, 0, newPolicies, 0, policies.length);
            policies = newPolicies;
            policies[index] = key;
            policies[index + 1] = editPolicy;
        }
    }
   
    if (editPolicy != null) {
        editPolicy.setHost(this);
        if (isActive())
            editPolicy.activate();
    }
}

Akinek nem világos elsőre, kifejteném a problémát: láthatóan egy tömböt használ a java-ban alapértelmezésként elérhető “Map” funkcionalitásának a kiváltására. A tömb páros (és nulladik) helyén szereplő elem tárolja a kulcsot, az utána lévő páratlan helyen lévő elem az érték.

Minden elem hozzáadásakor dinamikusan növeli a tömb méretét, törléskor meg egyszerűen null-ra állítja a tömb megfelelő elemét. Ehhez még társul egy custom iterátor is, ami a tömb nem null elemeit listázza.

Őszintén nem értem a tervezési döntést, ami a tömb-alapú Map-hez vezethetett. A memóriaigénye a HashMap-nek nem sokkal több, és mivel jellemzően kis elemszámú esetek fordulnak elő, ez nem számottevő. A sebessége a HashMap-nek jobb, a “get” és “put” metódusok általános esetben konstans, de mindenképpen kevesebb a tömb végigjárásánál. Mindennek a tetejébe a fenti kód Map alkalmazásával kb. 3 sorra cserélhető, nem beszélve az osztály egyéb kódjáról, ami a tömböt piszkálja.

Egyetlen érthető mentségként csak arra tudok gondolni, hogy esetleg a kód korábban íródott, minthogy a java collections API-ba belekerült volna a Map. Ez viszont az 1.2-es verzióban történt meg, tehát elég régen. Nem tudom mennyi idős a GEF, így ezt nem tudom eldönetni.. Mindenesetre ez a kód nálam megütötte a WTF szintet.