Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 47 additions & 0 deletions docs/development/extensions-contrib/unsigned-int.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
---
id: unsigned-int
title: "Unsigned Integer Column Type"
---

<!--
~ Licensed to the Apache Software Foundation (ASF) under one
~ or more contributor license agreements. See the NOTICE file
~ distributed with this work for additional information
~ regarding copyright ownership. The ASF licenses this file
~ to you under the Apache License, Version 2.0 (the
~ "License"); you may not use this file except in compliance
~ with the License. You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing,
~ software distributed under the License is distributed on an
~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
~ KIND, either express or implied. See the License for the
~ specific language governing permissions and limitations
~ under the License.
-->

Apache Druid Extension to utilize an unsigned int column.

Consider this an [EXPERIMENTAL](../experimental.md) feature mostly because it has not been tested yet on a wide variety of long-running Druid clusters.

## How it works

Only store a 4 byte unsigned integer instead of a long column when you need your columns don't require you to store a long. Aggregations still happen as long values, only the data stored on disk is as an unsigned integer.

## Configuration

To use this extension please make sure to [include](../extensions.md#loading-extensions)`unsigned-int-extensions` in the extensions load list.

Example Usage:

```
"metricsSpec": [
{
"type": "unsigned_int",
"name": "value",
"fieldName": "value"
},
```

1 change: 1 addition & 0 deletions docs/development/extensions.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ All of these community extensions can be downloaded using [pull-deps](../operati
|gce-extensions|GCE Extensions|[link](../development/extensions-contrib/gce-extensions.md)|
|prometheus-emitter|Exposes [Druid metrics](../operations/metrics.md) for Prometheus server collection (https://prometheus.io/)|[link](./extensions-contrib/prometheus.md)|
|kubernetes-overlord-extensions|Support for launching tasks in k8s without Middle Managers|[link](../development/extensions-contrib/k8s-jobs.md)|
|unsigned-int-extensions|Support for an unsigned integer column|[link](../development/extensions-contrib/unsigned-int.md)|

## Promoting community extensions to core extensions

Expand Down
98 changes: 98 additions & 0 deletions extensions-contrib/unsigned-int/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Licensed to the Apache Software Foundation (ASF) under one
~ or more contributor license agreements. See the NOTICE file
~ distributed with this work for additional information
~ regarding copyright ownership. The ASF licenses this file
~ to you under the Apache License, Version 2.0 (the
~ "License"); you may not use this file except in compliance
~ with the License. You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing,
~ software distributed under the License is distributed on an
~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
~ KIND, either express or implied. See the License for the
~ specific language governing permissions and limitations
~ under the License.
-->

<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>org.apache.druid.extensions.contrib</groupId>
<artifactId>unsigned-int-extensions</artifactId>
<name>unsigned-int-extensions</name>
<description>unsigned-int-extensions</description>

<parent>
<groupId>org.apache.druid</groupId>
<artifactId>druid</artifactId>
<version>26.0.0-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>


<dependencies>
<dependency>
<groupId>org.apache.druid</groupId>
<artifactId>druid-core</artifactId>
<version>${project.parent.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.druid</groupId>
<artifactId>druid-processing</artifactId>
<version>${project.parent.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.google.code.findbugs</groupId>
<artifactId>jsr305</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.google.inject</groupId>
<artifactId>guice</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.druid</groupId>
<artifactId>druid-processing</artifactId>
<version>${project.parent.version}</version>
<type>test-jar</type>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.druid</groupId>
<artifactId>druid-core</artifactId>
<version>${project.parent.version}</version>
<type>test-jar</type>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>

</dependencies>

</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

package org.apache.druid.uint;

import org.apache.druid.segment.data.ObjectStrategy;

import javax.annotation.Nullable;
import java.nio.ByteBuffer;
import java.util.Arrays;

public class UnSignedIntObjectStrategy implements ObjectStrategy<Long>
{
@Override
public Class<Long> getClazz()
{
return Long.class;
}

@Nullable
@Override
public Long fromByteBuffer(ByteBuffer buffer, int numBytes)
{
if (numBytes <= 0) {
return null;
}
byte[] cache = new byte[numBytes];
buffer.get(cache);
ByteBuffer result = ByteBuffer.allocate(8).put(new byte[]{0, 0, 0, 0}).put(cache);
result.position(0);
long toReturn = result.getLong();
return toReturn;

}

@Nullable
@Override
public byte[] toBytes(@Nullable Long val)
{
if (val == null) {
return new byte[0];
}
byte[] bytes = new byte[8];
ByteBuffer.wrap(bytes).putLong(val);
return Arrays.copyOfRange(bytes, 4, 8);
}

@Override
public int compare(Long left, Long right)
{
return left.compareTo(right);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

package org.apache.druid.uint;

import org.apache.druid.data.input.InputRow;
import org.apache.druid.segment.column.ColumnBuilder;
import org.apache.druid.segment.data.GenericIndexed;
import org.apache.druid.segment.data.ObjectStrategy;
import org.apache.druid.segment.serde.ComplexColumnPartSupplier;
import org.apache.druid.segment.serde.ComplexMetricExtractor;
import org.apache.druid.segment.serde.ComplexMetricSerde;

import java.nio.ByteBuffer;

public class UnsignedIntComplexSerde extends ComplexMetricSerde
{

public static final String TYPE = "unsigned_int";
private final UnSignedIntObjectStrategy strategy = new UnSignedIntObjectStrategy();


@Override
public String getTypeName()
{
return TYPE;
}

@Override
public ComplexMetricExtractor getExtractor()
{
return new ComplexMetricExtractor<Long>()
{
@Override
public Class<Long> extractedClass()
{
return Long.class;
}

@Override
public Long extractValue(InputRow inputRow, String metricName)
{
Object obj = inputRow.getRaw(metricName);
return (Long) obj;
}
};
}

@Override
public void deserializeColumn(ByteBuffer buffer, ColumnBuilder builder)
{
GenericIndexed<Long> column = GenericIndexed.read(buffer, getObjectStrategy(), builder.getFileMapper());
builder.setComplexColumnSupplier(new ComplexColumnPartSupplier(getTypeName(), column));
}

@Override
public ObjectStrategy getObjectStrategy()
{
return strategy;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

package org.apache.druid.uint;

import com.fasterxml.jackson.databind.Module;
import com.fasterxml.jackson.databind.jsontype.NamedType;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.google.inject.Binder;
import org.apache.druid.initialization.DruidModule;
import org.apache.druid.segment.serde.ComplexMetrics;
import org.apache.druid.uint.aggs.UnsignedIntAnyAggregatorFactory;
import org.apache.druid.uint.aggs.UnsignedIntMaxAggregatorFactory;
import org.apache.druid.uint.aggs.UnsignedIntMinAggregatorFactory;
import org.apache.druid.uint.aggs.UnsignedIntSumAggregatorFactory;

import java.util.Collections;
import java.util.List;

public class UnsignedIntDruidModule implements DruidModule
{
@Override
public List<? extends Module> getJacksonModules()
{
return Collections.singletonList(
new SimpleModule("UnsignedIntDruidModule")
.registerSubtypes(
new NamedType(
UnsignedIntSumAggregatorFactory.class,
"unsignedIntSum"
),
new NamedType(
UnsignedIntMaxAggregatorFactory.class,
"unsignedIntMax"
),
new NamedType(
UnsignedIntMinAggregatorFactory.class,
"unsignedIntMin"
),
new NamedType(
UnsignedIntAnyAggregatorFactory.class,
"unsignedIntAny"
)
)
);
}

@Override
public void configure(Binder binder)
{
if (ComplexMetrics.getSerdeForType(UnsignedIntComplexSerde.TYPE) == null) {
ComplexMetrics.registerSerde(UnsignedIntComplexSerde.TYPE, new UnsignedIntComplexSerde());
}
}
}
Loading