예제 #1
0
        public static int unpackString(byte[] arr, int offs, out string str, Encoding encoding)
        {
            int len = Bytes.unpack4(arr, offs);

            offs += 4;
            str   = null;
            if (len >= 0)
            {
                char[] chars = new char[len];
                for (int i = 0; i < len; i++)
                {
                    chars[i] = (char)Bytes.unpack2(arr, offs);
                    offs    += 2;
                }
                str = new string(chars);
            }
            else if (len < -1)
            {
                if (encoding != null)
                {
                    str = encoding.GetString(arr, offs, -2 - len);
                }
                else
                {
                    str = Encoding.Default.GetString(arr, offs, -2 - len);
                }
                offs -= 2 + len;
            }
            return(offs);
        }
 protected ReplicationSlaveStorageImpl(String pageTimestampFilePath)
 {
     if (pageTimestampFilePath != null)
     {
         pageTimestampFile = new OSFile(pageTimestampFilePath, fileParameters);
         long fileLength = pageTimestampFile.Length;
         if (fileLength == 0)
         {
             pageTimestamps = new int[INIT_PAGE_TIMESTAMPS_LENGTH];
         }
         else
         {
             pageTimestamps = new int[(int)(fileLength / 4)];
             byte[] page = new byte[Page.pageSize];
             int    i    = 0;
             for (long pos = 0; pos < fileLength; pos += Page.pageSize)
             {
                 int rc = pageTimestampFile.Read(pos, page);
                 for (int offs = 0; offs < rc; offs += 4)
                 {
                     pageTimestamps[i++] = Bytes.unpack4(page, offs);
                 }
             }
             if (i != pageTimestamps.Length)
             {
                 throw new StorageError(StorageError.ErrorCode.FILE_ACCESS_ERROR);
             }
         }
         dirtyPageTimestampMap = new int[(((pageTimestamps.Length * 4 + Page.pageSize - 1) >> Page.pageSizeLog) + 31) >> 5];
     }
 }
예제 #3
0
        internal void exportMultiFieldIndex(int oid, byte[] data)
        {
            Btree btree = new Btree(data, ObjectHeader.Sizeof);

            storage.assignOid(btree, oid);
            writer.Write(" <Perst.Impl.BtreeMultiFieldIndex id=\"" + oid + "\" unique=\"" + (btree.unique ? '1' : '0')
                         + "\" class=");
            int offs    = exportString(data, Btree.Sizeof);
            int nFields = Bytes.unpack4(data, offs);

            offs += 4;
            for (int i = 0; i < nFields; i++)
            {
                writer.Write(" field" + i + "=");
                offs = exportString(data, offs);
            }
            writer.Write(">\n");
            int nTypes = Bytes.unpack4(data, offs);

            offs            += 4;
            compoundKeyTypes = new ClassDescriptor.FieldType[nTypes];
            for (int i = 0; i < nTypes; i++)
            {
                compoundKeyTypes[i] = (ClassDescriptor.FieldType)Bytes.unpack4(data, offs);
                offs += 4;
            }
            btree.export(this);
            compoundKeyTypes = null;
            writer.Write(" </Perst.Impl.BtreeMultiFieldIndex>\n");
        }
예제 #4
0
 public static decimal unpackDecimal(byte[] arr, int offs)
 {
     int[] bits = new int[4];
     bits[0] = Bytes.unpack4(arr, offs);
     bits[1] = Bytes.unpack4(arr, offs + 4);
     bits[2] = Bytes.unpack4(arr, offs + 8);
     bits[3] = Bytes.unpack4(arr, offs + 12);
     return(new decimal(bits));
 }
예제 #5
0
        public static int skipString(byte[] arr, int offs)
        {
            int len = Bytes.unpack4(arr, offs);

            offs += 4;
            if (len >= 0)
            {
                offs += len * 2;
            }
            else if (len < -1)
            {
                offs -= len + 2;
            }
            return(offs);
        }
예제 #6
0
        void exportCompoundKey(byte[] body, int offs, int size, ClassDescriptor.FieldType type)
        {
            Debug.Assert(type == ClassDescriptor.FieldType.tpArrayOfByte);
            int end = offs + size;

            for (int i = 0; i < compoundKeyTypes.Length; i++)
            {
                type = compoundKeyTypes[i];
                if (type == ClassDescriptor.FieldType.tpArrayOfByte || type == ClassDescriptor.FieldType.tpString)
                {
                    size  = Bytes.unpack4(body, offs);
                    offs += 4;
                }
                writer.Write(" key" + i + "=\"");
                offs = exportKey(body, offs, size, type);
                writer.Write("\"");
            }
            Debug.Assert(offs == end);
        }
예제 #7
0
        internal int exportBinary(byte[] body, int offs)
        {
            int len = Bytes.unpack4(body, offs);

            offs += 4;
            if (len < 0)
            {
                if (len == -2 - (int)ClassDescriptor.FieldType.tpObject)
                {
                    exportRef(Bytes.unpack4(body, offs));
                    offs += 4;
                }
                else if (len < -1)
                {
                    writer.Write("\"#");
                    writer.Write(hexDigit[-2 - len]);
                    len = ClassDescriptor.Sizeof[-2 - len];
                    while (--len >= 0)
                    {
                        byte b = body[offs++];
                        writer.Write(hexDigit[(b >> 4) & 0xF]);
                        writer.Write(hexDigit[b & 0xF]);
                    }
                    writer.Write('\"');
                }
                else
                {
                    writer.Write("null");
                }
            }
            else
            {
                writer.Write('\"');
                while (--len >= 0)
                {
                    byte b = body[offs++];
                    writer.Write(hexDigit[(b >> 4) & 0xF]);
                    writer.Write(hexDigit[b & 0xF]);
                }
                writer.Write('\"');
            }
            return(offs);
        }
