示例#1
0
文件: VSpace.cs 项目: ivvinokurov/VSX
        /// <summary>
        /// Delete existing index
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        public void DeleteIndex(string name)
        {
            if (IndexSpace != null)
            {
                IndexSpace.DeleteIndex(DEFS.PrepareFullIndexName(this.Name, name));
            }
            else
            {
                VSIndex x = this.get_index(name);
                if (x == null)
                {
                    throw new VSException(DEFS.E0052_DELETE_INDEX_ERROR_CODE, "- index is not found - '" + name + "'");
                }

                // Remove all references
                VSIndex ref_x = get_index(DEFS.PrepareFullIndexName(DEFS.ParseIndexSpace(name), DEFS.INDEX_CROSS_REFERENCES));
                x.Reset();
                while (x.Next())
                {
                    long[] refs = x.CurrentRefs;
                    for (int i = 0; i < refs.Length; i++)
                    {
                        byte[] key = VSLib.ConvertLongToByte(refs[i]);
                        ref_x.delete_node(key, x.CurrentAvlNode.ID);
                    }
                }

                index_list.Remove(x);
                index_list_full.Remove(x);
                x.purge();
            }
        }
示例#2
0
        /// <summary>
        /// Write FBQE
        /// </summary>
        /// <param name="f"></param>
        private void SerializeFBQE(FBQE f)
        {
            VSLib.CopyBytes(buffer, VSLib.ConvertStringToByte(DEFS.FBQE_SIGNATURE), f.address + SG_POS, SG_LEN);
            VSLib.CopyBytes(buffer, VSLib.ConvertLongToByte(f.ADDRESS_START), f.address + ADDRESS_START_POS, ADDRESS_START_LEN);
            VSLib.CopyBytes(buffer, VSLib.ConvertLongToByte(f.ADDRESS_END), f.address + ADDRESS_END_POS, ADDRESS_END_LEN);
            VSLib.CopyBytes(buffer, VSLib.ConvertLongToByte(f.LENGTH), f.address + LENGTH_POS, LENGTH_LEN);
            VSLib.CopyBytes(buffer, VSLib.ConvertIntToByte(f.PREV), f.address + PREV_POS, PREV_LEN);
            VSLib.CopyBytes(buffer, VSLib.ConvertIntToByte(f.NEXT), f.address + NEXT_POS, NEXT_LEN);

            F_Object.Write(f.address, VSLib.GetByteArray(buffer, f.address, FBQE_LENGTH), FBQE_LENGTH);
        }
示例#3
0
        /// <summary>
        /// Delete reference
        /// </summary>
        /// <param name="rf"></param>
        /// <returns></returns>
        internal bool delete_ref(long rf)
        {
            int         x    = -1;
            List <long> refs = REFS.ToList <long>();

            int count = refs.Count;

            for (int i = 0; i < count; i++)
            {
                int i2 = count - 1 - i;
                if (i > i2)
                {
                    break;
                }

                if (refs[i] == rf)
                {
                    x = i;
                }
                else if (refs[i2] == rf)
                {
                    x = i2;
                }

                if (x > 0)
                {
                    break;
                }
            }

            if (x < 0)
            {
                return(false);
            }
            else
            {
                refs.RemoveAt(x);
            }

            byte[] refs_new = new byte[refs.Count * 8];

            for (int i = 0; i < refs.Count; i++)
            {
                VSLib.CopyBytes(refs_new, VSLib.ConvertLongToByte(refs[i]), (i * 8), 8);
            }

            ALLOCATION.Write(this.REF_POS, refs_new, refs_new.Length);        // Write

            REF_COUNT = refs.Count;

            return(true);
        }
