예제 #1
0
        /**
         * initialize the db file
         *
         * @param	raf
         * @
         */
        private void initDbFile(RandomAccessFile raf)
        {
            //1. zero fill the header part
            raf.seek(0L);
            raf.write(new byte[8]);                             //super block
            raf.write(new byte[dbConfig.getTotalHeaderSize()]); //header block

            headerPool = new LinkedList <HeaderBlock>();
            indexPool  = new LinkedList <IndexBlock>();
        }
예제 #2
0
        /**
         * get the region with a int ip address with b-tree algorithm
         *
         * @param   ip
         * @
         */
        public DataBlock btreeSearch(long ip)
        {
            //check and load the header
            if (HeaderSip == null)
            {
                raf.seek(8L);    //pass the super block
                byte[] b = new byte[dbConfig.getTotalHeaderSize()];
                // byte[] b = new byte[4096];
                raf.readFully(b, 0, b.Length);

                //fill the header
                int len = b.Length >> 3, idx = 0;  //b.lenght / 8
                HeaderSip = new long[len];
                HeaderPtr = new int[len];
                long startIp, dataPtr2;
                for (int i = 0; i < b.Length; i += 8)
                {
                    startIp  = Util.getIntLong(b, i);
                    dataPtr2 = Util.getIntLong(b, i + 4);
                    if (dataPtr2 == 0)
                    {
                        break;
                    }

                    HeaderSip[idx] = startIp;
                    HeaderPtr[idx] = (int)dataPtr2;
                    idx++;
                }

                headerLength = idx;
            }

            //1. define the index block with the binary search
            if (ip == HeaderSip[0])
            {
                return(getByIndexPtr(HeaderPtr[0]));
            }
            else if (ip == HeaderSip[headerLength - 1])
            {
                return(getByIndexPtr(HeaderPtr[headerLength - 1]));
            }

            int l = 0, h = headerLength, sptr = 0, eptr = 0;

            while (l <= h)
            {
                int m = (l + h) >> 1;

                //perfetc matched, just return it
                if (ip == HeaderSip[m])
                {
                    if (m > 0)
                    {
                        sptr = HeaderPtr[m - 1];
                        eptr = HeaderPtr[m];
                    }
                    else
                    {
                        sptr = HeaderPtr[m];
                        eptr = HeaderPtr[m + 1];
                    }

                    break;
                }

                //less then the middle value
                if (ip < HeaderSip[m])
                {
                    if (m == 0)
                    {
                        sptr = HeaderPtr[m];
                        eptr = HeaderPtr[m + 1];
                        break;
                    }
                    else if (ip > HeaderSip[m - 1])
                    {
                        sptr = HeaderPtr[m - 1];
                        eptr = HeaderPtr[m];
                        break;
                    }
                    h = m - 1;
                }
                else
                {
                    if (m == headerLength - 1)
                    {
                        sptr = HeaderPtr[m - 1];
                        eptr = HeaderPtr[m];
                        break;
                    }
                    else if (ip <= HeaderSip[m + 1])
                    {
                        sptr = HeaderPtr[m];
                        eptr = HeaderPtr[m + 1];
                        break;
                    }
                    l = m + 1;
                }
            }

            //match nothing just stop it
            if (sptr == 0)
            {
                return(null);
            }

            //2. search the index blocks to define the data
            int blockLen = eptr - sptr, blen = IndexBlock.getIndexBlockLength();

            byte[] iBuffer = new byte[blockLen + blen];    //include the right border block
            raf.seek(sptr);
            raf.readFully(iBuffer, 0, iBuffer.Length);

            l = 0; h = blockLen / blen;
            long sip, eip, dataptr = 0;

            while (l <= h)
            {
                int m = (l + h) >> 1;
                int p = m * blen;
                sip = Util.getIntLong(iBuffer, p);
                if (ip < sip)
                {
                    h = m - 1;
                }
                else
                {
                    eip = Util.getIntLong(iBuffer, p + 4);
                    if (ip > eip)
                    {
                        l = m + 1;
                    }
                    else
                    {
                        dataptr = Util.getIntLong(iBuffer, p + 8);
                        break;
                    }
                }
            }

            //not matched
            if (dataptr == 0)
            {
                return(null);
            }

            //3. get the data
            int dataLen = (int)((dataptr >> 24) & 0xFF);
            int dataPtr = (int)((dataptr & 0x00FFFFFF));

            raf.seek(dataPtr);
            byte[] data = new byte[dataLen];
            raf.readFully(data, 0, data.Length);

            int city_id = (int)Util.getIntLong(data, 0);
            //String region = new String(data, 4, data.Length - 4, "UTF-8");
            var region = Encoding.UTF8.GetString(data, 4, data.Length);

            return(new DataBlock(city_id, region, dataPtr));
        }