예제 #8
0
        internal int exportString(byte[] body, int offs)
        {
            int len = Bytes.unpack4(body, offs);

            offs += 4;
            if (len >= 0)
            {
                writer.Write("\"");
                while (--len >= 0)
                {
                    exportChar((char)Bytes.unpack2(body, offs));
                    offs += 2;
                }
                writer.Write("\"");
            }
            else if (len < -1)
            {
                writer.Write("\"");
                string s;
                if (storage.encoding != null)
                {
                    s = storage.encoding.GetString(body, offs, -len - 2);
                }
                else
                {
                    s = Encoding.Default.GetString(body, offs, -len - 2);
                }
                offs -= len + 2;
                for (int i = 0, n = s.Length; i < n; i++)
                {
                    exportChar(s[i]);
                }
            }
            else
            {
                writer.Write("null");
            }
            return(offs);
        }
예제 #9
0
        public override int compareByteArrays(byte[] key, byte[] item, int offs, int lengtn)
        {
            int o1 = 0;
            int o2 = offs;

            byte[] a1 = key;
            byte[] a2 = item;
            for (int i = 0; i < types.Length && o1 < key.Length; i++)
            {
                int diff = 0;
                switch (types[i])
                {
                case ClassDescriptor.FieldType.tpBoolean:
                case ClassDescriptor.FieldType.tpByte:
                    diff = a1[o1++] - a2[o2++];
                    break;

                case ClassDescriptor.FieldType.tpSByte:
                    diff = (sbyte)a1[o1++] - (sbyte)a2[o2++];
                    break;

                case ClassDescriptor.FieldType.tpShort:
                    diff = Bytes.unpack2(a1, o1) - Bytes.unpack2(a2, o2);
                    o1  += 2;
                    o2  += 2;
                    break;

                case ClassDescriptor.FieldType.tpUShort:
                    diff = (ushort)Bytes.unpack2(a1, o1) - (ushort)Bytes.unpack2(a2, o2);
                    o1  += 2;
                    o2  += 2;
                    break;

                case ClassDescriptor.FieldType.tpChar:
                    diff = (char)Bytes.unpack2(a1, o1) - (char)Bytes.unpack2(a2, o2);
                    o1  += 2;
                    o2  += 2;
                    break;

                case ClassDescriptor.FieldType.tpInt:
                {
                    int i1 = Bytes.unpack4(a1, o1);
                    int i2 = Bytes.unpack4(a2, o2);
                    diff = i1 < i2 ? -1 : i1 == i2 ? 0 : 1;
                    o1  += 4;
                    o2  += 4;
                    break;
                }

                case ClassDescriptor.FieldType.tpUInt:
                case ClassDescriptor.FieldType.tpEnum:
                case ClassDescriptor.FieldType.tpObject:
                case ClassDescriptor.FieldType.tpOid:
                {
                    uint u1 = (uint)Bytes.unpack4(a1, o1);
                    uint u2 = (uint)Bytes.unpack4(a2, o2);
                    diff = u1 < u2 ? -1 : u1 == u2 ? 0 : 1;
                    o1  += 4;
                    o2  += 4;
                    break;
                }

                case ClassDescriptor.FieldType.tpLong:
                {
                    long l1 = Bytes.unpack8(a1, o1);
                    long l2 = Bytes.unpack8(a2, o2);
                    diff = l1 < l2 ? -1 : l1 == l2 ? 0 : 1;
                    o1  += 8;
                    o2  += 8;
                    break;
                }

                case ClassDescriptor.FieldType.tpULong:
                case ClassDescriptor.FieldType.tpDate:
                {
                    ulong l1 = (ulong)Bytes.unpack8(a1, o1);
                    ulong l2 = (ulong)Bytes.unpack8(a2, o2);
                    diff = l1 < l2 ? -1 : l1 == l2 ? 0 : 1;
                    o1  += 8;
                    o2  += 8;
                    break;
                }

                case ClassDescriptor.FieldType.tpFloat:
                {
                    float f1 = Bytes.unpackF4(a1, o1);
                    float f2 = Bytes.unpackF4(a2, o2);
                    diff = f1 < f2 ? -1 : f1 == f2 ? 0 : 1;
                    o1  += 4;
                    o2  += 4;
                    break;
                }

                case ClassDescriptor.FieldType.tpDouble:
                {
                    double d1 = Bytes.unpackF8(a1, o1);
                    double d2 = Bytes.unpackF8(a2, o2);
                    diff = d1 < d2 ? -1 : d1 == d2 ? 0 : 1;
                    o1  += 8;
                    o2  += 8;
                    break;
                }

                case ClassDescriptor.FieldType.tpDecimal:
                {
                    decimal d1 = Bytes.unpackDecimal(a1, o1);
                    decimal d2 = Bytes.unpackDecimal(a2, o2);
                    diff = d1.CompareTo(d2);
                    o1  += 16;
                    o2  += 16;
                    break;
                }

                case ClassDescriptor.FieldType.tpGuid:
                {
                    Guid g1 = Bytes.unpackGuid(a1, o1);
                    Guid g2 = Bytes.unpackGuid(a2, o2);
                    diff = g1.CompareTo(g2);
                    o1  += 16;
                    o2  += 16;
                    break;
                }

                case ClassDescriptor.FieldType.tpString:
                {
                    int len1 = Bytes.unpack4(a1, o1);
                    int len2 = Bytes.unpack4(a2, o2);
                    o1 += 4;
                    o2 += 4;
                    int len = len1 < len2 ? len1 : len2;
                    while (--len >= 0)
                    {
                        diff = (char)Bytes.unpack2(a1, o1) - (char)Bytes.unpack2(a2, o2);
                        if (diff != 0)
                        {
                            return(diff);
                        }
                        o1 += 2;
                        o2 += 2;
                    }
                    diff = len1 - len2;
                    break;
                }

                case ClassDescriptor.FieldType.tpArrayOfByte:
                {
                    int len1 = Bytes.unpack4(a1, o1);
                    int len2 = Bytes.unpack4(a2, o2);
                    o1 += 4;
                    o2 += 4;
                    int len = len1 < len2 ? len1 : len2;
                    while (--len >= 0)
                    {
                        diff = a1[o1++] - a2[o2++];
                        if (diff != 0)
                        {
                            return(diff);
                        }
                    }
                    diff = len1 - len2;
                    break;
                }

                default:
                    Debug.Assert(false, "Invalid type");
                    break;
                }
                if (diff != 0)
                {
                    return(diff);
                }
            }
            return(0);
        }
