private void UpdateAddressSpaceEnd() { lock (blockDbWriteLock) { ITransaction transaction = blockDatabase.CreateTransaction(); try { // Get the map, BlockServerTable blockServerTable = new BlockServerTable(transaction.GetFile(BlockServerKey, FileAccess.Read)); // Set the 'current address space end' object with a value that is // past the end of the address space. // Fetch the last block added, DataAddress addressSpaceEnd = new DataAddress(0, 0); // If the map is empty, if (blockServerTable.Count != 0) { long lastBlockId = blockServerTable.LastBlockId; addressSpaceEnd = new DataAddress(lastBlockId + 1024, 0); } lock (allocationLock) { if (currentAddressSpaceEnd == null) { currentAddressSpaceEnd = addressSpaceEnd; } else { currentAddressSpaceEnd = currentAddressSpaceEnd.Max(addressSpaceEnd); } } } finally { blockDatabase.Dispose(transaction); } } }
private void RegisterBlockServer(IServiceAddress serviceAddress) { // Open a connection with the block service, IMessageProcessor processor = connector.Connect(serviceAddress, ServiceType.Block); // Lock the block service with this manager RequestMessage request = new RequestMessage("bindWithManager"); request.Arguments.Add(address); Message response = processor.Process(request); if (response.HasError) throw new ApplicationException(response.ErrorMessage); // Get the block set report from the service, request = new RequestMessage("blockSetReport"); response = processor.Process(request); if (response.HasError) throw new ApplicationException(response.ErrorMessage); long serverGuid = response.Arguments[0].ToInt64(); long[] blockIdList = (long[])response.Arguments[1].Value; // Create a transaction lock (blockDbWriteLock) { ITransaction transaction = blockDatabase.CreateTransaction(); try { // Get the map, BlockServerTable blockServerTable = new BlockServerTable(transaction.GetFile(BlockServerKey, FileAccess.ReadWrite)); int actualAdded = 0; // Read until the end int sz = blockIdList.Length; // Put each block item into the database, for (int i = 0; i < sz; ++i) { long block_id = blockIdList[i]; bool added = blockServerTable.Add(block_id, serverGuid); if (added) { // TODO: Check if a service is adding polluted blocks into the // network via checksum, ++actualAdded; } } if (actualAdded > 0) { // Commit and check point the update, blockDatabase.Publish(transaction); blockDatabase.CheckPoint(); } } finally { blockDatabase.Dispose(transaction); } } BlockServerInfo blockServer = new BlockServerInfo(serverGuid, serviceAddress, ServiceStatus.Up); // Add it to the map lock (blockServersMap) { blockServersMap[serverGuid] = blockServer; blockServers.Add(blockServer); PersistBlockServers(blockServers); } // Update the address space end variable, UpdateAddressSpaceEnd(); }
private void RemoveBlockServerMapping(long blockId, long serverGuid) { lock (blockDbWriteLock) { ITransaction transaction = blockDatabase.CreateTransaction(); try { BlockServerTable blockServerTable = new BlockServerTable(transaction.GetFile(BlockServerKey, FileAccess.Write)); blockServerTable.Remove(blockId, serverGuid); // Commit and check point the update, blockDatabase.Publish(transaction); blockDatabase.CheckPoint(); } finally { blockDatabase.Dispose(transaction); } } }
private long[] GetServerGuidList(long blockId) { long[] servers; // Note; we perform these operations inside a lock because we may need to // provision servers to contain certain blocks which requires a database // update. lock (blockDbWriteLock) { // Create a transaction ITransaction transaction = blockDatabase.CreateTransaction(); try { // Get the map, BlockServerTable blockServerTable = new BlockServerTable(transaction.GetFile(BlockServerKey, FileAccess.Read)); // Get the servers list, servers = blockServerTable.Get(blockId); } finally { blockDatabase.Dispose(transaction); } } return servers; }
private long[] GetOnlineServersWithBlock(long blockId) { long[] servers; // Note; we perform these operations inside a lock because we may need to // provision servers to contain certain blocks which requires a database // update. lock (blockDbWriteLock) { // Create a transaction ITransaction transaction = blockDatabase.CreateTransaction(); try { // Get the map, BlockServerTable blockServerTable = new BlockServerTable(transaction.GetFile(BlockServerKey, FileAccess.ReadWrite)); // Get the servers list, servers = blockServerTable[blockId]; // If the list is empty, if (servers.Length == 0) { // Provision servers to contain the block, servers = AllocateOnlineServerNodesForBlock(blockId); // Did we allocate any servers for this block? if (servers.Length > 0) { // Put the servers in the map, for (int i = 0; i < servers.Length; ++i) blockServerTable.Add(blockId, servers[i]); // Commit and check point the update, blockDatabase.Publish(transaction); blockDatabase.CheckPoint(); } } } finally { blockDatabase.Dispose(transaction); } } return servers; }
private long[] GetBlockMappingRange(long start, long end) { if (start < 0) throw new ArgumentException("start < 0"); if (end < 0) throw new ArgumentException("end < 0"); if (start > end) throw new ArgumentException("start > end"); lock (blockDbWriteLock) { // Create a transaction ITransaction transaction = blockDatabase.CreateTransaction(); try { // Get the map, BlockServerTable block_server_map = new BlockServerTable(transaction.GetFile(BlockServerKey, FileAccess.Read)); long size = block_server_map.Count; start = Math.Min(start, size); end = Math.Min(end, size); // Return the range, return block_server_map.GetRange(start, end); } finally { blockDatabase.Dispose(transaction); } } }
private long GetBlockMappingCount() { lock (blockDbWriteLock) { // Create a transaction ITransaction transaction = blockDatabase.CreateTransaction(); try { // Get the map, BlockServerTable blockServerTable = new BlockServerTable(transaction.GetFile(BlockServerKey, FileAccess.Read)); return blockServerTable.Count; } finally { blockDatabase.Dispose(transaction); } } }
private void AddBlockServerMapping(long blockId, long serverGuid) { lock (blockDbWriteLock) { // Create a transaction ITransaction transaction = blockDatabase.CreateTransaction(); try { // Get the map, BlockServerTable blockServerTable = new BlockServerTable(transaction.GetFile(BlockServerKey, FileAccess.Write)); // Make the block -> service map blockServerTable.Add(blockId, serverGuid); // Commit and check point the update, blockDatabase.Publish(transaction); blockDatabase.CheckPoint(); } finally { blockDatabase.Dispose(transaction); } } }