Skip to content

Commit

Permalink
Added DB aggregate function method
Browse files Browse the repository at this point in the history
Added Tin's put bytes method
  • Loading branch information
artbits committed Jun 4, 2023
1 parent 19fd989 commit a9fb2dc
Show file tree
Hide file tree
Showing 7 changed files with 163 additions and 5 deletions.
8 changes: 8 additions & 0 deletions src/main/java/com/github/artbits/quickio/api/Collection.java
Original file line number Diff line number Diff line change
Expand Up @@ -53,4 +53,12 @@ public interface Collection<T extends IOEntity> {
void dropIndex(String fieldName);
long count(Predicate<T> predicate);
long count();
Double sum(String fieldName, Predicate<T> predicate);
Double sum(String fieldName);
Double average(String fieldName, Predicate<T> predicate);
Double average(String fieldName);
Double max(String fieldName, Predicate<T> predicate);
Double max(String fieldName);
Double min(String fieldName, Predicate<T> predicate);
Double min(String fieldName);
}
1 change: 1 addition & 0 deletions src/main/java/com/github/artbits/quickio/api/Tin.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ public interface Tin extends AutoCloseable {
void close();
void destroy();
void put(String filename, File file);
void put(String filename, byte[] bytes);
File get(String filename);
void remove(String filename);
List<File> list();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,5 @@ final class Constants {
final static String SORTING_FIELD_NAME_ILLEGAL = "The sort method field name cannot be null or empty";
final static String SORTING_PARAMETER_VALUE_ILLEGAL = "The sorting parameter value can only be 1 or -1";
final static String KEY_ALREADY_EXISTS_AND_NOT_AVAILABLE = "The new key already exists and is not available";
final static String FIELD_NOT_NUMERICAL_TYPE = "This field is not of numerical type";
}
99 changes: 99 additions & 0 deletions src/main/java/com/github/artbits/quickio/core/QCollection.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import com.github.artbits.quickio.api.Collection;
import com.github.artbits.quickio.api.FindOptions;
import com.github.artbits.quickio.exception.QIOException;
import com.google.common.util.concurrent.AtomicDouble;
import org.iq80.leveldb.DBException;

import java.util.ArrayList;
Expand Down Expand Up @@ -368,4 +369,102 @@ public long count() {
return count(null);
}


@Override
public Double sum(String fieldName, Predicate<T> predicate) {
AtomicDouble sum = new AtomicDouble(0);
engine.iteration((key, value) -> {
T t = Codec.decode(value, clazz);
if (t != null) {
if (predicate != null && !predicate.test(t)) {
return;
}
sum.addAndGet(new ReflectObject<>(t).getNumberValue(fieldName));
}
});
return sum.get();
}


@Override
public Double sum(String fieldName) {
return sum(fieldName, null);
}


@Override
public Double average(String fieldName, Predicate<T> predicate) {
AtomicDouble sum = new AtomicDouble(0);
AtomicLong count = new AtomicLong(0);
engine.iteration((key, value) -> {
T t = Codec.decode(value, clazz);
if (t != null) {
if (predicate != null && !predicate.test(t)) {
return;
}
sum.addAndGet(new ReflectObject<>(t).getNumberValue(fieldName));
count.incrementAndGet();
}
});
return sum.get() / count.get();
}


@Override
public Double average(String fieldName) {
return average(fieldName, null);
}


@Override
public Double max(String fieldName, Predicate<T> predicate) {
AtomicReference<Double> max = new AtomicReference<>();
engine.iteration((key, value) -> {
T t = Codec.decode(value, clazz);
if (t != null) {
if (predicate != null && !predicate.test(t)) {
return;
}
if (max.get() == null) {
max.set(new ReflectObject<>(t).getNumberValue(fieldName));
} else {
max.set(Math.max(max.get(), new ReflectObject<>(t).getNumberValue(fieldName)));
}
}
});
return max.get();
}


@Override
public Double max(String fieldName) {
return max(fieldName, null);
}


@Override
public Double min(String fieldName, Predicate<T> predicate) {
AtomicReference<Double> min = new AtomicReference<>();
engine.iteration((key, value) -> {
T t = Codec.decode(value, clazz);
if (t != null) {
if (predicate != null && !predicate.test(t)) {
return;
}
if (min.get() == null) {
min.set(new ReflectObject<>(t).getNumberValue(fieldName));
} else {
min.set(Math.min(min.get(), new ReflectObject<>(t).getNumberValue(fieldName)));
}
}
});
return min.get();
}


@Override
public Double min(String fieldName) {
return min(fieldName, null);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ public void index(String fieldName, Object fieldValue) {
}


<T> List<T> get(List<T> list) {
<T extends IOEntity> List<T> get(List<T> list) {
Stream<T> stream = (list == null || list.isEmpty()) ? null : list.stream();
if (stream == null) {
return list;
Expand All @@ -92,7 +92,7 @@ <T> List<T> get(List<T> list) {
}


private <K, T> Comparator<K> createComparator(T object) {
private <K extends IOEntity, T extends IOEntity> Comparator<K> createComparator(T object) {
ReflectObject<T> reflectObject = new ReflectObject<>(object);
if (!reflectObject.contains(sortFieldName)) {
throw new QIOException(Constants.FIELD_DOES_NOT_EXIST);
Expand Down
20 changes: 20 additions & 0 deletions src/main/java/com/github/artbits/quickio/core/QTin.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
import java.nio.file.*;
Expand Down Expand Up @@ -126,6 +127,25 @@ public void put(String filename, File file) {
}


@Override
public void put(String filename, byte[] bytes) {
if (!LOCK_FILE_NAME.equals(filename)) {
String outPath = path + "/" + filename;
try (FileChannel outChannel = FileChannel.open(Paths.get(outPath), StandardOpenOption.READ,
StandardOpenOption.WRITE, StandardOpenOption.CREATE)) {
ByteBuffer buffer = ByteBuffer.allocate(bytes.length);
buffer.put(bytes);
buffer.flip();
while (buffer.hasRemaining()) {
outChannel.write(buffer);
}
} catch (IOException e) {
throw new QIOException(e);
}
}
}


@Override
public File get(String filename) {
if (!LOCK_FILE_NAME.equals(filename)) {
Expand Down
35 changes: 32 additions & 3 deletions src/main/java/com/github/artbits/quickio/core/ReflectObject.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,21 @@

package com.github.artbits.quickio.core;

import com.github.artbits.quickio.exception.QIOException;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.function.BiConsumer;

final class ReflectObject<T> {
final class ReflectObject<T extends IOEntity> {

private final Map<String, Field> fieldMap = new HashMap<>();
private final T t;
private long id;
private long createdAt;


ReflectObject(T t) {
Expand All @@ -34,7 +39,12 @@ final class ReflectObject<T> {
while (clazz != null){
for (Field field : clazz.getDeclaredFields()) {
field.setAccessible(true);
if ("_id".equals(field.getName()) || "createdAt".equals(field.getName())) {
if ("_id".equals(field.getName())) {
id = t.objectId();
continue;
}
if ("createdAt".equals(field.getName())) {
createdAt = t.createdAt();
continue;
}
fieldMap.put(field.getName(), field);
Expand Down Expand Up @@ -75,7 +85,6 @@ boolean contains(String fieldName) {

boolean containsAnnotation(Class<? extends Annotation> annotationClass) {
for (Field field : fieldMap.values()) {
QuickIO.println(field.getName());
if (field.isAnnotationPresent(annotationClass)) {
return true;
}
Expand Down Expand Up @@ -112,6 +121,26 @@ Class<?> getType(String fieldName) {
}


double getNumberValue(String fieldName) {
switch (fieldName) {
case "_id": return id;
case "createdAt": return createdAt;
}
Object object = getValue(fieldName);
Optional.ofNullable(object).orElseThrow(() -> new QIOException(Constants.FIELD_DOES_NOT_EXIST));
switch (getType(fieldName).getSimpleName().toLowerCase()) {
case "int":
case "integer": return (Integer) getValue(fieldName);
case "byte": return (Byte) getValue(fieldName);
case "short": return (Short) getValue(fieldName);
case "long": return (Long) getValue(fieldName);
case "float": return (Float) getValue(fieldName);
case "double": return (Double) getValue(fieldName);
default: throw new QIOException(Constants.FIELD_NOT_NUMERICAL_TYPE);
}
}


T get() {
return t;
}
Expand Down

0 comments on commit a9fb2dc

Please sign in to comment.