예제 #10
0
        protected override object unpackByteArrayKey(Page pg, int pos)
        {
            int offs = BtreePage.firstKeyOffs + BtreePage.getKeyStrOffs(pg, pos);

            byte[]   data   = pg.data;
            Object[] values = new Object[types.Length];

            for (int i = 0; i < types.Length; i++)
            {
                Object v = null;
                switch (types[i])
                {
                case ClassDescriptor.FieldType.tpBoolean:
                    v = data[offs++] != 0;
                    break;

                case ClassDescriptor.FieldType.tpSByte:
                    v = (sbyte)data[offs++];
                    break;

                case ClassDescriptor.FieldType.tpByte:
                    v = data[offs++];
                    break;

                case ClassDescriptor.FieldType.tpShort:
                    v     = Bytes.unpack2(data, offs);
                    offs += 2;
                    break;

                case ClassDescriptor.FieldType.tpUShort:
                    v     = (ushort)Bytes.unpack2(data, offs);
                    offs += 2;
                    break;

                case ClassDescriptor.FieldType.tpChar:
                    v     = (char)Bytes.unpack2(data, offs);
                    offs += 2;
                    break;

                case ClassDescriptor.FieldType.tpInt:
                    v     = Bytes.unpack4(data, offs);
                    offs += 4;
                    break;

                case ClassDescriptor.FieldType.tpUInt:
                    v     = (uint)Bytes.unpack4(data, offs);
                    offs += 4;
                    break;

                case ClassDescriptor.FieldType.tpOid:
                case ClassDescriptor.FieldType.tpObject:
                {
                    int oid = Bytes.unpack4(data, offs);
                    v     = oid == 0 ? null : ((StorageImpl)Storage).lookupObject(oid, null);
                    offs += 4;
                    break;
                }

                case ClassDescriptor.FieldType.tpLong:
                    v     = Bytes.unpack8(data, offs);
                    offs += 8;
                    break;

                case ClassDescriptor.FieldType.tpDate:
                {
                    v     = new DateTime(Bytes.unpack8(data, offs));
                    offs += 8;
                    break;
                }

                case ClassDescriptor.FieldType.tpULong:
                    v     = (ulong)Bytes.unpack8(data, offs);
                    offs += 8;
                    break;

                case ClassDescriptor.FieldType.tpFloat:
                    v     = Bytes.unpackF4(data, offs);
                    offs += 4;
                    break;

                case ClassDescriptor.FieldType.tpDouble:
                    v     = Bytes.unpackF8(data, offs);
                    offs += 8;
                    break;

                case ClassDescriptor.FieldType.tpDecimal:
                    v     = Bytes.unpackDecimal(data, offs);
                    offs += 16;
                    break;

                case ClassDescriptor.FieldType.tpGuid:
                    v     = Bytes.unpackGuid(data, offs);
                    offs += 16;
                    break;

                case ClassDescriptor.FieldType.tpString:
                {
                    int len = Bytes.unpack4(data, offs);
                    offs += 4;
                    char[] sval = new char[len];
                    for (int j = 0; j < len; j++)
                    {
                        sval[j] = (char)Bytes.unpack2(pg.data, offs);
                        offs   += 2;
                    }
                    v = new String(sval);
                    break;
                }

                case ClassDescriptor.FieldType.tpArrayOfByte:
                {
                    int len = Bytes.unpack4(data, offs);
                    offs += 4;
                    byte[] val = new byte[len];
                    Array.Copy(pg.data, offs, val, 0, len);
                    offs += len;
                    v     = val;
                    break;
                }

                default:
                    Debug.Assert(false, "Invalid type");
                    break;
                }
                values[i] = v;
            }
            return(values);
        }
 internal static int getItem(Page pg, int index)
 {
     return(Bytes.unpack4(pg.data, firstKeyOffs + index * 4));
 }
예제 #12
0
 internal static int getSize(byte[] arr, int offs)
 {
     return(Bytes.unpack4(arr, offs));
 }
