package org.shanbo.feluca.cf.common;
import org.shanbo.feluca.data2.Vector;
import org.shanbo.feluca.data2.Vector.VectorType;
/**
* Update to a new one by modifying vector and calling {@link #update()} explicitly
* Since rating for recommendation is in small range, (0, 5],
* We use 4 bytes (a int type) to store id(3 bytes, range can be up to 16 million) and rating(1 byte)
* @author lgn
*
*/
public class UserRatings{
private static VectorType ALLOW_VECTOR_TYPE = VectorType.LABEL_FID_WEIGHT;
Vector vector;
RatingInfo current;
int indexOfItem = 0;
public UserRatings(Vector sample){
this.vector = sample;
current = new RatingInfo();
current.userId = sample.getIntHeader();
}
/**
* null vector;
*/
public UserRatings(){
current = new RatingInfo();
}
public void setVector(Vector v){
if (v.getOutVectorType() != ALLOW_VECTOR_TYPE){
throw new IllegalArgumentException("vector type not allow : only " + ALLOW_VECTOR_TYPE + " but found:" + v.getOutVectorType());
}
vector = v;
current.userId = vector.getIntHeader();
}
public int getUid(){
return vector.getIntHeader();
}
public int getItemNum(){
return vector.getSize();
}
public RatingInfo getNormalNextRating(){
RatingInfo tmp = getRatingByIndex(indexOfItem);
indexOfItem += 1;
return tmp;
}
/**
* not thread safe!
* @param idx
* @return
* @throws ArrayIndexOutOfBoundsException
*/
public RatingInfo getRatingByIndex(int idx) throws ArrayIndexOutOfBoundsException{
if (vector.getSize() <= idx){
return null;
}
//do not create a new RatingInfo object
//update rating info by modify Object's members, return it's reference
// current.itemId = (this.vector.features[idx] & 0xffffff); //tail 3 bytes for itemid,
// if ((vector.features[idx] & 0xf0000000) > 0){ //check whether
// current.rating = ((this.vector.features[idx] & 0xf0000000) >>> 28) +
// ((this.vector.features[idx] & 0x0f000000) >>> 24) * 0.1f;
// }else{
// current.rating = this.vector.weights[idx];
// }
current.userId = vector.getIntHeader();
current.itemId = vector.getFId(idx);
current.rating = vector.getWeight(idx);
indexOfItem = idx + 1;
return current;
}
public void refresh(){
indexOfItem = 0;
}
}