
org.nuiton.math.matrix.LazyVector Maven / Gradle / Ivy
The newest version!
package org.nuiton.math.matrix;
/*
* #%L
* Nuiton Matrix :: API
* %%
* Copyright (C) 2004 - 2014 CodeLutin
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Lesser Public License for more details.
*
* You should have received a copy of the GNU General Lesser Public
* License along with this program. If not, see
* .
* #L%
*/
import java.util.concurrent.atomic.AtomicInteger;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
*
* Cette classe encapsule un Vector et permet de l'initialiser reellement que
* lorsqu'on souhaite modifier une valeur. Cela permet de ne pas initialise
* d'enorme tableau s'il n'y en a pas besoin. Chaque lazy est initialisé avec
* un Vector non initialise, lorsque l'on fait un paste, si le vector a partir
* duquel on fait le paste est aussi un lazy, alors on partage le backend
* jusqu'a ce qu'un des deux vector veuille modifier une de ses valeurs.
*
* @author poussin
* @version $Revision$
*
* Last update: $Date$
* by : $Author$
*/
public class LazyVector implements Vector {
/** to use log facility, just put in your code: log.info(\"...\"); */
static private Log log = LogFactory.getLog(LazyVector.class);
protected boolean isInitBackend = false;
/** reel backend, not initialized since not necessary */
protected Vector backend;
protected AtomicInteger users = new AtomicInteger();
protected long capacity;
/**
* Create new lazy, with initialized backend
* @param backend
*/
public LazyVector(Vector backend) {
this.isInitBackend = true;
this.backend = backend;
this.capacity = backend.size();
}
/**
* Create new lazy with not initialized backend
*
* @param backend
* @param capacity
*/
public LazyVector(Vector backend, long capacity) {
this.backend = backend;
this.capacity = capacity;
}
@Override
public void init(long capacity) {
}
@Override
public String getInfo() {
return "Lazy vector: " + (isInitBackend?backend.getInfo():"no backend");
}
@Override
public long getNumberOfAssignedValue() {
return isInitBackend?backend.getNumberOfAssignedValue():0;
}
@Override
public double getMaxOccurence() {
return getMaxOccurrence();
}
@Override
public double getMaxOccurrence() {
double result = 0;
if (isInitBackend) {
result = backend.getMaxOccurrence();
}
return result;
}
@Override
public double getValue(long pos) {
double result = 0;
if (isInitBackend) {
result = backend.getValue(pos);
}
return result;
}
@Override
public void setValue(long pos, double value) {
prepareBackendForModification();
backend.setValue(pos, value);
}
@Override
public long size() {
return capacity;
}
@Override
public boolean isImplementedPaste(Vector v) {
return true;
}
@Override
public boolean isImplementedAdd(Vector v) {
return backend.isImplementedAdd(v);
}
@Override
public boolean isImplementedMinus(Vector v) {
return backend.isImplementedMinus(v);
}
@Override
public boolean isImplementedMap() {
return backend.isImplementedMap();
}
@Override
public void paste(Vector source) {
if (!isInitBackend && source instanceof LazyVector && ((LazyVector)source).size() == size()) {
LazyVector l = ((LazyVector)source);
l.users.incrementAndGet();
users = l.users;
isInitBackend = l.isInitBackend;
backend = l.backend;
} else {
// initialized or already has copy, we need to paste, and not just
// reassign copy variable, in case of source Vector is smaller than copy
prepareBackendForModification();
pasteToBackend(backend, source);
}
}
@Override
public void add(Vector v) {
prepareBackendForModification();
backend.add(v);
}
@Override
public void minus(Vector v) {
prepareBackendForModification();
backend.minus(v);
}
@Override
public void map(MapFunction f) {
prepareBackendForModification();
backend.map(f);
}
@Override
public boolean equals(Object o) {
boolean result = false;
if (o instanceof Vector) {
Vector v = (Vector)o;
if (size() == v.size()) {
if (isInitBackend) {
result = v.equals(backend);
} else if (v instanceof LazyVector && !((LazyVector)v).isInitBackend) {
result = true;
} else {
result = v.equals(this);
}
}
}
return result;
}
@Override
public int hashCode() {
return Long.hashCode(size());
}
protected void prepareBackendForModification() {
if (users.get() > 0) {
try {
// others LazyVector use this backend, create new backend copy
Vector copy = backend.getClass().newInstance();
if (isInitBackend) {
copy.init(capacity);
pasteToBackend(copy, backend);
}
backend = copy;
users.decrementAndGet();
users = new AtomicInteger();
} catch (Exception eee) {
throw new MatrixException("Can't create new backend Vector", eee);
}
}
if (!isInitBackend) {
backend.init(capacity);
isInitBackend = true;
}
}
/**
* Before call this method backend, must be initialized
* @param target
* @param copy
*/
protected void pasteToBackend(Vector target, Vector copy) {
if (target.isImplementedPaste(copy)) {
target.paste(copy);
} else {
for (long i=0, max=Math.min(size(), copy.size()); i
© 2015 - 2025 Weber Informatics LLC | Privacy Policy