예제 #13
0
        internal void  extract(Page pg, int offs, ClassDescriptor.FieldType type)
        {
            byte[] data = pg.data;

            switch (type)
            {
            case ClassDescriptor.FieldType.tpBoolean:
                key = new Key(data[offs] != 0);
                break;

            case ClassDescriptor.FieldType.tpSByte:
                key = new Key((sbyte)data[offs]);
                break;

            case ClassDescriptor.FieldType.tpByte:
                key = new Key(data[offs]);
                break;

            case ClassDescriptor.FieldType.tpShort:
                key = new Key(Bytes.unpack2(data, offs));
                break;

            case ClassDescriptor.FieldType.tpUShort:
                key = new Key((ushort)Bytes.unpack2(data, offs));
                break;


            case ClassDescriptor.FieldType.tpChar:
                key = new Key((char)Bytes.unpack2(data, offs));
                break;

            case ClassDescriptor.FieldType.tpInt:
                key = new Key(Bytes.unpack4(data, offs));
                break;

            case ClassDescriptor.FieldType.tpEnum:
            case ClassDescriptor.FieldType.tpUInt:
            case ClassDescriptor.FieldType.tpObject:
            case ClassDescriptor.FieldType.tpOid:
                key = new Key((uint)Bytes.unpack4(data, offs));
                break;

            case ClassDescriptor.FieldType.tpLong:
                key = new Key(Bytes.unpack8(data, offs));
                break;

            case ClassDescriptor.FieldType.tpDate:
            case ClassDescriptor.FieldType.tpULong:
                key = new Key((ulong)Bytes.unpack8(data, offs));
                break;

            case ClassDescriptor.FieldType.tpFloat:
                key = new Key(Bytes.unpackF4(data, offs));
                break;

            case ClassDescriptor.FieldType.tpDouble:
                key = new Key(Bytes.unpackF8(data, offs));
                break;

            case ClassDescriptor.FieldType.tpGuid:
                key = new Key(Bytes.unpackGuid(data, offs));
                break;

            case ClassDescriptor.FieldType.tpDecimal:
                key = new Key(Bytes.unpackDecimal(data, offs));
                break;

            default:
                Debug.Assert(false, "Invalid type");
                break;
            }
        }
        public void run()
        {
            try
            {
                byte[] buf = new byte[Page.pageSize + PAGE_DATA_OFFSET + (pageTimestamps != null ? 4 : 0)];

                while (listening)
                {
                    int offs = 0;
                    do
                    {
                        int rc = -1;
                        try
                        {
                            if (socket != null)
                            {
                                ArrayList recvSocks = new ArrayList(1);
                                recvSocks.Add(socket);
                                Socket.Select(recvSocks, null, null, replicationReceiveTimeout * 2000);
                                if (recvSocks.Count == 1)
                                {
                                    rc = socket.Receive(buf, offs, buf.Length - offs, SocketFlags.None);
                                }
                                else
                                {
                                    Console.WriteLine("Receive timeout expired");
                                }
                            }
                        }
                        catch (SocketException x)
                        {
                            Console.WriteLine("Failed to receive data from master: " + x);
                            rc = -1;
                        }
                        lock (done)
                        {
                            if (!listening)
                            {
                                return;
                            }
                        }
                        if (rc < 0)
                        {
                            HandleError();
                            hangup();
                            return;
                        }
                        else
                        {
                            offs += rc;
                        }
                    } while (offs < buf.Length);

                    long pos = Bytes.unpack8(buf, 0);
                    bool transactionCommit = false;
                    if (pos == 0)
                    {
                        if (replicationAck)
                        {
                            try
                            {
                                socket.Send(buf, 0, 1, SocketFlags.None);
                            }
                            catch (SocketException x)
                            {
                                Console.WriteLine("Failed to send request to master: " + x);
                                HandleError();
                                hangup();
                                return;
                            }
                        }
                        if (buf[PAGE_DATA_OFFSET + DB_HDR_CURR_INDEX_OFFSET] != prevIndex)
                        {
                            prevIndex = buf[PAGE_DATA_OFFSET + DB_HDR_CURR_INDEX_OFFSET];
                            lck.ExclusiveLock();
                            transactionCommit = true;
                        }
                    }
                    else if (pos == REPL_SYNC)
                    {
                        lock (sync)
                        {
                            outOfSync = false;
                            Monitor.Pulse(sync);
                        }
                        continue;
                    }
                    else if (pos == REPL_PING)
                    {
                        continue;
                    }
                    else if (pos == REPL_CLOSE)
                    {
                        hangup();
                        return;
                    }

                    if (pageTimestamps != null)
                    {
                        int pageNo = (int)(pos >> Page.pageSizeLog);
                        if (pageNo >= pageTimestamps.Length)
                        {
                            int newLength = pageNo >= pageTimestamps.Length * 2 ? pageNo + 1 : pageTimestamps.Length * 2;

                            int[] newPageTimestamps = new int[newLength];
                            Array.Copy(pageTimestamps, 0, newPageTimestamps, 0, pageTimestamps.Length);
                            pageTimestamps = newPageTimestamps;

                            int[] newDirtyPageTimestampMap = new int[(((newLength * 4 + Page.pageSize - 1) >> Page.pageSizeLog) + 31) >> 5];
                            Array.Copy(dirtyPageTimestampMap, 0, newDirtyPageTimestampMap, 0, dirtyPageTimestampMap.Length);
                            dirtyPageTimestampMap = newDirtyPageTimestampMap;
                        }
                        int timestamp = Bytes.unpack4(buf, Page.pageSize + PAGE_DATA_OFFSET);
                        pageTimestamps[pageNo] = timestamp;
                        dirtyPageTimestampMap[pageNo >> (Page.pageSizeLog - 2 + 5)] |= 1 << ((pageNo >> (Page.pageSizeLog - 2)) & 31);
                    }

                    Page pg = pool.putPage(pos);
                    Array.Copy(buf, PAGE_DATA_OFFSET, pg.data, 0, Page.pageSize);
                    pool.unfix(pg);

                    if (pos == 0)
                    {
                        if (!initialized && buf[PAGE_DATA_OFFSET + DB_HDR_INITIALIZED_OFFSET] != 0)
                        {
                            lock (init)
                            {
                                initialized = true;
                                Monitor.Pulse(init);
                            }
                        }
                        if (transactionCommit)
                        {
                            lck.Unlock();
                            lock (commit)
                            {
                                Monitor.PulseAll(commit);
                            }
                            if (listener != null)
                            {
                                listener.OnMasterDatabaseUpdate();
                            }
                            pool.flush();
                            if (pageTimestamps != null)
                            {
                                byte[] page = new byte[Page.pageSize];
                                for (int i = 0; i < dirtyPageTimestampMap.Length; i++)
                                {
                                    if (dirtyPageTimestampMap[i] != 0)
                                    {
                                        for (int j = 0; j < 32; j++)
                                        {
                                            if ((dirtyPageTimestampMap[i] & (1 << j)) != 0)
                                            {
                                                int pageNo = (i << 5) + j;
                                                int beg    = pageNo << (Page.pageSizeLog - 2);
                                                int end    = beg + Page.pageSize / 4;
                                                if (end > pageTimestamps.Length)
                                                {
                                                    end = pageTimestamps.Length;
                                                }
                                                offs = 0;
                                                while (beg < end)
                                                {
                                                    Bytes.pack4(page, offs, pageTimestamps[beg]);
                                                    beg  += 1;
                                                    offs += 4;
                                                }
                                                pageTimestampFile.Write(pageNo << Page.pageSizeLog, page);
                                            }
                                        }
                                    }
                                    dirtyPageTimestampMap[i] = 0;
                                }
                                pageTimestampFile.Sync();
                            }
                        }
                    }
                }
            }
            finally
            {
                listening = false;
                lock (init)
                {
                    Monitor.Pulse(init);
                }
                lock (sync)
                {
                    Monitor.Pulse(sync);
                }
            }
        }
