/// <summary> /// Open new address space: _path - root folder path; _cat_file - catalog file name; idx - index in the catalog. Return: space id or -1(if error) /// </summary> /// <param name="_path"></param> /// <param name="_cat_file"></param> /// <param name="idx"></param> /// <returns></returns> public string Open(VSCatalogDescriptor desc, VSTransaction ta) { this.DESCRIPTOR = desc; this.page_size = DESCRIPTOR.PageSize; this.imo = DESCRIPTOR.IMO; e_key = VSLib.ConvertStringToByte(DEFS.ENCRYPT_SPACE); e_buf = new byte[page_size]; _ta = ta; ////////////////////////////////////////////// ///////////// Initiate partitions //////////// ////////////////////////////////////////////// this.pd = new partition_descriptor[DESCRIPTOR.Partitions]; //Check if all partitions exists if (imo) { pd[0].start_page = 0; //Start Page pd[0].end_page = DESCRIPTOR.space_size_pg - 1; //End Page } else { for (int i = 0; i < DESCRIPTOR.Partitions; i++) { short j = (short)(i + 1); pd[i].file_name = DESCRIPTOR.Path + "\\" + DEFS.SPACE_FILE_NAME(DESCRIPTOR.Name, i); if (!System.IO.File.Exists(pd[i].file_name)) { return("Error: space file is not found - " + pd[i].file_name); } //FileStream f = null; //f = File.Open(pd[i].file_name, FileMode.Open, FileAccess.ReadWrite, FileShare.None); pd[i].fs = new VSIO(pd[i].file_name, VSIO.FILE_MODE_OPEN, DEFS.ENCRYPT_SPACE); pd[i].fs.SetEncryption(false); pd[i].start_page = (i == 0) ? 0 : pd[i - 1].end_page + 1; //Start Page pd[i].end_page = pd[i].start_page + ((pd[i].fs.GetLength()) / page_size) - 1; //End Page } } ////////////////////////////////////////////// ///////////// Initiate cache ///////////////// ////////////////////////////////////////////// // Create segment table segment_table = new page_segment_descriptor[DEFS.PAGE_SEGMENTS_NUMBER]; // Create page table for 1st segment segment_table[0] = new page_segment_descriptor(); segment_table[0].start_page = 0; segment_table[0].end_page = DESCRIPTOR.space_size_pg - 1; // Set initial number of segments used segments_used = 1; // Calculate cache size in pages if (imo) { cache_size_pages = DESCRIPTOR.space_size_pg; cache_size_bytes = DESCRIPTOR.SpaceSize; } else { string confs = VSLib.VSGetKey(DEFS.VM_CACHE_SIZE_KEY); if (confs == "") { confs = DEFS.VM_CACHE_SIZE_DEFAULT; VSLib.VSSetKey(DEFS.VM_CACHE_SIZE_KEY, confs); } int csize = VSLib.ConvertStringToInt(confs); cache_size_bytes = ((csize < 2) ? 2 : csize) * 1048576; if (cache_size_bytes < (page_size * 10)) { cache_size_bytes = page_size * 10; } cache_size_pages = (cache_size_bytes / page_size) + 1; } // Initialize cache segment_table[0].cache = new page_buffer[cache_size_pages]; for (int i = 0; i < cache_size_pages; i++) { segment_table[0].cache[i].buf = new byte[page_size]; segment_table[0].cache[i].tbuf = null; segment_table[0].cache[i].last_access = 0; segment_table[0].cache[i].access_count = 0; if (imo) { segment_table[0].cache[i].page_no = i; // Page no = Buf no segment_table[0].cache[i].prev = -1; segment_table[0].cache[i].next = -1; } else { segment_table[0].cache[i].page_no = -1; segment_table[0].cache[i].prev = i - 1; segment_table[0].cache[i].next = ((i + 1) == cache_size_pages) ? -1 : i + 1; } } // Initialize queues (not IMO) if (!imo) { q_read = new int[3]; q_read[number] = 0; q_read[first] = -1; q_read[last] = -1; q_write = new int[3]; q_write[number] = 0; q_write[first] = -1; q_write[last] = -1; q_free = new int[3]; q_free[number] = (int)cache_size_pages; q_free[first] = 0; q_free[last] = (int)cache_size_pages - 1; } ////////////////////////////////////////////// ///////////// Initiate page table //////////// ////////////////////////////////////////////// segment_table[0].page_table = new page_descriptor[DESCRIPTOR.space_size_pg]; for (int i = 0; i < segment_table[0].page_table.Length; i++) { if (imo) { segment_table[0].page_table[i].page_state = DEFS.PAGE_READ; segment_table[0].page_table[i].page_lock = DEFS.PAGE_LOCKED; segment_table[0].page_table[i].bufno = i; // For IMO bufno = page table element } else { segment_table[0].page_table[i].page_state = DEFS.PAGE_FREE; segment_table[0].page_table[i].page_lock = DEFS.PAGE_UNLOCKED; segment_table[0].page_table[i].bufno = -1; } } // Set state 'Opened' this.state = DEFS.SPACE_OPENED; // For IMO: write owner 'undefined'; otherwise: load and lock page 0. if (imo) { this.Write(DEFS.SYSTEM_OWNER_ADDRESS, DEFS.SYSTEM_OWNER_UNDEFINED.PadRight((int)DEFS.SYSTEM_OWNER_LENGTH)); } else { fetch(0, 0, 0, DEFS.PAGE_READ); this.lock_page(0); // lock 1st page } return(""); }