This project contains a JNA (Java Native Access) implementation built on top of the native Hnswlib (Hierarchical Navigable Small World Graph) which offers a fast approximate nearest neighbor search. It includes some modifications and simplifications in order to provide Hnswlib features with native like performance to applications written in Java. Differently from the original Python implementation, the multi-thread support is not included in the bindings itself but it can be easily implemented on the Java side. Hnswlib-jna
works in collaboration with a shared library which contains the native code. For more information, please check the sections below.
The jar file includes some pre-generated libraries for Windows, Debian Linux and MacOS (x86-64) which should allow an easy integration and abstract all complexity related to compilation. An extra library for Debian Linux (aarch64) is also available for tests with AWS Graviton 2. In the case of operating system issues, a runtime exception will be thrown and the manual compilation will be advised.
On Windows, the Build Tools for Visual Studio 2019 (C++ build tools) is required.
Add the following dependency in your pom.xml
:
<dependency>
<groupId>com.stepstone.search.hnswlib.jna</groupId>
<artifactId>hnswlib-jna</artifactId>
<version>1.4.0</version>
</dependency>
For more information and implementation details, please check hnswlib-jna-example.
This section includes more information about how to compile the shared libraries on Windows, Linux and Mac for different architectures (e.g., x86-64
, aarch64
). If you were able to run the example project on your PC, this section can be ignored.
To generate the shared library required by this project, binding.cpp
needs to be compiled using a C compiler (e.g., clang
or gcc
) with C++11 support, at least. The library can be generated with clang
via:
clang++ -O3 -shared bindings.cpp -I hnswlib -o <project_folder>/lib/libhnswlib-jna-x86-64.dylib
Note: The shared library's name must be: libhnswlib-jna-ARCH.EXT where ARCH
is the canonical architecture name (e.g., x86-64
for AMD64, or aarch64
for ARM64) and EXT
is dylib
for MacOS, for windows use dll
, and linux so
.
clang
:
clang++ -O3 -shared bindings.cpp -I hnswlib -o <project_folder>/lib/libhnswlib-jna-x86-64.dll
This procedure will generate the 3 necessary files: libhnswlib-jna-x86-64.dll
, libhnswlib-jna-x86-64.exp
and libhnswlib-jna-x86-64.lib
.
clang
:
clang++ -O3 -target x86_64-pc-windows-gnu -shared bindings.cpp -I hnswlib -o <project_folder>lib/libhnswlib-jna-x86-64.dll -lpthread
This procedure will generate libhnswlib-jna-x86-64.dll
.
clang
(older versions might trigger compilation issues, so it is better use a recent version);clang
:
clang++ -O3 -fPIC -shared -std=c++11 bindings.cpp -I hnswlib -o <project_folder>/lib/libhnswlib-jna-x86-64.so
This procedure will generate libhnswlib-jna-x86-64.so
.
Once the shared library is available, it is necessary to tell the JVM
and JNA
where it is located. This can be done by setting the property jna.library.path
via JVM parameters or system properties.
-Djna.library.path=<project_folder>/lib
System.setProperty("jna.library.path", "<project_folder>/lib");
For more information and implementation details, please check hnswlib-jna-example.
Copyright 2020 StepStone Services
Licensed 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.