예제 #15
0
        int exportKey(byte[] body, int offs, int size, ClassDescriptor.FieldType type)
        {
            switch (type)
            {
            case ClassDescriptor.FieldType.tpBoolean:
                writer.Write(body[offs++] != 0?"1":"0");
                break;

            case ClassDescriptor.FieldType.tpByte:
                writer.Write(System.Convert.ToString((byte)body[offs++]));
                break;

            case ClassDescriptor.FieldType.tpSByte:
                writer.Write(System.Convert.ToString((sbyte)body[offs++]));
                break;

            case ClassDescriptor.FieldType.tpChar:
                writer.Write(System.Convert.ToString((ushort)Bytes.unpack2(body, offs)));
                offs += 2;
                break;

            case ClassDescriptor.FieldType.tpShort:
                writer.Write(System.Convert.ToString((ushort)Bytes.unpack2(body, offs)));
                offs += 2;
                break;

            case ClassDescriptor.FieldType.tpUShort:
                writer.Write(System.Convert.ToString((ushort)Bytes.unpack2(body, offs)));
                offs += 2;
                break;

            case ClassDescriptor.FieldType.tpInt:
                writer.Write(System.Convert.ToString(Bytes.unpack4(body, offs)));
                offs += 4;
                break;

            case ClassDescriptor.FieldType.tpUInt:
            case ClassDescriptor.FieldType.tpObject:
            case ClassDescriptor.FieldType.tpEnum:
                writer.Write(System.Convert.ToString((uint)Bytes.unpack4(body, offs)));
                offs += 4;
                break;

            case ClassDescriptor.FieldType.tpLong:
                writer.Write(System.Convert.ToString(Bytes.unpack8(body, offs)));
                offs += 8;
                break;

            case ClassDescriptor.FieldType.tpULong:
                writer.Write(System.Convert.ToString((ulong)Bytes.unpack8(body, offs)));
                offs += 8;
                break;

            case ClassDescriptor.FieldType.tpFloat:
                writer.Write(System.Convert.ToString(Bytes.unpackF4(body, offs)));
                offs += 4;
                break;

            case ClassDescriptor.FieldType.tpDouble:
                writer.Write(System.Convert.ToString(Bytes.unpackF8(body, offs)));
                offs += 8;
                break;

            case ClassDescriptor.FieldType.tpGuid:
                writer.Write(Bytes.unpackGuid(body, offs).ToString());
                offs += 16;
                break;

            case ClassDescriptor.FieldType.tpDecimal:
                writer.Write(Bytes.unpackDecimal(body, offs).ToString());
                offs += 16;
                break;

            case ClassDescriptor.FieldType.tpString:
                for (int i = 0; i < size; i++)
                {
                    exportChar((char)Bytes.unpack2(body, offs));
                    offs += 2;
                }
                break;

            case ClassDescriptor.FieldType.tpArrayOfByte:
                for (int i = 0; i < size; i++)
                {
                    byte b = body[offs++];
                    writer.Write(hexDigit[(b >> 4) & 0xF]);
                    writer.Write(hexDigit[b & 0xF]);
                }
                break;

            case ClassDescriptor.FieldType.tpDate:
                writer.Write(Bytes.unpackDate(body, offs).ToString());
                offs += 8;
                break;

            default:
                Debug.Assert(false, "Invalid type");
                break;
            }
            return(offs);
        }
 private ReplicationMasterFile(ReplicationMasterStorageImpl storage, IFile file, string localhost, int port, string[] hosts, bool ack, String pageTimestampFilePath)
 {
     this.storage   = storage;
     this.file      = file;
     this.ack       = ack;
     this.localhost = localhost;
     this.port      = port;
     mutex          = new object();
     replicas       = new Replica[hosts.Length];
     rcBuf          = new byte[1];
     nHosts         = 0;
     if (pageTimestampFilePath != null)
     {
         FileParameters fileParameters = storage != null ? storage.fileParameters : new FileParameters(false, false, false, 1024 * 1024);
         pageTimestampFile = new OSFile(pageTimestampFilePath, fileParameters);
         long fileLength = pageTimestampFile.Length;
         if (fileLength == 0)
         {
             pageTimestamps = new int[InitPageTimestampsLength];
         }
         else
         {
             pageTimestamps = new int[(int)(fileLength / 4)];
             byte[] page = new byte[Page.pageSize];
             int    i    = 0;
             for (long pos = 0; pos < fileLength; pos += Page.pageSize)
             {
                 int rc = pageTimestampFile.Read(pos, page);
                 for (int offs = 0; offs < rc; offs += 4, i++)
                 {
                     pageTimestamps[i] = Bytes.unpack4(page, offs);
                     if (pageTimestamps[i] > timestamp)
                     {
                         timestamp = pageTimestamps[i];
                     }
                 }
             }
             if (i != pageTimestamps.Length)
             {
                 throw new StorageError(StorageError.ErrorCode.FILE_ACCESS_ERROR);
             }
         }
         dirtyPageTimestampMap = new int[(((pageTimestamps.Length * 4 + Page.pageSize - 1) >> Page.pageSizeLog) + 31) >> 5];
         txBuf = new byte[12 + Page.pageSize];
     }
     else
     {
         txBuf = new byte[8 + Page.pageSize];
     }
     for (int i = 0; i < hosts.Length; i++)
     {
         replicas[i]      = new Replica();
         replicas[i].host = hosts[i];
         Connect(i);
     }
     if (port >= 0)
     {
         storage.SetProperty("perst.alternative.btree", true); // prevent direct modification of pages
         listenSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
         listenSocket.Bind(new IPEndPoint(localhost != null && localhost != "localhost" ? IPAddress.Parse(localhost) : IPAddress.Any, port));
         listenSocket.Listen(ListenQueueSize);
         listening    = true;
         listenThread = new Thread(new ThreadStart(run));
         listenThread.Start();
     }
     watchdogThread = new Thread(new ThreadStart(watchdog));
     watchdogThread.Start();
 }
        void synchronizeNewSlaveNode(int i)
        {
            long size = storage.DatabaseSize;

            int[]  syncNodeTimestamps = null;
            byte[] txBuf;
            if (pageTimestamps != null)
            {
                txBuf = new byte[12 + Page.pageSize];
                byte[] psBuf = new byte[4];
                if (!Receive(i, psBuf))
                {
                    Console.WriteLine("Failed to receive page timestamps length from slave node " + replicas[i].host);
                    return;
                }
                int psSize = Bytes.unpack4(psBuf, 0);
                psBuf = new byte[psSize * 4];
                if (!Receive(i, psBuf))
                {
                    Console.WriteLine("Failed to receive page timestamps from slave node " + replicas[i].host);
                    return;
                }
                syncNodeTimestamps = new int[psSize];
                for (int j = 0; j < psSize; j++)
                {
                    syncNodeTimestamps[j] = Bytes.unpack4(psBuf, j * 4);
                }
            }
            else
            {
                txBuf = new byte[8 + Page.pageSize];
            }
            for (long pos = 0; pos < size; pos += Page.pageSize)
            {
                int pageNo = (int)(pos >> Page.pageSizeLog);
                if (syncNodeTimestamps != null)
                {
                    if (pageNo < syncNodeTimestamps.Length &&
                        pageNo < pageTimestamps.Length &&
                        syncNodeTimestamps[pageNo] == pageTimestamps[pageNo])
                    {
                        continue;
                    }
                }
                lock (storage)
                {
                    lock (storage.objectCache)
                    {
                        Page pg = storage.pool.getPage(pos);
                        Bytes.pack8(txBuf, 0, pos);
                        Array.Copy(pg.data, 0, txBuf, 8, Page.pageSize);
                        storage.pool.unfix(pg);
                        if (syncNodeTimestamps != null)
                        {
                            Bytes.pack4(txBuf, Page.pageSize + 8, pageNo < pageTimestamps.Length ? pageTimestamps[pageNo] : 0);
                        }
                    }
                }
                if (!Send(i, txBuf))
                {
                    return;
                }
                if (ack && pos == 0 && !Receive(i, rcBuf))
                {
                    Console.WriteLine("Failed to receive ACK from node " + replicas[i].host);
                    return;
                }
            }
            Bytes.pack8(txBuf, 0, ReplicationSlaveStorageImpl.REPL_SYNC);
            Send(i, txBuf);
        }