示例#4
0
        /// <summary>
        /// Lock current directory(all spaces)
        /// </summary>
        /// <returns></returns>
        private bool Lock()
        {
            if (IMO)
            {
                return(true);
            }

            byte[] shared_code           = { 0x0F, 0, 0, 0, 0, 0, 0, 0 };
            byte[] exclusive_code        = { 0xFF, 0, 0, 0, 0, 0, 0, 0 };
            long   exclusive_lock_offset = 0;

            string lock_fn = root_path + "\\" + DEFS.LOCK_FILE_NAME;

            if (fslck == null)
            {
                lock_number = -1;
                if (!File.Exists(lock_fn))
                {
                    byte[] b = new byte[8192];
                    fslck = File.Create(lock_fn);
                    fslck.Write(b, 0, b.Length);
                    fslck.Close();
                    fslck = null;
                }

                fslck = File.Open(lock_fn, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite);
                long number = fslck.Length / lock_length;

                try
                {
                    fslck.Lock(exclusive_lock_offset, fslck.Length);           // Lock for both read/write exclusively
                    lock_number = 0;
                    fslck.Seek(lock_number, SeekOrigin.Begin);
                    fslck.Write(exclusive_code, 0, exclusive_code.Length);
                    fslck.Write(VSLib.ConvertLongToByte(DateTime.Now.ToBinary()), 0, 8);
                }
                catch (IOException e)
                {
                    this.Error = e.Message;
                    fslck.Close();
                    fslck = null;
                }
                return(lock_number >= 0);
            }
            else
            {
                return(true);
            }
        }
示例#5
0
        /// <summary>
        /// Convert long to byte array
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        private static string GetAddressSignature(long value)
        {
            //string s = VSLib.ConvertLongToHexString(value);

            byte[] b = VSLib.ConvertLongToByte(value);
            int    n = 0;

            for (int i = 0; i < b.Length; i++)
            {
                n += b[i] + (i * 8);
                if (n > 9999)
                {
                    n -= 9999;
                }
            }

            return(n.ToString("D4"));
        }
示例#6
0
 /// <summary>
 /// Write DateTime
 /// </summary>
 /// <param name="address"></param>
 /// <param name="data"></param>
 /// <returns></returns>
 public void Write(long address, DateTime data)
 {
     Write(address, VSLib.ConvertLongToByte(data.Ticks), 8);
 }
示例#7
0
 /// <summary>
 /// Write data (long)
 /// </summary>
 /// <param name="address"></param>
 /// <param name="data"></param>
 /// <returns></returns>
 public void Write(long address, long data)
 {
     Write(address, VSLib.ConvertLongToByte(data), 8);
 }
