All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.btrplace.model.DefaultMapping Maven / Gradle / Ivy

/*
 * Copyright  2020 The BtrPlace Authors. All rights reserved.
 * Use of this source code is governed by a LGPL-style
 * license that can be found in the LICENSE.txt file.
 */

package org.btrplace.model;

import gnu.trove.map.hash.TIntIntHashMap;
import gnu.trove.map.hash.TIntObjectHashMap;
import gnu.trove.set.hash.THashSet;

import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;

/**
 * Default implementation of {@link Mapping}.
 * 

* Methods {@link #getRunningVMs()}, {@link #getSleepingVMs()}, {@link #getAllVMs()}, {@link #getAllNodes()}, * {@link #getRunningVMs(Collection)}, {@link #getSleepingVMs(java.util.Collection)} have a O(n) complexity. *

* Methods {@code is*()} have a O(1) complexity. * * @author Fabien Hermenier */ public class DefaultMapping extends AbstractMapping { private static final int RUNNING_STATE = 0; private static final int SLEEPING_STATE = 1; private static final int READY_STATE = 2; private static final int ONLINE_STATE = 0; private static final int OFFLINE_STATE = 1; /** * The node by states (online, offline) */ private final Set[] nodeState; /** * The state of each VM. */ private final TIntIntHashMap st; /** * The current location of the VMs. */ private final TIntObjectHashMap place; /** * The VMs that are in the ready state. */ private final Set vmReady; /** * The VMs hosted by each node, by state (running or sleeping) */ private final TIntObjectHashMap>[] host; /** * Create a new mapping. */ @SuppressWarnings("unchecked") public DefaultMapping() { nodeState = new Set[2]; nodeState[ONLINE_STATE] = new THashSet<>(); nodeState[OFFLINE_STATE] = new THashSet<>(); vmReady = new THashSet<>(); place = new TIntObjectHashMap<>(); host = new TIntObjectHashMap[2]; host[RUNNING_STATE] = new TIntObjectHashMap<>(); host[SLEEPING_STATE] = new TIntObjectHashMap<>(); st = new TIntIntHashMap(100, 0.5f, -1, -1); } /** * Make a new mapping from an existing one. * * @param m the mapping to copy */ public DefaultMapping(Mapping m) { this(); MappingUtils.fill(m, this); } @Override public boolean isRunning(VM v) { return st.get(v.id()) == RUNNING_STATE; } @Override public boolean isSleeping(VM v) { return st.get(v.id()) == SLEEPING_STATE; } @Override public boolean isReady(VM v) { return st.get(v.id()) == READY_STATE; } @Override public boolean isOnline(Node n) { return nodeState[ONLINE_STATE].contains(n); } @Override public boolean isOffline(Node n) { return nodeState[OFFLINE_STATE].contains(n); } @Override public boolean addRunningVM(VM vm, Node n) { if (!nodeState[ONLINE_STATE].contains(n)) { return false; } Node old; int vmId = vm.id(); int nId = n.id(); Set on = host[RUNNING_STATE].get(nId); if (on == null) { on = new THashSet<>(); host[RUNNING_STATE].put(nId, on); } switch (st.get(vmId)) { case RUNNING_STATE: old = place.put(vmId, n); if (!old.equals(n)) { host[RUNNING_STATE].get(old.id()).remove(vm); on.add(vm); } break; case SLEEPING_STATE: old = place.put(vmId, n); host[SLEEPING_STATE].get(old.id()).remove(vm); on.add(vm); st.put(vmId, RUNNING_STATE); break; case READY_STATE: place.put(vmId, n); on.add(vm); vmReady.remove(vm); st.put(vmId, RUNNING_STATE); break; default: place.put(vmId, n); on.add(vm); st.put(vmId, RUNNING_STATE); break; } return true; } @Override public boolean addSleepingVM(VM vm, Node n) { if (!nodeState[ONLINE_STATE].contains(n)) { return false; } int nId = n.id(); int vmId = vm.id(); Set on = host[SLEEPING_STATE].get(nId); if (on == null) { on = new THashSet<>(); host[SLEEPING_STATE].put(nId, on); } Node old; switch (st.get(vmId)) { case RUNNING_STATE: //If was running, sync the state old = place.put(vmId, n); host[RUNNING_STATE].get(old.id()).remove(vm); on.add(vm); st.put(vmId, SLEEPING_STATE); break; case SLEEPING_STATE: //If was sleeping, sync the state old = place.put(vmId, n); if (!old.equals(n)) { host[SLEEPING_STATE].get(old.id()).remove(vm); on.add(vm); } break; case READY_STATE: place.put(vmId, n); on.add(vm); vmReady.remove(vm); st.put(vmId, SLEEPING_STATE); break; default: //it's a new VM place.put(vmId, n); host[SLEEPING_STATE].get(nId).add(vm); st.put(vmId, SLEEPING_STATE); break; } st.put(vm.id(), SLEEPING_STATE); return true; } @Override public boolean addReadyVM(VM vm) { Node n = place.remove(vm.id()); int state = st.get(vm.id()); if (state == RUNNING_STATE) { //If was running, sync the state host[RUNNING_STATE].get(n.id()).remove(vm); } else if (state == SLEEPING_STATE) { //If was sleeping, sync the state host[SLEEPING_STATE].get(n.id()).remove(vm); } st.put(vm.id(), READY_STATE); vmReady.add(vm); return true; } @Override public boolean remove(VM vm) { if (place.containsKey(vm.id())) { Node n = this.place.remove(vm.id()); //The VM exists and is already placed if (st.get(vm.id()) == RUNNING_STATE) { host[RUNNING_STATE].get(n.id()).remove(vm); } else if (st.get(vm.id()) == SLEEPING_STATE) { host[SLEEPING_STATE].get(n.id()).remove(vm); } st.remove(vm.id()); return true; } else if (st.get(vm.id()) == READY_STATE) { vmReady.remove(vm); st.remove(vm.id()); return true; } return false; } @Override public boolean remove(Node n) { if (nodeState[ONLINE_STATE].contains(n)) { int nId = n.id(); Set on = host[RUNNING_STATE].get(nId); if (on != null) { if (!on.isEmpty()) { return false; } host[RUNNING_STATE].remove(nId); } on = host[SLEEPING_STATE].get(nId); if (on != null) { if (!on.isEmpty()) { return false; } host[SLEEPING_STATE].remove(nId); } return nodeState[ONLINE_STATE].remove(n); } return nodeState[OFFLINE_STATE].remove(n); } @Override public boolean addOnlineNode(Node n) { nodeState[OFFLINE_STATE].remove(n); nodeState[ONLINE_STATE].add(n); return true; } @Override public boolean addOfflineNode(Node n) { int nId = n.id(); if (nodeState[ONLINE_STATE].contains(n)) { Set on = host[SLEEPING_STATE].get(nId); if (on != null && !on.isEmpty()) { return false; } on = host[RUNNING_STATE].get(nId); if (on != null && !on.isEmpty()) { return false; } nodeState[ONLINE_STATE].remove(n); } nodeState[OFFLINE_STATE].add(n); return true; } @Override public Set getOnlineNodes() { return nodeState[ONLINE_STATE]; } @Override public Set getOfflineNodes() { return nodeState[OFFLINE_STATE]; } @Override public Set getRunningVMs() { return getRunningVMs(getOnlineNodes()); } @Override public Set getSleepingVMs() { return getSleepingVMs(getOnlineNodes()); } @Override public Set getSleepingVMs(Node n) { Set in = host[SLEEPING_STATE].get(n.id()); if (in == null) { return Collections.emptySet(); } return in; } @Override public Set getRunningVMs(Node n) { Set in = host[RUNNING_STATE].get(n.id()); if (in == null) { return Collections.emptySet(); } return in; } @Override public Set getReadyVMs() { return vmReady; } @Override public Set getAllVMs() { final Set s = new HashSet<>(vmReady); host[RUNNING_STATE].forEachEntry((a, b) -> { s.addAll(b); return true; }); host[SLEEPING_STATE].forEachEntry((a, b) -> { s.addAll(b); return true; }); return s; } @Override public Set getAllNodes() { Set ns = new THashSet<>( nodeState[OFFLINE_STATE].size() + nodeState[ONLINE_STATE].size() ); ns.addAll(nodeState[OFFLINE_STATE]); ns.addAll(nodeState[ONLINE_STATE]); return ns; } @Override public Node getVMLocation(VM vm) { return place.get(vm.id()); } @Override public Set getRunningVMs(Collection ns) { Set vms = new THashSet<>(); for (Node n : ns) { vms.addAll(getRunningVMs(n)); } return vms; } @Override public Set getSleepingVMs(Collection ns) { Set vms = new THashSet<>(); for (Node n : ns) { vms.addAll(getSleepingVMs(n)); } return vms; } @Override public Mapping copy() { return new DefaultMapping(this); } @Override public boolean contains(Node n) { return nodeState[OFFLINE_STATE].contains(n) || nodeState[ONLINE_STATE].contains(n); } @Override public boolean contains(VM vm) { return st.get(vm.id()) >= 0; } @Override public void clear() { for (Set s : nodeState) { s.clear(); } st.clear(); vmReady.clear(); place.clear(); for (TIntObjectHashMap> h : host) { h.clear(); } } @Override public void clearNode(Node u) { //Get the VMs on the node for (TIntObjectHashMap> h : host) { Set s = h.get(u.id()); if (s != null) { for (VM vm : s) { place.remove(vm.id()); st.remove(vm.id()); } s.clear(); } } } @Override public void clearAllVMs() { place.clear(); st.clear(); vmReady.clear(); for (TIntObjectHashMap> h : host) { h.clear(); } } @Override public String toString() { StringBuilder buf = new StringBuilder(); for (Node n : nodeState[ONLINE_STATE]) { buf.append(n); buf.append(':'); if (this.getRunningVMs(n).isEmpty() && this.getSleepingVMs(n).isEmpty()) { buf.append(" - "); } for (VM vm : this.getRunningVMs(n)) { buf.append(' ').append(vm); } for (VM vm : this.getSleepingVMs(n)) { buf.append(" (").append(vm).append(')'); } buf.append('\n'); } for (Node n : nodeState[OFFLINE_STATE]) { buf.append('(').append(n).append(")\n"); } buf.append("READY"); for (VM vm : this.getReadyVMs()) { buf.append(' ').append(vm); } return buf.append('\n').toString(); } @Override public int getNbNodes() { return nodeState[ONLINE_STATE].size() + nodeState[OFFLINE_STATE].size(); } @Override public int getNbVMs() { return st.size(); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy