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; } }
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); }