Giter Site home page Giter Site logo

cachelot / cachelot Goto Github PK

View Code? Open in Web Editor NEW
353.0 353.0 34.0 1.12 MB

Cache library and distributed caching server. Memcached compatible.

Home Page: http://cachelot.io/

License: BSD 2-Clause "Simplified" License

Shell 1.88% Python 6.83% CMake 3.55% C++ 79.98% Makefile 0.33% C 4.85% Dockerfile 0.93% Batchfile 1.66%

cachelot's Introduction

What is Cachelot Library

If your application needs an LRU cache that works at the speed of light. That's what the Cachelot library is.

The library works with a fixed pre-allocated memory. You tell the memory size and LRU cache is ready.

Small metadata, up to 98% memory utilization.

Besides memory management, Cachelot ensures smooth responsiveness, without any "gaps" for both read and write operations.

Cachelot can work as a consistent cache, returning an error when out of memory or evicting old items to free space for new ones.

The code is highly optimized C++. You can use cachelot on platforms where resources are limited, like IoT devices or handheld; as well, as on servers with tons of RAM.

All this allows you to store and access three million items per second (depending on the CPU cache size). Maybe 3MOPs doesn't sound like such a large number, but it means ~333 nanoseconds are spent on a single operation, while RAM reference cost is at ~100 nanoseconds. Only 3 RAM reference per request, can you compete with that?

There are benchmarks inside of repo; we encourage you to try them for yourself.

It is possible to create bindings and use cachelot from your programming language of choice: Python, Go, Java, etc.

What is Cachelot Distributed Cache Server

Think of Memcached but Cachelot far better utilizes RAM so you can store more items in the same amount of memory. Also Cachelot is faster in terms of latency. See benchmarks on the cachelot web site.

Cachelot is single-threaded. It can scale to 1024 cores, and run even on battery-powered devices.

Cachelot supports TCP, UDP, and Unix sockets.

The easiest way to play with cachelot is to run Docker container

$ docker run --net=host cachelot/cachelot

Then you can connect to the port 11211 and speak memcached protocol

$ telnet localhost 11211
>set test 0 0 16
>Hello, cachelot!
STORED
>get test
VALUE test 0 16
Hello, cachelot!
END
>quit

Cross-platform

Cachelot is tested on Alpine Linux (Docker), CentOS 7, Ubuntu Trusty, macOS and Windows 10/11.

32bit ARM and x86-64 supported.

How To Hack

Prerequisites

Build

Clone source code repository:

$ git clone https://github.com/cachelot/cachelot.git

Next

$ cd cachelot

Generate project files for your favorite IDE or Makefile by running cmake -G "{target}" in the cachelot root directory.

For example, compiling Release configuration (Linux):

$ cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release
$ make

or (macOS):

$ cmake -G "Xcode" -DCMAKE_BUILD_TYPE=Release
$ make

or (Windows):

C:\> cmake -G "Visual Studio 17 2022" -DCMAKE_BUILD_TYPE=Release
C:\> cmake --build . --config Release
    OR
C:\> msbuild ALL_BUILD.vcxproj

There are several variants of build:

-DCMAKE_BUILD_TYPE must be one of the:

  • Debug - enable debug messages, assertions and disable optimization
  • Release - release build
  • RelWithDebInfo - release build with debug information enabled
  • MinSizeRel - minimal size release
  • AddressSanitizer - special build to run under Address Sanitizer (compiler support and libasan required)
  • UBSanitizer - special build to run under Undefined Behavior Sanitizer (compiler support required)

-DCMAKE_INSTALL_PREFIX could also be added to specify the installation folder.

Linux and macOS:

$ cmake <...> -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr/cachelot
$ make
$ make install

Windows:

C:\> cmake <...> -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=C:/cachelot
C:\> cmake --build . --config Release
C:\> cmake --install . --config Release

Dedicated scripts are available to respectively clean, build and build all configurations:

