zoukankan      html  css  js  c++  java
  • plsql HashMap &HashSet implement

    Thinking

    HashMap 和HashSet其实类似于具有特定存储方式的二维数组。拿Integerhashset为例,我想要往hashset里面存储一个数字5,首先先通过某一种hash算法获得一个hash值比如获得的是3,那么先纵向遍历,查看二维数组的纵列第三个位置上是否为空,如果为空,就将该二维数组的横向初始化,然后把数字5放进初始化的横向数组里面;如果,二维数组第三个位置不为空,那么再继续横向遍历找到位置三并将数字5放入(注意:如果该位置也有值那么会覆盖掉原来的值)

    plsql IntegerSet

    CREATE OR REPLACE TYPE IntegerSet_gdb AS OBJECT
        (chains IntegerarrayArray , numChains integer , numEntries integer ,
         threshold integer , --阈值
       loadFactor float ,
         cachedChain integer , cachedChainPos integer , CONSTRUCTOR FUNCTION IntegerSet_gdb RETURN SELF AS RESULT, MEMBER PROCEDURE put (k INTEGER ), MEMBER FUNCTION get (k INTEGER ) RETURN boolean , MEMBER FUNCTION getByIndex (self IN OUT NOCOPY IntegerSet_gdb , idx integer ) RETURN INTEGER , MEMBER PROCEDURE remove (k INTEGER ), MEMBER PROCEDURE clear, MEMBER FUNCTION getNumEntries RETURN integer , --整个set里面存储内容的个数 MEMBER FUNCTION isEmpty RETURN boolean , MEMBER FUNCTION toString RETURN varchar2 , MEMBER FUNCTION toArray RETURN IntegerArray_1 , MEMBER FUNCTION getKeyPosition (key INTEGER ) RETURN integer ) ; --通过Hash算法获取hash值 / CREATE OR REPLACE TYPE BODY IntegerSet_gdb AS CONSTRUCTOR FUNCTION IntegerSet_gdb RETURN SELF AS RESULT AS i integer ; BEGIN self.numChains := 11; self.numEntries := 0; self.loadFactor := 0.75; self.threshold := floor (self.numChains * self.loadFactor ); self.cachedChain := 0; self.cachedChainPos := 0; self.chains := IntegerarrayArray (); self.chains.extend (self.numChains ); RETURN; END; MEMBER PROCEDURE put (k INTEGER ) AS pos integer ; newChains IntegerarrayArray ; BEGIN IF self.numEntries > self.threshold THEN  --对超出阈值进行处理 self.numChains := self.numChains * 2; self.threshold := floor (self.numChains * self.loadFactor ); newChains := IntegerarrayArray (); newChains.extend (self.numChains ); FOR i IN 1..self.chains.count LOOP IF self.chains (i ) IS NOT NULL THEN FOR j IN 1..self.chains (i ).count LOOP IF self.chains (i )(j ) IS NOT NULL THEN pos := getKeyPosition (self.chains (i )(j )); IF newChains (pos ) IS NULL THEN newChains (pos ) := IntegerArray_1 (); END IF; newChains (pos ).extend; newChains (pos )(newChains (pos ).count) := self. chains (i )(j ); END IF; END LOOP; END IF; END LOOP; self.chains := newChains ; self.put (k ); END IF; pos := getKeyPosition (k ); --获取hash值   IF self.chains (pos ) IS NOT NULL THEN FOR i IN 1..self.chains (pos ).count LOOP IF self.chains (pos )(i ) = k THEN RETURN; END IF; END LOOP; FOR i IN 1..self.chains (pos ).count LOOP IF self.chains (pos )(i ) IS NULL THEN self.chains (pos )(i ) := k ; self.numEntries := self.numEntries + 1; --总个数+1 RETURN; END IF; END LOOP; self.chains (pos ).extend; self.chains (pos )(self.chains (pos ).count) := k ;  --放入value self.numEntries := self.numEntries + 1; ELSE self.chains (pos ) := IntegerArray_1 (); self.put (k ); END IF; END; MEMBER FUNCTION get (k INTEGER ) RETURN boolean AS pos integer ; i integer ; BEGIN pos := getKeyPosition (k ); IF self.chains (pos ) IS NOT NULL THEN FOR i IN 1..self.chains (pos ).count LOOP IF self.chains (pos )(i ) = k THEN RETURN TRUE; END IF; END LOOP; END IF; RETURN FALSE; END; MEMBER PROCEDURE clear AS oldNumChains integer ; BEGIN self.numEntries := 0; oldNumChains := self.numChains ; self.numChains := 11; self.chains.trim (self.numChains - oldNumChains ); self.threshold := floor (self.numChains * self.loadFactor ); FOR i IN 1..self.chains.count LOOP IF ( self.chains (i ) IS NOT NULL) THEN self.chains (i ).delete; END IF; END LOOP; END; MEMBER PROCEDURE remove (k INTEGER ) AS pos integer ; i integer ; BEGIN pos := getKeyPosition (k ); IF self.chains (pos ).count IS NOT NULL THEN FOR i IN 1..self.chains (pos ).count LOOP IF self.chains (pos )(i ) = k THEN self.chains (pos )(i ) := NULL; self.numEntries := self.numEntries - 1; END IF; END LOOP; END IF; END; MEMBER FUNCTION getNumEntries RETURN integer AS BEGIN RETURN self.numEntries ; END; MEMBER FUNCTION isEmpty RETURN boolean AS BEGIN IF self.getNumEntries () = 0 THEN RETURN TRUE; ELSE RETURN FALSE; END IF; END; MEMBER FUNCTION getByIndex (self IN OUT IntegerSet_gdb , idx integer ) RETURN INTEGER AS BEGIN IF idx >= 1 AND idx <= self.getNumEntries THEN IF self.cachedChain = 0 OR idx = 1 THEN self.cachedChain := 1; self.cachedChainPos := 0; END IF; FOR i IN self.cachedChain ..self.chains.count LOOP IF self.chains (i ) IS NOT NULL THEN FOR j IN self.cachedChainPos + 1..self.chains (i ).count LOOP IF self.chains (i )(j ) IS NOT NULL THEN self.cachedChainPos := j ; RETURN self.chains (i )(j ); END IF; END LOOP; END IF; self.cachedChainPos := 0; self.cachedChain := self.cachedChain + 1; END LOOP; END IF; END; MEMBER FUNCTION toString RETURN varchar2 AS res VARCHAR2 (32767); BEGIN res := ''; FOR i IN 1..self.chains.count LOOP IF self.chains (i ) IS NOT NULL THEN FOR j IN 1..self.chains (i ).count LOOP IF self.chains (i )(j ) IS NOT NULL THEN res := res || ', ' || TO_CHAR (self.chains (i )(j )); END IF; END LOOP; END IF; END LOOP; res := '{ ' || substr (res , 3) || ' }'; RETURN res ; END; MEMBER FUNCTION toArray RETURN IntegerArray_1 AS res IntegerArray_1 ; BEGIN res := IntegerArray_1 (); FOR i IN 1..self.chains.count LOOP IF self.chains (i ) IS NOT NULL THEN FOR j IN 1..self.chains (i ).count LOOP IF self.chains (i )(j ) IS NOT NULL THEN res.extend ; res (res.count ) := self.chains (i )(j ); END IF; END LOOP; END IF; END LOOP; RETURN res ; END; MEMBER FUNCTION getKeyPosition (key INTEGER ) RETURN integer IS BEGIN RETURN mod (abs (integerIdentity (key )), self.numChains ) + 1; END; END ; /

    plsql varchar2varchar2Map

    CREATE OR REPLACE TYPE Varchar2Varchar2Map_gdb AS OBJECT
        (chains Vrchr2vrchr2mp1ntryrryArr , numChains integer ,
         numEntries integer , threshold integer , loadFactor float ,
         CONSTRUCTOR FUNCTION Varchar2Varchar2Map_gdb RETURN SELF AS RESULT,
         MEMBER PROCEDURE put (k VARCHAR2 , v VARCHAR2 ),
         MEMBER FUNCTION get (k VARCHAR2 ) RETURN VARCHAR2 ,
         MEMBER PROCEDURE remove (k VARCHAR2 ),
         MEMBER FUNCTION containsKey (k VARCHAR2 ) RETURN boolean ,
         MEMBER FUNCTION getKeys RETURN Varchar2Set_gdb ,
         MEMBER FUNCTION getEntries RETURN Varchar2varchar2map1entrySet ,
         MEMBER FUNCTION getNumEntries RETURN integer ,
         MEMBER FUNCTION isEmpty RETURN boolean , MEMBER PROCEDURE clear,
         MEMBER FUNCTION toString RETURN varchar2 ,
         MEMBER FUNCTION getKeyPosition (key VARCHAR2 ) RETURN integer ) ;
    /
    
    CREATE OR REPLACE TYPE BODY Varchar2Varchar2Map_gdb AS
        CONSTRUCTOR FUNCTION Varchar2Varchar2Map_gdb RETURN SELF AS RESULT AS
        i integer ; BEGIN
            self.numChains  := 11;
            self.numEntries  := 0;
            self.loadFactor  := 0.75;
            self.threshold  := floor (self.numChains  * self.loadFactor );
            self.chains  := Vrchr2vrchr2mp1ntryrryArr ();
            self.chains.extend (self.numChains );
            RETURN;
        END;
        MEMBER PROCEDURE put (k VARCHAR2 , v VARCHAR2 ) AS
        pos integer ; newChains Vrchr2vrchr2mp1ntryrryArr ; BEGIN
            IF  self.numEntries  > self.threshold  THEN
                self.numChains  := self.numChains  * 2;
                self.threshold  := floor (self.numChains  * self.loadFactor );
                newChains  := Vrchr2vrchr2mp1ntryrryArr ();
                newChains.extend (self.numChains );
                FOR i IN 1..self.chains.count
                LOOP
                    IF  self.chains (i ) IS NOT NULL THEN
                        FOR j IN 1..self.chains (i ).count
                        LOOP
                            IF  self.chains (i )(j ) IS NOT NULL THEN
                                pos  := getKeyPosition (self.chains (i )(j ).k);
                                IF  newChains (pos ) IS NULL THEN
                                    newChains (pos ) := Varchar2varchar2map1entryArray ();
                                END IF;
                                newChains (pos ).extend;
                                newChains (pos )(newChains (pos ).count) := self.
                                                                            chains (i )(j );
                            END IF;
                        END LOOP;
                    END IF;
                END LOOP;
                self.chains  := newChains ;
                self.put (k , v );
            END IF;
            pos  := getKeyPosition (k );
            IF  self.chains (pos ) IS NOT NULL THEN
                FOR i IN 1..self.chains (pos ).count
                LOOP
                    IF  self.chains (pos )(i ).k = k  THEN
                        self.chains (pos )(i ).v := v ; RETURN; END IF;
                END LOOP;
                FOR i IN 1..self.chains (pos ).count
                LOOP
                    IF  self.chains (pos )(i ) IS NULL THEN
                        self.chains (pos )(i ) := Varchar2Varchar2Map1Entry_gdb (k ,
                                                                             v );
                        self.numEntries  := self.numEntries  + 1;
                        RETURN;
                    END IF;
                END LOOP;
                self.chains (pos ).extend;
                self.
                chains (pos )(self.
                              chains (pos ).count) := Varchar2Varchar2Map1Entry_gdb (k ,
                                                                                 v );
                self.numEntries  := self.numEntries  + 1;
            ELSE
                self.chains (pos ) := Varchar2varchar2map1entryArray ();
                self.put (k , v );
            END IF;
        END;
        MEMBER FUNCTION get (k VARCHAR2 ) RETURN VARCHAR2  AS
        pos integer ; i integer ; BEGIN
            pos  := getKeyPosition (k );
            IF  self.chains (pos ) IS NOT NULL THEN
                FOR i IN 1..self.chains (pos ).count
                LOOP
                    IF  self.chains (pos )(i ).k = k  THEN
                        RETURN self.chains (pos )(i ).v; END IF;
                END LOOP;
            END IF;
            RETURN NULL;
        END;
        MEMBER PROCEDURE remove (k VARCHAR2 ) AS
        pos integer ; i integer ; BEGIN
            pos  := getKeyPosition (k );
            IF  self.chains (pos ) IS NOT NULL THEN
                FOR i IN 1..self.chains (pos ).count
                LOOP
                    IF  self.chains (pos )(i ).k = k  THEN
                        self.chains (pos )(i ) := NULL;
                        self.numEntries  := self.numEntries  - 1;
                    END IF;
                END LOOP;
            END IF;
        END;
        MEMBER FUNCTION getKeys RETURN Varchar2Set_gdb  AS
        keys Varchar2Set_gdb ; BEGIN
            keys  := Varchar2Set_gdb ();
            FOR i IN 1..self.chains.count
            LOOP
                IF  self.chains (i ) IS NOT NULL THEN
                    FOR j IN 1..self.chains (i ).count
                    LOOP
                        IF  self.chains (i )(j ) IS NOT NULL THEN
                            keys.put (self.chains (i )(j ).k); END IF;
                    END LOOP;
                END IF;
            END LOOP;
            RETURN keys ;
        END;
        MEMBER FUNCTION getEntries RETURN Varchar2varchar2map1entrySet  AS
        entries Varchar2varchar2map1entrySet ; BEGIN
            entries  := Varchar2varchar2map1entrySet ();
            FOR i IN 1..self.chains.count
            LOOP
                IF  self.chains (i ) IS NOT NULL THEN
                    FOR j IN 1..self.chains (i ).count
                    LOOP
                        IF  self.chains (i )(j ) IS NOT NULL THEN
                            entries.
                            put (Varchar2Varchar2Map1Entry_gdb (self.chains (i )(j ).k,
                                                            self.
                                                            chains (i )(j ).v));
                        END IF;
                    END LOOP;
                END IF;
            END LOOP;
            RETURN entries ;
        END;
        MEMBER FUNCTION containsKey (k VARCHAR2 ) RETURN boolean  AS
        pos integer ; i integer ; BEGIN
            pos  := getKeyPosition (k );
            IF  self.chains (pos ) IS NOT NULL THEN
                FOR i IN 1..self.chains (pos ).count
                LOOP IF  self.chains (pos )(i ).k = k  THEN RETURN TRUE; END IF;
                END LOOP;
            END IF;
            RETURN FALSE;
        END;
        MEMBER FUNCTION getNumEntries RETURN integer  AS
        BEGIN RETURN self.numEntries ; END;
        MEMBER FUNCTION isEmpty RETURN boolean  AS
        BEGIN
            IF  self.getNumEntries () = 0 THEN RETURN TRUE; ELSE RETURN FALSE;
            END IF;
        END;
        MEMBER PROCEDURE clear AS
        oldNumChains integer ; BEGIN
            self.numEntries  := 0;
            oldNumChains  := self.numChains ;
            self.numChains  := 11;
            self.chains.trim (self.numChains  - oldNumChains );
            self.threshold  := floor (self.numChains  * self.loadFactor );
            FOR i IN 1..self.chains.count
            LOOP
                IF  ( self.chains (i ) IS NOT NULL) THEN self.chains (i ).delete;
                END IF;
            END LOOP;
        END;
        MEMBER FUNCTION toString RETURN varchar2  AS
        res VARCHAR2 (32767); BEGIN
            res  := '';
            FOR i IN 1..self.chains.count
            LOOP
                IF  self.chains (i ) IS NOT NULL THEN
                    FOR j IN 1..self.chains (i ).count
                    LOOP
                        IF  self.chains (i )(j ) IS NOT NULL THEN
                            res  := res  || ', '
                            || self.chains (i )(j ).toString();
                        END IF;
                    END LOOP;
                END IF;
            END LOOP;
            res  := '{ ' || substr (res , 3) || ' }';
            RETURN res ;
        END;
        MEMBER FUNCTION getKeyPosition (key VARCHAR2 ) RETURN integer  IS
        BEGIN RETURN mod (abs (djb2 (key )), self.numChains ) + 1; END;
    END ;
    /

    refference

    http://blog.csdn.net/vking_wang/article/details/14166593

    每天一点点
  • 相关阅读:
    python面向对象__call__
    python的上下文管理协议
    python析构方法__del__
    next和iter可迭代协议
    __slots__ 用法
    定制自己的数据类型
    内置的Attr系列
    反射和自省
    isinstance和issubclass
    BLE 学习
  • 原文地址:https://www.cnblogs.com/juliazhang/p/5091683.html
Copyright © 2011-2022 走看看