package com.bagri.core.model;
import static com.bagri.core.api.TransactionManagement.TX_NO;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
* Represents unique index on XDM Document
*
* @author Denis Sukhoroslov
*
*/
public class UniqueDocument extends IndexedValue {
private List<UniqueValue> docs = new ArrayList<>();
/**
* default constructor
*/
public UniqueDocument() {
super();
}
/**
*
* @param docKey the internal document key
*/
public UniqueDocument(long docKey) {
super();
addDocument(docKey, TX_NO);
}
/**
*
* @param docKeys the collection of internal document keys
*/
public UniqueDocument(Collection<Long> docKeys) {
super();
if (docKeys != null) {
for (Long docKey: docKeys) {
addDocument(docKey, TX_NO);
}
}
}
/**
* @return the number of indexed documents
*/
@Override
public int getCount() {
int cnt = 0;
for (int i=docs.size() - 1; i >=0; i--) {
UniqueValue doc = docs.get(i);
if (doc.getTxFinish() == TX_NO) {
cnt++;
}
}
return cnt;
}
/**
* @return the indexed document key
*/
@Override
public long getDocumentKey() {
for (int i=docs.size() - 1; i >=0; i--) {
UniqueValue doc = docs.get(i);
if (doc.getTxFinish() == TX_NO) {
return doc.getDocumentKey();
}
}
return 0;
}
/**
* @return the collection of indexed document keys
*/
@Override
public Set<Long> getDocumentKeys() {
Set<Long> docIds = new HashSet<>(1);
for (UniqueValue doc: docs) {
if (doc.getTxFinish() == TX_NO) {
docIds.add(doc.getDocumentKey());
}
}
// returning size must be 1!
return docIds;
}
/**
*
* @return the collection of unique indexed values
*/
public Collection<UniqueValue> getDocumentValues() {
return docs;
}
/**
* adds document to the index
*
* @param docKey the internal document key
* @param txId the internal transaction id
*/
@Override
public boolean addDocument(long docKey, long txId) { // synchronized?
UniqueValue doc;
for (int i=docs.size() - 1; i >=0; i--) {
doc = docs.get(i);
if (doc.getTxFinish() == TX_NO) {
doc = new UniqueValue(doc.getDocumentKey(), doc.getTxStart(), txId);
docs.set(i, doc);
break;
}
}
doc = new UniqueValue(docKey, txId, TX_NO);
docs.add(doc);
return true;
}
/**
* removes document from the index
*
* @param docKey the internal document key
* @param txId the internal transaction id
*/
@Override
public boolean removeDocument(long docKey, long txId) { // synchronized?
for (int i=docs.size() - 1; i >=0; i--) {
UniqueValue doc = docs.get(i);
if (doc.getDocumentKey() == docKey && doc.getTxFinish() == TX_NO) {
doc = new UniqueValue(doc.getDocumentKey(), doc.getTxStart(), txId);
docs.set(i, doc);
return true;
}
}
return false;
}
/**
*
* @param values the collection of unique values
*/
public void setDocumentValues(Collection<UniqueValue> values) {
docs.clear();
if (values != null) {
docs.addAll(values);
}
}
/**
* {@inheritDoc}
*/
@Override
public String toString() {
return "UniqueDocument [docs=" + docs + "]";
}
/**
* return consumed size in bytes
*/
@Override
public int getSize() {
// have no idea how much memory ArrayList takes!
return Long.SIZE / Byte.SIZE // List ref
+ (4 * Long.SIZE / Byte.SIZE) * docs.size();
}
}