Esempio n. 1
0
        void _OpenRIndex()
        {
            try
            {
                if (state == ConnectionState.Open)
                {
                    throw new Exception("Connnection is already open.");
                }

                if (connstr.RIndex == QaConnectionString.RIndexType.POOLED)
                {
                    string[] hosts = connstr.DataSource;
                    Random   rnd   = new Random(unchecked (System.DateTime.Now.Millisecond + System.Threading.Thread.CurrentThread.ManagedThreadId));
                    for (int hi = 0; hi < hosts.Length; hi++)
                    {
                        int    swapindex = rnd.Next() % hosts.Length;
                        string oval      = hosts[hi];
                        hosts[hi]        = hosts[swapindex];
                        hosts[swapindex] = oval;
                    }
                    for (int hi = 0; hi < hosts.Length; hi++)
                    {
                        _OpenSocketRIndex(hosts[hi]);
                    }
                }
                else
                {
                    _OpenSocketRIndex(null);
                }

                netstm.WriteByte((byte)'i'); //get all master indexes.

                sysindexes = new Dictionary <string, Index>();
                {
                    string xml = XContent.ReceiveXString(netstm, buf);
                    if (xml.Length > 0)
                    {
                        System.Xml.XmlDocument xi = new System.Xml.XmlDocument();
                        xi.LoadXml(xml);
                        System.Xml.XmlNodeList xnIndexes = xi.SelectNodes("/indexes/index");
                        foreach (System.Xml.XmlNode xnIndex in xnIndexes)
                        {
                            string                 indName            = xnIndex["name"].InnerText;
                            System.Xml.XmlNode     xnUpdatememoryonly = xnIndex.SelectSingleNode("updatememoryonly");
                            System.Xml.XmlElement  xePinHash          = xnIndex["pinHash"];
                            System.Xml.XmlElement  xeTable            = xnIndex["table"];
                            System.Xml.XmlNodeList xnCols             = xeTable.SelectNodes("column");

                            Column[] cols = new Column[xnCols.Count];
                            for (int ci = 0; ci < xnCols.Count; ci++)
                            {
                                System.Xml.XmlNode xnCol = xnCols[ci];
                                cols[ci].Name  = xnCol["name"].InnerText;
                                cols[ci].Type  = xnCol["type"].InnerText;
                                cols[ci].Bytes = Int32.Parse(xnCol["bytes"].InnerText);
                            }

                            Table tab;
                            tab.Name    = xeTable["name"].InnerText;
                            tab.Columns = cols;

                            Index ind;
                            ind.Name             = indName;
                            ind.Ordinal          = Int32.Parse(xnIndex["ordinal"].InnerText);
                            ind.Table            = tab;
                            ind.UpdateMemoryOnly = (xnUpdatememoryonly != null && xnUpdatememoryonly.InnerText == "1");
                            ind.PinHash          = (xePinHash != null && xePinHash.InnerText == "1");
                            ind.Hash             = ind.PinHash ? new Position[256 * 256] : null;
                            ind.MaxKey           = new byte[tab.Columns[ind.Ordinal].Bytes];
                            sysindexes.Add(indName.ToLower(), ind);
                        }
                    }
                }

                int micnt = 0;
                XContent.ReceiveXBytes(netstm, out micnt, buf);
                micnt    = Utils.BytesToInt(buf, 0);
                mindexes = new Dictionary <string, List <KeyValuePair <byte[], string> > >(micnt);
                for (int mi = 0; mi < micnt; mi++)
                {
                    string indexname = XContent.ReceiveXString(netstm, buf).ToLower();
                    List <KeyValuePair <byte[], string> > lines = new List <KeyValuePair <byte[], string> >();
                    int        keylen  = 9;
                    bool       pinhash = false;
                    Position[] hash    = null;
                    byte[]     maxkey  = null;
                    if (sysindexes.ContainsKey(indexname))
                    {
                        Index thisindex = sysindexes[indexname];
                        int   ordinal   = thisindex.Ordinal;
                        keylen  = thisindex.Table.Columns[ordinal].Bytes;
                        pinhash = thisindex.PinHash;
                        hash    = thisindex.Hash;
                        maxkey  = thisindex.MaxKey;
                    }
                    else
                    {
                        throw new Exception("Index version conflict, need to recreate indexes");
                    }

                    byte[] lastkeybuf = new byte[3];
                    int    filelen    = 0;
                    XContent.ReceiveXBytesNoCap(netstm, out filelen, ref buf);
                    if (filelen > 0)
                    {
                        int pos     = 0;
                        int hoffset = 0;
                        int hlen    = 0;

                        for (int ki = 0; ki < keylen; ki++)
                        {
                            maxkey[ki] = buf[pos++];
                        }

                        while (pos < filelen)
                        {
                            byte[] keybuf = new byte[keylen];
                            for (int ki = 0; ki < keylen; ki++)
                            {
                                keybuf[ki] = buf[pos++];
                            }

                            /*bool samekey = true;
                             * for (int ki = 0; ki < keybuf.Length; ki++)
                             * {
                             *  if (lastkeybuf[ki] != keybuf[ki])
                             *  {
                             *      samekey = false;
                             *      break;
                             *  }
                             * }*/

                            int chunknamestartpos = pos;
                            while (buf[pos++] != (byte)'\0')
                            {
                            }

                            //samekey = false;
                            //if (!samekey)
                            {
                                string chunkname = System.Text.Encoding.UTF8.GetString(buf, chunknamestartpos, pos - chunknamestartpos - 1);

                                if (pinhash)
                                {
                                    if (lines.Count > 0)
                                    {
                                        if (keybuf[1] != lastkeybuf[1] || keybuf[2] != lastkeybuf[2])
                                        {
                                            int shortkey = TwoBytesToInt(lastkeybuf[1], lastkeybuf[2]);
                                            hash[shortkey].Offset = hoffset;
                                            hash[shortkey].Length = hlen;
                                            hoffset = lines.Count;
                                            hlen    = 0;
                                        }
                                    }
                                    hlen++;
                                }

                                lines.Add(new KeyValuePair <byte[], string>(keybuf, chunkname));
                                Buffer.BlockCopy(keybuf, 0, lastkeybuf, 0, 3);
                            }
                        }

                        if (pinhash)
                        {
                            //last flush
                            if (hlen > 0)
                            {
                                int shortkey = TwoBytesToInt(lastkeybuf[1], lastkeybuf[2]);
                                hash[shortkey].Offset = hoffset;
                                hash[shortkey].Length = hlen;
                            }

                            //fill in the gap
                            int prevoffset = 0;
                            int prevlen    = 0;
                            for (int hi = 0; hi < hash.Length; hi++)
                            {
                                Position thispos = hash[hi];
                                if (thispos.Length == 0)
                                {
                                    thispos.Length = prevlen;
                                    thispos.Offset = prevoffset;
                                    hash[hi]       = thispos;
                                }
                                else
                                {
                                    prevoffset = thispos.Offset;
                                    prevlen    = thispos.Length;
                                }
                            }
                        }
                    }
                    mindexes.Add(indexname, lines);
                }

                if (connstr.RIndex == QaConnectionString.RIndexType.NOPOOL)
                {
                    _CloseSocketRIndex();
                }
                state = ConnectionState.Open;
            }
            catch
            {
                Cleanup();
                throw;
            }
        }