Linux and macOS:

$ # Build Debug configuration
$ ./build.sh Debug

$ # Build all configurations
$ ./cleanup.sh
$ ./all_build.sh

Windows:

C:\> REM Build Debug configuration
C:\> build.bat Debug

C:\> REM Build all configurations
C:\> cleanup.bat
C:\> all_build.bat

Windows specificity

Additional libraries under Windows have to be installed and declared one by one. To do that Microsoft proposes a dedicated tool named vcpkg which is in charge of downloading, compiling and deploying libraries like Boost.

vcpkg have to installed on the computer to be able to install libraries. Follow these instructions to download and install vcpkg.

After installation, run the following command to integrate vcpkg in the system (required admin privieges).

C:\> vcpkg integrate install

Cachelot requires Boost libraries. To install them with vcpkg, simply call this command:

C:\> vcpkg install boost:x64-windows

Note: All dependencies required by Boost will be automatically installed too.

Then, vcpkg is ready to be used with Visual Studio and CMake. If the vcpkg installation folder is for example C:\vcpkg\ the CMake toolchain could be completed like:

-DCMAKE_TOOLCHAIN_FILE=C:/vcpkg/scripts/buildsystems/vcpkg.cmake

Note: The script build.bat automatically detect vcpkg installation folder.

Run tests or benchmarks

All binaries (main executable, unit tests, etc.) will be in bin/{build_type}.

Dedicated test script if available for automatically run the tests:

Linux and macOS:

$ ./run_tests.sh

Windows:

C:\> run_tests.bat

Subscribe to Cachelot blog

cachelot.io/blog

Follow Cachelot in social media

Be first to know about the new features


License

Cachelot is free and open source. Distributed under the terms of Simplified BSD License

Credits

cachelot's People

Contributors

aka-rider avatar boidolr avatar herveancher avatar iurii-k avatar thedrow avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

cachelot's Issues

Build for Freebsd

-- Build files have been written to: /root/cachelot
[ 15%] Built target cachelot
[ 18%] Building CXX object src/server/CMakeFiles/cachelotd.dir/memcached/proto_ascii.cpp.o
In file included from /root/cachelot/src/server/memcached/proto_ascii.cpp:2:
In file included from /root/cachelot/src/server/memcached/proto_ascii.h:10:
In file included from /root/cachelot/src/server/memcached/memcached.h:15:
/root/cachelot/src/server/socket_stream.h:148:23: warning: unused variable 'receive_result' [-Wunused-variable]
                slice receive_result;
                      ^
