package com.github.believe3301.nonheapdb;
import java.util.Comparator;
import java.util.Objects;
public class RecordIndex implements Comparable<RecordIndex>, Comparator<RecordIndex> {
private short index; // memory block index 内存块索引:第几个内存块,用于定位记录在哪个内存块
private int offset; // in memory block offset, record alignment? 一条记录在内存块中的偏移量,用于定位记录
private int capacity; // allocated size 记录占用的字节数
public RecordIndex() {
}
//根据bucket解析出对应的三个字段
public RecordIndex(long bucket) {
this.capacity = (int)(bucket >>> 48);
this.index = (short)((bucket >>> 32) & 0x0000FFFF);
this.offset = (int)(bucket & 0x0000FFFFFFFFFFFFL);
}
//根据三个字段组成bucket
public long getBucket() {
return (long)capacity << 48 | (long)index << 32 | offset;
}
public RecordIndex setIndex(int idx) {
this.index =(short)idx;
return this;
}
public RecordIndex setCapacity(int capacity) {
this.capacity = capacity;
return this;
}
public RecordIndex setOffset(int offset) {
this.offset = offset;
return this;
}
public short index() {
return this.index;
}
public int offset() {
return this.offset;
}
public int capacity() {
return this.capacity;
}
//sort record by size
public int compare(RecordIndex o1, RecordIndex o2) {
return o1.compareTo(o2);
}
public int compareTo(RecordIndex rec) {
//TODO using ComparisonChain
int ret = this.capacity - rec.capacity;
if (ret == 0) {
return this.offset - rec.offset;
}
return ret;
}
//sort record by offset
public static Comparator<Long> offsetComparator() {
return new Comparator<Long>() {
public int compare(Long l, Long r) {
RecordIndex lidx = new RecordIndex(l.longValue());
RecordIndex ridx = new RecordIndex(r.longValue());
return lidx.offset - ridx.offset;
}
};
}
//sort record by capacity
public static Comparator<Long> capacityComparator() {
return new Comparator<Long>() {
public int compare(Long l, Long r) {
RecordIndex lidx = new RecordIndex(l.longValue());
RecordIndex ridx = new RecordIndex(r.longValue());
return lidx.compareTo(ridx);
}
};
}
public int hashCode() {
return Objects.hash(index, offset, capacity);
}
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (obj == this) {
return true;
}
if (obj.getClass() != getClass()) {
return false;
}
RecordIndex rec = (RecordIndex)obj;
return this.index == rec.index &&
this.offset == rec.offset &&
this.capacity == rec.capacity;
}
public String toString() {
//TODO using Objects.toStringHelper
StringBuilder sb = new StringBuilder();
sb.append(String.format("index: %d\r\n", this.index));
sb.append(String.format("offset: %d\r\n", this.offset));
sb.append(String.format("capacity: %d\r\n", this.capacity));
return sb.toString();
}
}