Esempio n. 2
0
        private bool _ReadRIndex()
        {
            if (isFirstRead)
            {
                isFirstRead = false;
                XContent.ReceiveXBytesNoCap(netstm, out allRowsByteCount, ref cmd.buf);
                allRowsCurPos = 0;
            }
            if (allRowsCurPos >= allRowsByteCount)
            {
                eof = true;
                return(false);
            }
            //Read a row.
            for (int i = 0; i < metadata.Length; i++)
            {
                MetaData column      = metadata[i];
                int      bytesremain = allRowsByteCount - allRowsCurPos;
                if (bytesremain < column.FrontBytes + column.Size + column.BackBytes)
                {
                    throw new Exception("Column value bytes remained has fewer bytes than expected.");
                }

                if (0 != cmd.buf[allRowsCurPos])
                {
                    currow[i] = DBNull.Value;
                }
                else
                {
                    switch (column.Type.FullName)
                    {
                    case "System.Int64":
                        currow[i] = Utils.ToInt64((UInt64)Utils.BytesToLong(cmd.buf, allRowsCurPos + column.FrontBytes));
                        break;

                    case "System.Int32":
                        currow[i] = Utils.ToInt32((UInt32)Utils.BytesToInt(cmd.buf, allRowsCurPos + column.FrontBytes));
                        break;

                    case "System.Double":
                        currow[i] = Utils.BytesToDouble(cmd.buf, allRowsCurPos + column.FrontBytes);
                        break;

                    case "System.DateTime":
                    {
                        Int64 ticks = Utils.BytesToLong(cmd.buf, allRowsCurPos + column.FrontBytes);
                        currow[i] = new DateTime(ticks);
                    }
                    break;

                    case "System.String":
                    {
                        //trim padding
                        int stringend = allRowsCurPos;
                        int strstart  = allRowsCurPos + column.FrontBytes;
                        for (int si = allRowsCurPos + column.FrontBytes + column.Size - 1; si > strstart; si = si - 2)
                        {
                            if (cmd.buf[si] != 0 || cmd.buf[si - 1] != 0)
                            {
                                stringend = si;
                                break;
                            }
                        }
                        currow[i] = System.Text.Encoding.Unicode.GetString(cmd.buf, allRowsCurPos + column.FrontBytes, stringend - column.FrontBytes + 1 - allRowsCurPos);
                    }
                    break;

                    default:
                        throw new Exception("Type not supported yet for RIndex.");
                    }
                }
                allRowsCurPos += column.FrontBytes + column.Size + column.BackBytes;
            }
            return(true);
        }