示例#8
0
        /// <summary>
        /// Serialize all fields to object fields space
        /// Free excessive chunks if needed
        /// </summary>
        private void serialize()
        {
            // If no fields
            if (FCache.Count == 0)
            {
                set_alloc(ALLOC_RESET);
                FIELDS_SIZE = 0;
                FreeSpace   = -1;
                FCache      = null;
                return;
            }

            byte[] b        = null;
            int    old_size = (int)(FIELDS_SIZE);                  // Current used size (number of fields + all fields size)

            // 1. Calculate new size
            int new_size = FIRST_FIELD_OFFSET_REL;

            for (int i = 0; i < FCache.Count; i++)
            {
                new_size += FCache[i].FULL_LENGTH;
            }

            // 2. Check if space is availabe, extend if required
            if (new_size > (old_size + FreeSpace))
            {
                sp.Extend(this, (new_size - old_size));
            }

            // 3. Check if only value update is required

            List <FieldCache> afc = FCache;

            FCache = new List <FieldCache>(32);

            int array_size = (new_size > old_size) ? new_size : old_size;

            byte[] data = new byte[array_size];


            int data_pos = FIRST_FIELD_OFFSET_REL;

            VSLib.CopyBytes(data, VSLib.ConvertIntToByte(new_size), FIELDS_SIZE_POS, FIELDS_SIZE_LEN);                          // Size
            VSLib.CopyBytes(data, VSLib.ConvertShortToByte((short)afc.Count), FIELDS_NUMBER_POS, FIELDS_NUMBER_LEN);            // Fields number

            FCache.Clear();
            for (int i = 0; i < afc.Count; i++)
            {
                FieldCache fc_element = afc[i];
                if (!fc_element.DELETED)
                {
                    fc_element.OFFSET = data_pos;

                    // Type
                    data[data_pos] = fc_element.TYPE;
                    data_pos++;

                    // Name length
                    data[data_pos] = (byte)(fc_element.NAME.Length);
                    data_pos++;

                    // Name
                    b = VSLib.ConvertStringToByte(fc_element.NAME);
                    VSLib.CopyBytes(data, b, data_pos, b.Length);
                    data_pos += b.Length;

                    // Value
                    if (FIELD_COMPRESS[fc_element.TYPE])                                                              // int/long/decimal
                    {
                        data[data_pos] = (byte)(fc_element.LENGTH);
                        data_pos++;
                    }
                    else if ((fc_element.TYPE == FIELD_TYPE_BYTES) | (fc_element.TYPE == FIELD_TYPE_STRING))
                    {
                        b = compress(VSLib.ConvertLongToByte(fc_element.LENGTH), FIELD_TYPE_LONG);
                        data[data_pos] = (byte)b.Length;
                        data_pos++;

                        if (b.Length > 0)
                        {
                            VSLib.CopyBytes(data, b, data_pos, b.Length);
                            data_pos += b.Length;
                        }
                    }

                    // Write value
                    if (fc_element.VALUE.Length > 0)
                    {
                        VSLib.CopyBytes(data, fc_element.VALUE, data_pos, fc_element.VALUE.Length);
                        data_pos += afc[i].LENGTH;
                    }

                    // Shift offset and add to cache
                    fc_element.OLDLENGTH = afc[i].LENGTH;
                    fc_element.STATE     = STATE_LOADED;

                    FCacheTree.Insert(fc_element.NAME, FCache.Count);
                    FCache.Add(fc_element);
                }
            }

            base.Write(base.FIXED, data, data.Length);

            set_alloc(ALLOC_RENEW);

            // Fill the rest by zeros if le length < old length
            if (new_size < old_size)
            {
                long full_used_size = base.FIXED + new_size;
                b = new byte[old_size - new_size];
                base.Write(full_used_size, b, b.Length);                              // Fill be zeros unused space

                // Multiple chunks, chech if there are exessive
                if (base.Chunk > 0)
                {
                    sp.ShrinkObject(this, full_used_size);
                }
            }

            FreeSpace = (int)(this.Size - base.FIXED - new_size);
        }