In file included from /root/cachelot/src/server/memcached/proto_ascii.cpp:2:
In file included from /root/cachelot/src/server/memcached/proto_ascii.h:10:
In file included from /root/cachelot/src/server/memcached/memcached.h:21:
In file included from /root/cachelot/src/cachelot/cache.h:12:
In file included from /root/cachelot/src/cachelot/memalloc.h:14:
/root/cachelot/src/cachelot/bits.h:48:24: error: expected unqualified-id
        constexpr bool isset(const IntType value, const unsigned bitno) noexcept {
                       ^
/usr/include/sys/param.h:287:5: note: expanded from macro 'isset'
        (((const unsigned char *)(a))[(i)/NBBY] & (1<<((i)%NBBY)))
           ^
In file included from /root/cachelot/src/server/memcached/proto_ascii.cpp:2:
In file included from /root/cachelot/src/server/memcached/proto_ascii.h:10:
In file included from /root/cachelot/src/server/memcached/memcached.h:21:
In file included from /root/cachelot/src/cachelot/cache.h:12:
In file included from /root/cachelot/src/cachelot/memalloc.h:14:
/root/cachelot/src/cachelot/bits.h:48:24: error: expected ')'
/usr/include/sys/param.h:287:5: note: expanded from macro 'isset'
        (((const unsigned char *)(a))[(i)/NBBY] & (1<<((i)%NBBY)))
           ^
/root/cachelot/src/cachelot/bits.h:48:24: note: to match this '('
/usr/include/sys/param.h:287:4: note: expanded from macro 'isset'
        (((const unsigned char *)(a))[(i)/NBBY] & (1<<((i)%NBBY)))
          ^
In file included from /root/cachelot/src/server/memcached/proto_ascii.cpp:2:
In file included from /root/cachelot/src/server/memcached/proto_ascii.h:10:
In file included from /root/cachelot/src/server/memcached/memcached.h:21:
In file included from /root/cachelot/src/cachelot/cache.h:12:
In file included from /root/cachelot/src/cachelot/memalloc.h:14:
/root/cachelot/src/cachelot/bits.h:48:66: error: expected ')'
        constexpr bool isset(const IntType value, const unsigned bitno) noexcept {
                                                                 ^
/root/cachelot/src/cachelot/bits.h:48:24: note: to match this '('
        constexpr bool isset(const IntType value, const unsigned bitno) noexcept {
                       ^
/usr/include/sys/param.h:287:32: note: expanded from macro 'isset'
        (((const unsigned char *)(a))[(i)/NBBY] & (1<<((i)%NBBY)))
                                      ^
In file included from /root/cachelot/src/server/memcached/proto_ascii.cpp:2:
In file included from /root/cachelot/src/server/memcached/proto_ascii.h:10:
In file included from /root/cachelot/src/server/memcached/memcached.h:21:
In file included from /root/cachelot/src/cachelot/cache.h:12:
In file included from /root/cachelot/src/cachelot/memalloc.h:14:
/root/cachelot/src/cachelot/bits.h:48:24: error: expected expression
        constexpr bool isset(const IntType value, const unsigned bitno) noexcept {
                       ^
/usr/include/sys/param.h:287:35: note: expanded from macro 'isset'
        (((const unsigned char *)(a))[(i)/NBBY] & (1<<((i)%NBBY)))
                                         ^
In file included from /root/cachelot/src/server/memcached/proto_ascii.cpp:2:
In file included from /root/cachelot/src/server/memcached/proto_ascii.h:10:
In file included from /root/cachelot/src/server/memcached/memcached.h:21:
In file included from /root/cachelot/src/cachelot/cache.h:12:
In file included from /root/cachelot/src/cachelot/memalloc.h:14:
/root/cachelot/src/cachelot/bits.h:48:24: error: expected ')'
/usr/include/sys/param.h:287:42: note: expanded from macro 'isset'
        (((const unsigned char *)(a))[(i)/NBBY] & (1<<((i)%NBBY)))
                                                ^
/root/cachelot/src/cachelot/bits.h:48:24: note: to match this '('
/usr/include/sys/param.h:287:2: note: expanded from macro 'isset'
        (((const unsigned char *)(a))[(i)/NBBY] & (1<<((i)%NBBY)))
        ^
In file included from /root/cachelot/src/server/memcached/proto_ascii.cpp:2:
In file included from /root/cachelot/src/server/memcached/proto_ascii.h:10:
In file included from /root/cachelot/src/server/memcached/memcached.h:21:
In file included from /root/cachelot/src/cachelot/cache.h:12:
In file included from /root/cachelot/src/cachelot/memalloc.h:14:
/root/cachelot/src/cachelot/bits.h:112:16: error: no member named 'most_significant' in namespace 'cachelot::bit'; did you mean 'significand'?
        return bit::most_significant(value);
               ^~~~~~~~~~~~~~~~~~~~~
               significand
/usr/include/math.h:337:8: note: 'significand' declared here
double  significand(double);
        ^
In file included from /root/cachelot/src/server/memcached/proto_ascii.cpp:2:
In file included from /root/cachelot/src/server/memcached/proto_ascii.h:10:
In file included from /root/cachelot/src/server/memcached/memcached.h:21:
In file included from /root/cachelot/src/cachelot/cache.h:12:
In file included from /root/cachelot/src/cachelot/memalloc.h:150:
/root/cachelot/src/cachelot/memalloc-inl.h:462:25: error: expected unqualified-id
            return bit::isset(first_level_bit_index, pos.pow_index) && bit::isset(second_level_bit_index[pos.pow_index], pos.sub_index);
                        ^
/usr/include/sys/param.h:287:2: note: expanded from macro 'isset'
        (((const unsigned char *)(a))[(i)/NBBY] & (1<<((i)%NBBY)))
        ^
In file included from /root/cachelot/src/server/memcached/proto_ascii.cpp:2:
In file included from /root/cachelot/src/server/memcached/proto_ascii.h:10:
In file included from /root/cachelot/src/server/memcached/memcached.h:21:
In file included from /root/cachelot/src/cachelot/cache.h:12:
In file included from /root/cachelot/src/cachelot/memalloc.h:150:
/root/cachelot/src/cachelot/memalloc-inl.h:462:25: warning: cast to 'const unsigned char *' from smaller integer type 'cachelot::uint32' (aka 'unsigned int') [-Wint-to-pointer-cast]
/usr/include/sys/param.h:287:4: note: expanded from macro 'isset'
        (((const unsigned char *)(a))[(i)/NBBY] & (1<<((i)%NBBY)))
          ^
In file included from /root/cachelot/src/server/memcached/proto_ascii.cpp:2:
In file included from /root/cachelot/src/server/memcached/proto_ascii.h:10:
In file included from /root/cachelot/src/server/memcached/memcached.h:21:
In file included from /root/cachelot/src/cachelot/cache.h:12:
In file included from /root/cachelot/src/cachelot/memalloc.h:150:
/root/cachelot/src/cachelot/memalloc-inl.h:462:77: error: expected unqualified-id
            return bit::isset(first_level_bit_index, pos.pow_index) && bit::isset(second_level_bit_index[pos.pow_index], pos.sub_index);
                                                                            ^
/usr/include/sys/param.h:287:2: note: expanded from macro 'isset'
        (((const unsigned char *)(a))[(i)/NBBY] & (1<<((i)%NBBY)))
        ^
In file included from /root/cachelot/src/server/memcached/proto_ascii.cpp:2:
In file included from /root/cachelot/src/server/memcached/proto_ascii.h:10:
In file included from /root/cachelot/src/server/memcached/memcached.h:21:
In file included from /root/cachelot/src/cachelot/cache.h:12:
In file included from /root/cachelot/src/cachelot/memalloc.h:150:
/root/cachelot/src/cachelot/memalloc-inl.h:462:77: warning: cast to 'const unsigned char *' from smaller integer type 'std::__1::__vector_base<unsigned int, std::__1::allocator<unsigned int> >::value_type' (aka 'unsigned int')
      [-Wint-to-pointer-cast]
/usr/include/sys/param.h:287:4: note: expanded from macro 'isset'
        (((const unsigned char *)(a))[(i)/NBBY] & (1<<((i)%NBBY)))
          ^
In file included from /root/cachelot/src/server/memcached/proto_ascii.cpp:2:
In file included from /root/cachelot/src/server/memcached/proto_ascii.h:10:
In file included from /root/cachelot/src/server/memcached/memcached.h:21:
In file included from /root/cachelot/src/cachelot/cache.h:12:
In file included from /root/cachelot/src/cachelot/memalloc.h:150:
/root/cachelot/src/cachelot/memalloc-inl.h:468:58: error: no member named 'unset' in namespace 'cachelot::bit'
            second_level_bit_index[pos.pow_index] = bit::unset(second_level_bit_index[pos.pow_index], pos.sub_index);
                                                    ~~~~~^
/root/cachelot/src/cachelot/memalloc-inl.h:471:46: error: no member named 'unset' in namespace 'cachelot::bit'
                first_level_bit_index = bit::unset(first_level_bit_index, pos.pow_index);
                                        ~~~~~^
/root/cachelot/src/cachelot/memalloc-inl.h:477:58: error: no member named 'set' in namespace 'cachelot::bit'
            second_level_bit_index[pos.pow_index] = bit::set(second_level_bit_index[pos.pow_index], pos.sub_index);
                                                    ~~~~~^

[freebsd][                                                                                                    (0*$ csh)                                                                                                    ][08/22/18  7:34 PM]
/root/cachelot/src/cachelot/memalloc-inl.h:478:42: error: no member named 'set' in namespace 'cachelot::bit'
            first_level_bit_index = bit::set(first_level_bit_index, pos.pow_index);
                                    ~~~~~^
/root/cachelot/src/cachelot/memalloc-inl.h:492:89: error: no member named 'least_significant' in namespace 'cachelot::bit'
                    return tuple<bool, position>(true, position(current.pow_index, bit::least_significant(next_sub_index_mask)));
                                                                                   ~~~~~^
/root/cachelot/src/cachelot/memalloc-inl.h:499:51: error: no member named 'least_significant' in namespace 'cachelot::bit'
                    const uint32 next_pow2 = bit::least_significant(next_pow2_mask);
                                             ~~~~~^
/root/cachelot/src/cachelot/memalloc-inl.h:501:81: error: no member named 'least_significant' in namespace 'cachelot::bit'
                    return tuple<bool, position>(true, position(next_pow2, bit::least_significant(second_level_bit_index[next_pow2])));
                                                                           ~~~~~^
3 warnings and 15 errors generated.
*** Error code 1

Stop.
make[2]: stopped in /root/cachelot
*** Error code 1

Unit test failure in test_int_to_str

Running 24 test cases...
/home/joe/cachelot/src/unit_test/test_string_conv.cpp(31): error: in "test_string_conv/test_int_to_str": check my_value == their_value has failed [-9223372036854775807 != -9223372036854775808]

I'm on Ubuntu running on WSL2.

-- Compiler: GNU v9.3.0

Some questions about cache api (cache.h) in multi-threaded app

Hello, thank you for creating this cache library, and I have some questions while using it in multi-threaded app:

  1. Does concurrent read is allowed(cache item created with cache::Item::infinite_TTL and Cache object is protectted by ReadWriteLock) ?
    I see some doc says: returned pointer guaranteed to be valid only *until* the next Cachelot call, does this limitation exit on concurrent read ?

  2. In some situation, I want to clear all item(with cache::Item::infinite_TTL) but reserve memory(like Cache::do_flush_all does), is there an api to do this ?

Install Missing in cmake List

install script which uses make install is missing in cmakeLists.txt
if this proj has to be included as cmake subproject via FetchContent that will not work as config.h.in is being fetch using CMAKE_SOURCE_DIR rather than CMAKE_CURRENT_SOURCE_DIR

Question: Atomic operations

Great work here ๐Ÿ‘

I am planning to create a Rust wrapper around C-API and use in my rust program. My use-case is a pre-allocate 100GB memory for cache and use as LRU cache. The cache will be initialized from DB or file at startup and mostly used for read-only except if DB records are changes.

Are the insert, read and update atomic operation or mutex lock is required?

Does not build out-of-tree

~/wk/cachelot$ cd __build
~/wk/cachelot/__build$ cmake -G Ninja ..
-- The C compiler identification is GNU 7.3.0
-- The CXX compiler identification is GNU 7.3.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Platform: Linux x64
-- Compiler ID: GNU
-- gcc version 7.3.0
-- Enable ccache
-- Looking for aligned_alloc
-- Looking for aligned_alloc - found
-- Looking for posix_memalign
-- Looking for posix_memalign - found
-- Boost version: 1.65.1
-- Found the following Boost libraries:
--   unit_test_framework
--   system
--   program_options
-- Cachelot setup ...
-- Configuring done
-- Generating done
-- Build files have been written to: ~/wk/cachelot/__build
~/wk/cachelot/__build$ ninja -v
[1/32] ccache /usr/bin/c++  -DBOOST_ALL_NO_LIB -DCACHELOT_PLATFORM_BITS=64 -DHAVE_CONFIG_H=1 -I../src -Wall -Wextra -pedantic -fstrict-overflow -fstrict-aliasing -Wshadow -Wstrict-aliasing -Wstrict-overflow=4  -msse2  -m64 -std=c++11 -MD -MT src/cachelot/CMakeFiles/cachelot.dir/common.cpp.o -MF src/cachelot/CMakeFiles/cachelot.dir/common.cpp.o.d -o src/cachelot/CMakeFiles/cachelot.dir/common.cpp.o -c ../src/cachelot/common.cpp
FAILED: src/cachelot/CMakeFiles/cachelot.dir/common.cpp.o 
ccache /usr/bin/c++  -DBOOST_ALL_NO_LIB -DCACHELOT_PLATFORM_BITS=64 -DHAVE_CONFIG_H=1 -I../src -Wall -Wextra -pedantic -fstrict-overflow -fstrict-aliasing -Wshadow -Wstrict-aliasing -Wstrict-overflow=4  -msse2  -m64 -std=c++11 -MD -MT src/cachelot/CMakeFiles/cachelot.dir/common.cpp.o -MF src/cachelot/CMakeFiles/cachelot.dir/common.cpp.o.d -o src/cachelot/CMakeFiles/cachelot.dir/common.cpp.o -c ../src/cachelot/common.cpp
In file included from ../src/cachelot/common.cpp:7:0:
../src/cachelot/common.h:16:12: fatal error: config.h: No such file or directory
 #  include "config.h"
            ^~~~~~~~~~
compilation terminated.
[2/32] ccache /usr/bin/c++  -DBOOST_ALL_NO_LIB -DCACHELOT_PLATFORM_BITS=64 -DHAVE_CONFIG_H=1 -I../src -Wall -Wextra -pedantic -fstrict-overflow -fstrict-aliasing -Wshadow -Wstrict-aliasing -Wstrict-overflow=4  -msse2  -m64 -std=c++11 -MD -MT src/cachelot/CMakeFiles/cachelot.dir/item.cpp.o -MF src/cachelot/CMakeFiles/cachelot.dir/item.cpp.o.d -o src/cachelot/CMakeFiles/cachelot.dir/item.cpp.o -c ../src/cachelot/item.cpp
FAILED: src/cachelot/CMakeFiles/cachelot.dir/item.cpp.o 
ccache /usr/bin/c++  -DBOOST_ALL_NO_LIB -DCACHELOT_PLATFORM_BITS=64 -DHAVE_CONFIG_H=1 -I../src -Wall -Wextra -pedantic -fstrict-overflow -fstrict-aliasing -Wshadow -Wstrict-aliasing -Wstrict-overflow=4  -msse2  -m64 -std=c++11 -MD -MT src/cachelot/CMakeFiles/cachelot.dir/item.cpp.o -MF src/cachelot/CMakeFiles/cachelot.dir/item.cpp.o.d -o src/cachelot/CMakeFiles/cachelot.dir/item.cpp.o -c ../src/cachelot/item.cpp
In file included from ../src/cachelot/item.cpp:1:0:
../src/cachelot/common.h:16:12: fatal error: config.h: No such file or directory
 #  include "config.h"
            ^~~~~~~~~~
compilation terminated.

thread safe

If I use it as standalone caching library, is it thread safe? And how does it compare with unordered_map?

Documentation?

I've been looking around, but I haven't found any docs for cachelot. Am I right in guessing that it supports the same interface as Memcache (such that any existing memcache client will work)? The readme hinted at it, but I didn't find any direct confirmation that it supports the Memcache interface. Is cachelot a memcache replacement, or an enhancement? Are there other features in Cachelot that are not available in memcache?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.