예제 #18
0
        internal int exportObject(ClassDescriptor desc, byte[] body, int offs, int indent)
        {
            ClassDescriptor.FieldDescriptor[] all = desc.allFields;

            for (int i = 0, n = all.Length; i < n; i++)
            {
                ClassDescriptor.FieldDescriptor fd = all[i];
                FieldInfo f = fd.field;
                indentation(indent);
                String fieldName = exportIdentifier(fd.fieldName);
                writer.Write("<" + fieldName + ">");
                switch (fd.type)
                {
                case ClassDescriptor.FieldType.tpBoolean:
                    writer.Write(body[offs++] != 0?"1":"0");
                    break;

                case ClassDescriptor.FieldType.tpByte:
                    writer.Write(System.Convert.ToString((byte)body[offs++]));
                    break;

                case ClassDescriptor.FieldType.tpSByte:
                    writer.Write(System.Convert.ToString((sbyte)body[offs++]));
                    break;

                case ClassDescriptor.FieldType.tpChar:
                    writer.Write(System.Convert.ToString((ushort)Bytes.unpack2(body, offs)));
                    offs += 2;
                    break;

                case ClassDescriptor.FieldType.tpShort:
                    writer.Write(System.Convert.ToString((ushort)Bytes.unpack2(body, offs)));
                    offs += 2;
                    break;

                case ClassDescriptor.FieldType.tpUShort:
                    writer.Write(System.Convert.ToString((ushort)Bytes.unpack2(body, offs)));
                    offs += 2;
                    break;

                case ClassDescriptor.FieldType.tpInt:
                    writer.Write(System.Convert.ToString(Bytes.unpack4(body, offs)));
                    offs += 4;
                    break;

                case ClassDescriptor.FieldType.tpEnum:
                    writer.Write(Enum.ToObject(f.FieldType, Bytes.unpack4(body, offs)));
                    offs += 4;
                    break;

                case ClassDescriptor.FieldType.tpUInt:
                    writer.Write(System.Convert.ToString((uint)Bytes.unpack4(body, offs)));
                    offs += 4;
                    break;

                case ClassDescriptor.FieldType.tpLong:
                    writer.Write(System.Convert.ToString(Bytes.unpack8(body, offs)));
                    offs += 8;
                    break;

                case ClassDescriptor.FieldType.tpULong:
                    writer.Write(System.Convert.ToString((ulong)Bytes.unpack8(body, offs)));
                    offs += 8;
                    break;

                case ClassDescriptor.FieldType.tpFloat:
                    writer.Write(System.Convert.ToString(Bytes.unpackF4(body, offs)));
                    offs += 4;
                    break;

                case ClassDescriptor.FieldType.tpDouble:
                    writer.Write(System.Convert.ToString(Bytes.unpackF8(body, offs)));
                    offs += 8;
                    break;

                case ClassDescriptor.FieldType.tpGuid:
                    writer.Write("\"" + Bytes.unpackGuid(body, offs) + "\"");
                    offs += 16;
                    break;

                case ClassDescriptor.FieldType.tpDecimal:
                    writer.Write("\"" + Bytes.unpackDecimal(body, offs) + "\"");
                    offs += 16;
                    break;

                case ClassDescriptor.FieldType.tpString:
                    offs = exportString(body, offs);
                    break;

                case ClassDescriptor.FieldType.tpDate:
                {
                    long msec = Bytes.unpack8(body, offs);
                    offs += 8;
                    if (msec >= 0)
                    {
                        writer.Write("\"" + new System.DateTime(msec) + "\"");
                    }
                    else
                    {
                        writer.Write("null");
                    }
                    break;
                }

                case ClassDescriptor.FieldType.tpObject:
                    exportRef(Bytes.unpack4(body, offs));
                    offs += 4;
                    break;

                case ClassDescriptor.FieldType.tpValue:
                    writer.Write('\n');
                    offs = exportObject(fd.valueDesc, body, offs, indent + 1);
                    indentation(indent);
                    break;

#if SUPPORT_RAW_TYPE
                case ClassDescriptor.FieldType.tpRaw:
#endif
                case ClassDescriptor.FieldType.tpArrayOfByte:
                case ClassDescriptor.FieldType.tpArrayOfSByte:
                    offs = exportBinary(body, offs);
                    break;

                case ClassDescriptor.FieldType.tpArrayOfBoolean:
                {
                    int len = Bytes.unpack4(body, offs);
                    offs += 4;
                    if (len < 0)
                    {
                        writer.Write("null");
                    }
                    else
                    {
                        writer.Write('\n');
                        while (--len >= 0)
                        {
                            indentation(indent + 1);
                            writer.Write("<element>" + (body[offs++] != 0?"1":"0") + "</element>\n");
                        }
                        indentation(indent);
                    }
                    break;
                }

                case ClassDescriptor.FieldType.tpArrayOfChar:
                {
                    int len = Bytes.unpack4(body, offs);
                    offs += 4;
                    if (len < 0)
                    {
                        writer.Write("null");
                    }
                    else
                    {
                        writer.Write('\n');
                        while (--len >= 0)
                        {
                            indentation(indent + 1);
                            writer.Write("<element>" + (Bytes.unpack2(body, offs) & 0xFFFF) + "</element>\n");
                            offs += 2;
                        }
                        indentation(indent);
                    }
                    break;
                }

                case ClassDescriptor.FieldType.tpArrayOfShort:
                {
                    int len = Bytes.unpack4(body, offs);
                    offs += 4;
                    if (len < 0)
                    {
                        writer.Write("null");
                    }
                    else
                    {
                        writer.Write('\n');
                        while (--len >= 0)
                        {
                            indentation(indent + 1);
                            writer.Write("<element>" + Bytes.unpack2(body, offs) + "</element>\n");
                            offs += 2;
                        }
                        indentation(indent);
                    }
                    break;
                }

                case ClassDescriptor.FieldType.tpArrayOfUShort:
                {
                    int len = Bytes.unpack4(body, offs);
                    offs += 4;
                    if (len < 0)
                    {
                        writer.Write("null");
                    }
                    else
                    {
                        writer.Write('\n');
                        while (--len >= 0)
                        {
                            indentation(indent + 1);
                            writer.Write("<element>" + (ushort)Bytes.unpack2(body, offs) + "</element>\n");
                            offs += 2;
                        }
                        indentation(indent);
                    }
                    break;
                }

                case ClassDescriptor.FieldType.tpArrayOfInt:
                {
                    int len = Bytes.unpack4(body, offs);
                    offs += 4;
                    if (len < 0)
                    {
                        writer.Write("null");
                    }
                    else
                    {
                        writer.Write('\n');
                        while (--len >= 0)
                        {
                            indentation(indent + 1);
                            writer.Write("<element>" + Bytes.unpack4(body, offs) + "</element>\n");
                            offs += 4;
                        }
                        indentation(indent);
                    }
                    break;
                }

                case ClassDescriptor.FieldType.tpArrayOfEnum:
                {
                    int len = Bytes.unpack4(body, offs);
                    offs += 4;
                    if (len < 0)
                    {
                        writer.Write("null");
                    }
                    else
                    {
                        Type elemType = f.FieldType.GetElementType();
                        writer.Write('\n');
                        while (--len >= 0)
                        {
                            indentation(indent + 1);
                            writer.Write("<element>" + Enum.ToObject(elemType, Bytes.unpack4(body, offs)) + "</element>\n");
                            offs += 4;
                        }
                        indentation(indent);
                    }
                    break;
                }

                case ClassDescriptor.FieldType.tpArrayOfUInt:
                {
                    int len = Bytes.unpack4(body, offs);
                    offs += 4;
                    if (len < 0)
                    {
                        writer.Write("null");
                    }
                    else
                    {
                        writer.Write('\n');
                        while (--len >= 0)
                        {
                            indentation(indent + 1);
                            writer.Write("<element>" + (uint)Bytes.unpack4(body, offs) + "</element>\n");
                            offs += 4;
                        }
                        indentation(indent);
                    }
                    break;
                }

                case ClassDescriptor.FieldType.tpArrayOfLong:
                {
                    int len = Bytes.unpack4(body, offs);
                    offs += 4;
                    if (len < 0)
                    {
                        writer.Write("null");
                    }
                    else
                    {
                        writer.Write('\n');
                        while (--len >= 0)
                        {
                            indentation(indent + 1);
                            writer.Write("<element>" + Bytes.unpack8(body, offs) + "</element>\n");
                            offs += 8;
                        }
                        indentation(indent);
                    }
                    break;
                }

                case ClassDescriptor.FieldType.tpArrayOfULong:
                {
                    int len = Bytes.unpack4(body, offs);
                    offs += 4;
                    if (len < 0)
                    {
                        writer.Write("null");
                    }
                    else
                    {
                        writer.Write('\n');
                        while (--len >= 0)
                        {
                            indentation(indent + 1);
                            writer.Write("<element>" + (ulong)Bytes.unpack8(body, offs) + "</element>\n");
                            offs += 8;
                        }
                        indentation(indent);
                    }
                    break;
                }

                case ClassDescriptor.FieldType.tpArrayOfFloat:
                {
                    int len = Bytes.unpack4(body, offs);
                    offs += 4;
                    if (len < 0)
                    {
                        writer.Write("null");
                    }
                    else
                    {
                        writer.Write('\n');
                        while (--len >= 0)
                        {
                            indentation(indent + 1);
                            writer.Write("<element>" + Bytes.unpackF4(body, offs) + "</element>\n");
                            offs += 4;
                        }
                        indentation(indent);
                    }
                    break;
                }

                case ClassDescriptor.FieldType.tpArrayOfDouble:
                {
                    int len = Bytes.unpack4(body, offs);
                    offs += 4;
                    if (len < 0)
                    {
                        writer.Write("null");
                    }
                    else
                    {
                        writer.Write('\n');
                        while (--len >= 0)
                        {
                            indentation(indent + 1);
                            writer.Write("<element>" + Bytes.unpackF8(body, offs) + "</element>\n");
                            offs += 8;
                        }
                        indentation(indent);
                    }
                    break;
                }

                case ClassDescriptor.FieldType.tpArrayOfDate:
                {
                    int len = Bytes.unpack4(body, offs);
                    offs += 4;
                    if (len < 0)
                    {
                        writer.Write("null");
                    }
                    else
                    {
                        writer.Write('\n');
                        while (--len >= 0)
                        {
                            indentation(indent + 1);
                            writer.Write("<element>\"" + Bytes.unpackDate(body, offs) + "\"</element>\n");
                            offs += 8;
                        }
                    }
                    break;
                }

                case ClassDescriptor.FieldType.tpArrayOfGuid:
                {
                    int len = Bytes.unpack4(body, offs);
                    offs += 4;
                    if (len < 0)
                    {
                        writer.Write("null");
                    }
                    else
                    {
                        writer.Write('\n');
                        while (--len >= 0)
                        {
                            writer.Write("<element>\"" + Bytes.unpackGuid(body, offs) + "\"</element>\n");
                            offs += 16;
                        }
                    }
                    break;
                }

                case ClassDescriptor.FieldType.tpArrayOfDecimal:
                {
                    int len = Bytes.unpack4(body, offs);
                    offs += 4;
                    if (len < 0)
                    {
                        writer.Write("null");
                    }
                    else
                    {
                        writer.Write('\n');
                        while (--len >= 0)
                        {
                            writer.Write("<element>\"" + Bytes.unpackDecimal(body, offs) + "\"</element>\n");
                            offs += 16;
                        }
                    }
                    break;
                }

                case ClassDescriptor.FieldType.tpArrayOfString:
                {
                    int len = Bytes.unpack4(body, offs);
                    offs += 4;
                    if (len < 0)
                    {
                        writer.Write("null");
                    }
                    else
                    {
                        writer.Write('\n');
                        while (--len >= 0)
                        {
                            indentation(indent + 1);
                            writer.Write("<element>");
                            offs = exportString(body, offs);
                            writer.Write("</element>\n");
                        }
                        indentation(indent);
                    }
                    break;
                }

                case ClassDescriptor.FieldType.tpLink:
                case ClassDescriptor.FieldType.tpArrayOfObject:
                {
                    int len = Bytes.unpack4(body, offs);
                    offs += 4;
                    if (len < 0)
                    {
                        writer.Write("null");
                    }
                    else
                    {
                        writer.Write('\n');
                        while (--len >= 0)
                        {
                            indentation(indent + 1);
                            int oid = Bytes.unpack4(body, offs);
                            if (oid != 0 && (exportedBitmap[oid >> 5] & (1 << (oid & 31))) == 0)
                            {
                                markedBitmap[oid >> 5] |= 1 << (oid & 31);
                            }
                            writer.Write("<element><ref id=\"" + oid + "\"/></element>\n");
                            offs += 4;
                        }
                        indentation(indent);
                    }
                    break;
                }

                case ClassDescriptor.FieldType.tpArrayOfValue:
                {
                    int len = Bytes.unpack4(body, offs);
                    offs += 4;
                    if (len < 0)
                    {
                        writer.Write("null");
                    }
                    else
                    {
                        writer.Write('\n');
                        while (--len >= 0)
                        {
                            indentation(indent + 1);
                            writer.Write("<element>\n");
                            offs = exportObject(fd.valueDesc, body, offs, indent + 2);
                            indentation(indent + 1);
                            writer.Write("</element>\n");
                        }
                        indentation(indent);
                    }
                    break;
                }

#if SUPPORT_RAW_TYPE
                case ClassDescriptor.FieldType.tpArrayOfRaw:
                {
                    int len = Bytes.unpack4(body, offs);
                    offs += 4;
                    if (len < 0)
                    {
                        writer.Write("null");
                    }
                    else
                    {
                        writer.Write('\n');
                        while (--len >= 0)
                        {
                            indentation(indent + 1);
                            writer.Write("<element>");
                            offs = exportBinary(body, offs);
                            writer.Write("</element>\n");
                        }
                        indentation(indent);
                    }
                    break;
                }
#endif
                }
                writer.Write("</" + fieldName + ">\n");
            }
            return(offs);
        }