示例#9
0
        /// <summary>
        /// Generic Set
        /// </summary>
        /// <param name="serialize">false = do not write (for multiple values at once)</param>
        /// <returns></returns>
        private void set_field(string name, byte type, byte[] data, bool serialize = true)
        {
            string nm = name.Trim();

            if ((nm.Length < 1) | (nm.Length > 255))
            {
                throw new VSException(DEFS.E0027_FIELD_WRITE_ERROR_CODE, "- " + name + " : name length shall be between 1 and 255");
            }

            FieldCache fc;
            int        index;

            byte[] compressed_length = null;                           // Compressed length

            // Initialize fields structure
            if (base.ALLOC == ALLOC_TYPE_RAW)
            {
                index = -1;

                set_alloc(ALLOC_INIT);

                FreeSpace     = (int)(this.Size - FIRST_FIELD_OFFSET_ABS);
                FIELDS_NUMBER = (short)0;
                FIELDS_SIZE   = FIRST_FIELD_OFFSET_REL;

                // Create cache
                FCache = new List <FieldCache>(32);
                // Create cache binary tree
                FCacheTree = new VSBBTree(FCT_NAME, 32, true);
            }
            else
            {
                index = find_field(nm, type);
            }


            // Field is not found in cache, add new field
            if (index < 0)
            {
                fc             = new FieldCache();
                fc.STATE       = STATE_NEW;                             // New field
                fc.OFFSET      = -1;
                fc.NAME        = nm;
                fc.VALUE       = compress(data, type);
                fc.LENGTH      = fc.VALUE.Length;
                fc.OLDLENGTH   = fc.VALUE.Length;
                fc.TYPE        = type;
                fc.DATA_OFFSET = FIELD_NAME_POS + fc.NAME.Length;

                if ((fc.TYPE == FIELD_TYPE_INT) | (fc.TYPE == FIELD_TYPE_LONG))
                {
                    fc.DATA_OFFSET += 1;
                }
                else if ((fc.TYPE == FIELD_TYPE_BYTES) | (fc.TYPE == FIELD_TYPE_STRING))
                {
                    compressed_length = compress(VSLib.ConvertLongToByte(fc.LENGTH), FIELD_TYPE_LONG);
                    fc.DATA_OFFSET   += (compressed_length.Length + 1);
                }

                fc.FULL_LENGTH = fc.DATA_OFFSET + fc.LENGTH;

                // Add to the tree
                FCacheTree.Insert(fc.NAME, (long)FCache.Count);

                // Add to the cache
                FCache.Add(fc);
            }
            else
            { // Field found in cache, update
                fc = FCache[index];

                byte[] b = compress(data, type);

                if (b.Length == fc.LENGTH)
                {
                    if (b.Length == 0)
                    {
                        return;
                    }

                    bool eq = true;
                    for (int i = 0; i < b.Length; i++)
                    {
                        if (b[i] != fc.VALUE[i])
                        {
                            eq = false;
                            break;
                        }
                    }

                    if (eq)
                    {
                        return;             // Value not changed
                    }
                    for (int i = 0; i < b.Length; i++)
                    {
                        fc.VALUE[i] = b[i];
                    }

                    base.Write(base.FIXED + fc.OFFSET + fc.DATA_OFFSET, b, fc.LENGTH);
                    fc.STATE = STATE_LOADED;

                    FCache.RemoveAt(index);
                    FCache.Insert(index, fc);

                    set_alloc(ALLOC_RENEW);

                    return;
                }

                fc.VALUE       = b;
                fc.LENGTH      = fc.VALUE.Length;
                fc.DATA_OFFSET = FIELD_NAME_POS + fc.NAME.Length;

                if ((fc.TYPE == FIELD_TYPE_INT) | (fc.TYPE == FIELD_TYPE_LONG))
                {
                    fc.DATA_OFFSET += 1;
                }
                else if ((fc.TYPE == FIELD_TYPE_BYTES) | (fc.TYPE == FIELD_TYPE_STRING))
                {
                    compressed_length = compress(VSLib.ConvertLongToByte(fc.LENGTH), FIELD_TYPE_LONG);
                    fc.DATA_OFFSET   += (compressed_length.Length + 1);
                }

                fc.FULL_LENGTH = fc.DATA_OFFSET + fc.LENGTH;       // Update full length
                fc.STATE       = STATE_UPDATED;

                FCache.RemoveAt(index);
                FCache.Insert(index, fc);
            }
            if (serialize)
            {
                this.serialize();
            }
        }
示例#10
0
 /// <summary>
 /// Set DateTime value
 /// </summary>
 /// <param name="name"></param>
 /// <returns></returns>
 public void Set(string name, DateTime value)
 {
     set_field(name, FIELD_TYPE_DATETIME, VSLib.ConvertLongToByte(value.Ticks));
 }
示例#11
0
 /// <summary>
 /// Set long value
 /// </summary>
 /// <param name="name"></param>
 /// <returns></returns>
 public void Set(string name, long value)
 {
     set_field(name, FIELD_TYPE_LONG, VSLib.ConvertLongToByte(value));
 }
示例#12
0
 // long
 public new void Write(long address, long data)
 {
     this.Write(address, VSLib.ConvertLongToByte(data), 8);
 }
示例#13
0
 /// <summary>
 /// Write long
 /// </summary>
 /// <param name="offset"></param>
 /// <param name="data"></param>
 public void Write(long offset, long data)
 {
     byte[] b = VSLib.ConvertLongToByte(data);
     this.Write(offset, ref b);
 }