├── CMake
└── cotire.cmake
├── CMakeLists.txt
├── LICENSE
├── README.md
├── WebContent
├── css
│ ├── images
│ │ ├── layers-2x.png
│ │ ├── layers.png
│ │ ├── marker-icon-2x.png
│ │ ├── marker-icon.png
│ │ ├── marker-shadow.png
│ │ ├── ui-bg_flat_0_aaaaaa_40x100.png
│ │ ├── ui-bg_flat_75_ffffff_40x100.png
│ │ ├── ui-bg_glass_55_fbf9ee_1x400.png
│ │ ├── ui-bg_glass_65_ffffff_1x400.png
│ │ ├── ui-bg_glass_75_dadada_1x400.png
│ │ ├── ui-bg_glass_75_e6e6e6_1x400.png
│ │ ├── ui-bg_glass_95_fef1ec_1x400.png
│ │ ├── ui-bg_highlight-soft_75_cccccc_1x100.png
│ │ ├── ui-icons_222222_256x240.png
│ │ ├── ui-icons_2e83ff_256x240.png
│ │ ├── ui-icons_454545_256x240.png
│ │ ├── ui-icons_888888_256x240.png
│ │ └── ui-icons_cd0a0a_256x240.png
│ ├── jquery-ui-timepicker-addon.min.css
│ ├── jquery-ui.css
│ ├── jquery-ui.min.css
│ ├── jquery-ui.structure.css
│ ├── jquery-ui.structure.min.css
│ ├── jquery-ui.theme.css
│ ├── jquery-ui.theme.min.css
│ ├── leaflet.css
│ ├── styles.css
│ └── ui.jqgrid.css
├── images
│ ├── android-icon.png
│ ├── apple-icon.ico
│ ├── chrome-icon.png
│ ├── loading.gif
│ ├── other-icon.png
│ ├── twitter-icon.png
│ └── windows-icon.ico
├── index.html
└── js
│ ├── d3.tip.js
│ ├── d3
│ ├── LICENSE
│ └── d3-3.5.5.min.js
│ ├── global.js
│ ├── histogram.js
│ ├── i18n
│ ├── grid.locale-ar.js
│ ├── grid.locale-bg.js
│ ├── grid.locale-ca.js
│ ├── grid.locale-cn.js
│ ├── grid.locale-cs.js
│ ├── grid.locale-de.js
│ ├── grid.locale-dk.js
│ ├── grid.locale-el.js
│ ├── grid.locale-en.js
│ ├── grid.locale-es.js
│ ├── grid.locale-fa.js
│ ├── grid.locale-fi.js
│ ├── grid.locale-fr.js
│ ├── grid.locale-gl.js
│ ├── grid.locale-he.js
│ ├── grid.locale-hr.js
│ ├── grid.locale-hu.js
│ ├── grid.locale-id.js
│ ├── grid.locale-is.js
│ ├── grid.locale-it.js
│ ├── grid.locale-ja.js
│ ├── grid.locale-kr.js
│ ├── grid.locale-lt.js
│ ├── grid.locale-me.js
│ ├── grid.locale-nl.js
│ ├── grid.locale-no.js
│ ├── grid.locale-pl.js
│ ├── grid.locale-pt-br.js
│ ├── grid.locale-pt.js
│ ├── grid.locale-ro.js
│ ├── grid.locale-ru.js
│ ├── grid.locale-sk.js
│ ├── grid.locale-sq.js
│ ├── grid.locale-sr-latin.js
│ ├── grid.locale-sr.js
│ ├── grid.locale-sv.js
│ ├── grid.locale-th.js
│ ├── grid.locale-tr.js
│ ├── grid.locale-tw.js
│ ├── grid.locale-uk.js
│ ├── grid.locale-vi.js
│ ├── jquery-ui-timepicker-addon-i18n.js
│ ├── jquery-ui-timepicker-addon-i18n.min.js
│ ├── jquery-ui-timepicker-af.js
│ ├── jquery-ui-timepicker-am.js
│ ├── jquery-ui-timepicker-bg.js
│ ├── jquery-ui-timepicker-ca.js
│ ├── jquery-ui-timepicker-cs.js
│ ├── jquery-ui-timepicker-da.js
│ ├── jquery-ui-timepicker-de.js
│ ├── jquery-ui-timepicker-el.js
│ ├── jquery-ui-timepicker-es.js
│ ├── jquery-ui-timepicker-et.js
│ ├── jquery-ui-timepicker-eu.js
│ ├── jquery-ui-timepicker-fa.js
│ ├── jquery-ui-timepicker-fi.js
│ ├── jquery-ui-timepicker-fr.js
│ ├── jquery-ui-timepicker-gl.js
│ ├── jquery-ui-timepicker-he.js
│ ├── jquery-ui-timepicker-hr.js
│ ├── jquery-ui-timepicker-hu.js
│ ├── jquery-ui-timepicker-id.js
│ ├── jquery-ui-timepicker-it.js
│ ├── jquery-ui-timepicker-ja.js
│ ├── jquery-ui-timepicker-ko.js
│ ├── jquery-ui-timepicker-lt.js
│ ├── jquery-ui-timepicker-lv.js
│ ├── jquery-ui-timepicker-mk.js
│ ├── jquery-ui-timepicker-nl.js
│ ├── jquery-ui-timepicker-no.js
│ ├── jquery-ui-timepicker-pl.js
│ ├── jquery-ui-timepicker-pt-BR.js
│ ├── jquery-ui-timepicker-pt.js
│ ├── jquery-ui-timepicker-ro.js
│ ├── jquery-ui-timepicker-ru.js
│ ├── jquery-ui-timepicker-sk.js
│ ├── jquery-ui-timepicker-sl.js
│ ├── jquery-ui-timepicker-sr-RS.js
│ ├── jquery-ui-timepicker-sr-YU.js
│ ├── jquery-ui-timepicker-sv.js
│ ├── jquery-ui-timepicker-th.js
│ ├── jquery-ui-timepicker-tr.js
│ ├── jquery-ui-timepicker-uk.js
│ ├── jquery-ui-timepicker-vi.js
│ ├── jquery-ui-timepicker-zh-CN.js
│ └── jquery-ui-timepicker-zh-TW.js
│ ├── images
│ ├── layers-2x.png
│ ├── layers.png
│ ├── marker-icon-2x.png
│ ├── marker-icon.png
│ └── marker-shadow.png
│ ├── jquery-2.1.4.min.js
│ ├── jquery-dateFormat.min.js
│ ├── jquery-ui-1.11.4.min.js
│ ├── jquery-ui-sliderAccess.js
│ ├── jquery-ui-timepicker-addon.min.js
│ ├── jquery.jqGrid.min.js
│ ├── leaflet-hashedcubes.js
│ ├── leaflet-src.js
│ ├── leaflet.js
│ ├── linechart.js
│ ├── loadmap.js
│ ├── loadui.js
│ ├── scatterchart.js
│ ├── sql.js
│ └── view_schemas.js
├── csv.7z
├── data.7z
├── include
├── SQLiteCpp
│ ├── Assertion.h
│ ├── Backup.cpp
│ ├── Backup.h
│ ├── Column.cpp
│ ├── Column.h
│ ├── Database.cpp
│ ├── Database.h
│ ├── Exception.h
│ ├── SQLiteCpp.h
│ ├── Statement.cpp
│ ├── Statement.h
│ ├── Transaction.cpp
│ └── Transaction.h
├── boost
│ └── serialization
│ │ └── tuple.hpp
├── meerkat
│ ├── LICENSE
│ ├── meerkat.c
│ └── meerkat.h
├── rapidjson
│ ├── allocators.h
│ ├── document.h
│ ├── encodedstream.h
│ ├── encodings.h
│ ├── error
│ │ ├── en.h
│ │ └── error.h
│ ├── filereadstream.h
│ ├── filewritestream.h
│ ├── internal
│ │ ├── biginteger.h
│ │ ├── diyfp.h
│ │ ├── dtoa.h
│ │ ├── ieee754.h
│ │ ├── itoa.h
│ │ ├── meta.h
│ │ ├── pow10.h
│ │ ├── stack.h
│ │ ├── strfunc.h
│ │ └── strtod.h
│ ├── memorybuffer.h
│ ├── memorystream.h
│ ├── msinttypes
│ │ ├── inttypes.h
│ │ └── stdint.h
│ ├── prettywriter.h
│ ├── rapidjson.h
│ ├── reader.h
│ ├── stringbuffer.h
│ └── writer.h
└── sqlite
│ ├── sqlite3.c
│ └── sqlite3.h
├── src
├── CategoricalDimension.cpp
├── CategoricalDimension.h
├── CategoricalNode.cpp
├── CategoricalNode.h
├── CategoricalPivot.h
├── CategoricalSerializer.cpp
├── CategoricalSerializer.h
├── DMPLoader.cpp
├── DMPLoader.h
├── Data.cpp
├── Data.h
├── DataGenerator.h
├── DataLoader.cpp
├── DataLoader.h
├── Date.h
├── FlightsDelayLoader.cpp
├── FlightsDelayLoader.h
├── FlightsLoader.h
├── FlightsPerformanceLoader.cpp
├── FlightsPerformanceLoader.h
├── HashedCube.cpp
├── HashedCube.h
├── HashedCubeInstances.cpp
├── HashedCubeInstances.h
├── Hashing.h
├── InMemoryData.cpp
├── InMemoryData.h
├── InMemoryDataDescriptor.h
├── InMemoryDataGenerator.cpp
├── InMemoryDataGenerator.h
├── Mercator.h
├── MySQLSerializer.cpp
├── MySQLSerializer.h
├── Nanocubes.h
├── Pivot.h
├── Query.cpp
├── Query.h
├── ResidentSetSize.h
├── Response.h
├── SQLData.cpp
├── SQLData.h
├── ScatterSerializer.cpp
├── ScatterSerializer.h
├── Serializer.h
├── Server.cpp
├── Server.h
├── SnapLoader.cpp
├── SnapLoader.h
├── SpatialDimension.cpp
├── SpatialDimension.h
├── SpatialSerializer.cpp
├── SpatialSerializer.h
├── SplomLoader.cpp
├── SplomLoader.h
├── StringUtil.cpp
├── StringUtil.h
├── TemporalDimension.cpp
├── TemporalDimension.h
├── TemporalInterval.h
├── TemporalNode.cpp
├── TemporalNode.h
├── TemporalPivot.h
├── TemporalSerializer.cpp
├── TemporalSerializer.h
├── TileNode.cpp
├── TileNode.h
├── TilePivot.h
├── TripLoader.cpp
├── TripLoader.h
├── Trunc.h
├── TwitterSQL.h
├── Types.cpp
├── Types.h
├── main.cpp
├── stdafx.cpp
└── stdafx.h
└── xml
├── brightkite-immens.xml
├── brightkite-nanocubes.xml
└── gowalla.xml
/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | project (hashedcubes)
2 | cmake_minimum_required (VERSION 3.0)
3 |
4 | if(WIN32)
5 | if (MSVC)
6 | set(CMAKE_CXX_FLAGS "/EHsc")
7 | endif()
8 |
9 | set(BOOST_LIBRARYDIR "C:/Boost/lib/")
10 | set(BOOST_INCLUDEDIR "C:/Boost/include/boost-1_62/")
11 | endif()
12 |
13 | if(UNIX)
14 | set(CMAKE_CXX_FLAGS "-std=c++14")
15 | endif()
16 |
17 | set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/CMake")
18 |
19 | include(cotire)
20 |
21 | aux_source_directory(. SRC_LIST)
22 |
23 | include_directories(AFTER ./)
24 | include_directories(AFTER src)
25 | include_directories(AFTER include)
26 | include_directories(AFTER include/sqlite)
27 |
28 | file(GLOB_RECURSE HEADERS "src/*.h")
29 | source_group("Header Files" FILES ${HEADERS})
30 |
31 | add_executable (${PROJECT_NAME} ${SRC_LIST} ${HEADERS}
32 | include/sqlite/sqlite3.c
33 | include/meerkat/meerkat.c
34 | include/SQLiteCpp/Backup.cpp
35 | include/SQLiteCpp/Column.cpp
36 | include/SQLiteCpp/Database.cpp
37 | include/SQLiteCpp/Statement.cpp
38 | include/SQLiteCpp/Transaction.cpp
39 | src/CategoricalDimension.cpp
40 | src/CategoricalNode.cpp
41 | src/CategoricalSerializer.cpp
42 | src/Data.cpp
43 | src/DataLoader.cpp
44 | src/DMPLoader.cpp
45 | src/FlightsDelayLoader.cpp
46 | src/FlightsPerformanceLoader.cpp
47 | src/HashedCube.cpp
48 | src/HashedCubeInstances.cpp
49 | src/InMemoryData.cpp
50 | src/InMemoryDataGenerator.cpp
51 | src/main.cpp
52 | src/MySQLSerializer.cpp
53 | src/Query.cpp
54 | src/ScatterSerializer.cpp
55 | src/Server.cpp
56 | src/SnapLoader.cpp
57 | src/SpatialDimension.cpp
58 | src/SpatialSerializer.cpp
59 | src/SplomLoader.cpp
60 | src/SQLData.cpp
61 | src/StringUtil.cpp
62 | src/TemporalDimension.cpp
63 | src/TemporalNode.cpp
64 | src/TemporalSerializer.cpp
65 | src/TileNode.cpp
66 | src/TripLoader.cpp
67 | src/Types.cpp
68 | )
69 |
70 | find_package(Threads REQUIRED)
71 |
72 | set(Boost_USE_MULTITHREAD ON)
73 | set(Boost_USE_STATIC_LIBS ON)
74 |
75 | find_package(Boost 1.62 COMPONENTS system filesystem serialization iostreams program_options REQUIRED)
76 |
77 | include_directories(${Boost_INCLUDE_DIR})
78 | link_directories(${Boost_LIBRARY_DIR})
79 |
80 | target_link_libraries (${PROJECT_NAME} LINK_PUBLIC ${CMAKE_DL_LIBS} ${Boost_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT})
81 |
82 | set_target_properties(${PROJECT_NAME} PROPERTIES COTIRE_CXX_PREFIX_HEADER_INIT "src/stdafx.h")
83 |
84 | cotire(${PROJECT_NAME})
85 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | **Hashedcubes: Simple, Low Memory, Real-Time Visual Exploration of Big Data**
2 |
3 | Hashedcubes is formulated on the simple idea that a combination of progressive partitioning and sorting, along with a compact representation of data subsets, allows to create a data structure that efficiently stores and query spatiotemporal datasets.
4 |
5 | The underlying concept behind Hashedcubes makes it natural to create links between the data structure and original records, thus encouraging to complement the visual queries with additional information stored in an external database.
6 |
7 | **How To Build Hashedcubes**
8 |
9 | Hashedcubes depends on Boost 1.62 or later and CMake 3.0 or later, both on Windows and Linux.
10 |
11 | To build and run on Linux:
12 |
13 | 1- extract csv.7z and data.7z
14 |
15 | 2- cd build
16 |
17 | 3- cmake -DCMAKE_BUILD_TYPE=Release ..
18 |
19 | 4- make
20 |
21 | 5- cd .. && cp build/hashedcubes .
22 |
23 | 6- ./hashedcubes
24 |
25 | __Web interface: [http://localhost:8000]__
26 |
27 | __To list all command line parameters: ./hashedcubes -h__
28 |
--------------------------------------------------------------------------------
/WebContent/css/images/layers-2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cicerolp/hashedcubes/ff15e60f4449762c8282b66387dcb7bab836bf77/WebContent/css/images/layers-2x.png
--------------------------------------------------------------------------------
/WebContent/css/images/layers.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cicerolp/hashedcubes/ff15e60f4449762c8282b66387dcb7bab836bf77/WebContent/css/images/layers.png
--------------------------------------------------------------------------------
/WebContent/css/images/marker-icon-2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cicerolp/hashedcubes/ff15e60f4449762c8282b66387dcb7bab836bf77/WebContent/css/images/marker-icon-2x.png
--------------------------------------------------------------------------------
/WebContent/css/images/marker-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cicerolp/hashedcubes/ff15e60f4449762c8282b66387dcb7bab836bf77/WebContent/css/images/marker-icon.png
--------------------------------------------------------------------------------
/WebContent/css/images/marker-shadow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cicerolp/hashedcubes/ff15e60f4449762c8282b66387dcb7bab836bf77/WebContent/css/images/marker-shadow.png
--------------------------------------------------------------------------------
/WebContent/css/images/ui-bg_flat_0_aaaaaa_40x100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cicerolp/hashedcubes/ff15e60f4449762c8282b66387dcb7bab836bf77/WebContent/css/images/ui-bg_flat_0_aaaaaa_40x100.png
--------------------------------------------------------------------------------
/WebContent/css/images/ui-bg_flat_75_ffffff_40x100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cicerolp/hashedcubes/ff15e60f4449762c8282b66387dcb7bab836bf77/WebContent/css/images/ui-bg_flat_75_ffffff_40x100.png
--------------------------------------------------------------------------------
/WebContent/css/images/ui-bg_glass_55_fbf9ee_1x400.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cicerolp/hashedcubes/ff15e60f4449762c8282b66387dcb7bab836bf77/WebContent/css/images/ui-bg_glass_55_fbf9ee_1x400.png
--------------------------------------------------------------------------------
/WebContent/css/images/ui-bg_glass_65_ffffff_1x400.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cicerolp/hashedcubes/ff15e60f4449762c8282b66387dcb7bab836bf77/WebContent/css/images/ui-bg_glass_65_ffffff_1x400.png
--------------------------------------------------------------------------------
/WebContent/css/images/ui-bg_glass_75_dadada_1x400.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cicerolp/hashedcubes/ff15e60f4449762c8282b66387dcb7bab836bf77/WebContent/css/images/ui-bg_glass_75_dadada_1x400.png
--------------------------------------------------------------------------------
/WebContent/css/images/ui-bg_glass_75_e6e6e6_1x400.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cicerolp/hashedcubes/ff15e60f4449762c8282b66387dcb7bab836bf77/WebContent/css/images/ui-bg_glass_75_e6e6e6_1x400.png
--------------------------------------------------------------------------------
/WebContent/css/images/ui-bg_glass_95_fef1ec_1x400.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cicerolp/hashedcubes/ff15e60f4449762c8282b66387dcb7bab836bf77/WebContent/css/images/ui-bg_glass_95_fef1ec_1x400.png
--------------------------------------------------------------------------------
/WebContent/css/images/ui-bg_highlight-soft_75_cccccc_1x100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cicerolp/hashedcubes/ff15e60f4449762c8282b66387dcb7bab836bf77/WebContent/css/images/ui-bg_highlight-soft_75_cccccc_1x100.png
--------------------------------------------------------------------------------
/WebContent/css/images/ui-icons_222222_256x240.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cicerolp/hashedcubes/ff15e60f4449762c8282b66387dcb7bab836bf77/WebContent/css/images/ui-icons_222222_256x240.png
--------------------------------------------------------------------------------
/WebContent/css/images/ui-icons_2e83ff_256x240.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cicerolp/hashedcubes/ff15e60f4449762c8282b66387dcb7bab836bf77/WebContent/css/images/ui-icons_2e83ff_256x240.png
--------------------------------------------------------------------------------
/WebContent/css/images/ui-icons_454545_256x240.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cicerolp/hashedcubes/ff15e60f4449762c8282b66387dcb7bab836bf77/WebContent/css/images/ui-icons_454545_256x240.png
--------------------------------------------------------------------------------
/WebContent/css/images/ui-icons_888888_256x240.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cicerolp/hashedcubes/ff15e60f4449762c8282b66387dcb7bab836bf77/WebContent/css/images/ui-icons_888888_256x240.png
--------------------------------------------------------------------------------
/WebContent/css/images/ui-icons_cd0a0a_256x240.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cicerolp/hashedcubes/ff15e60f4449762c8282b66387dcb7bab836bf77/WebContent/css/images/ui-icons_cd0a0a_256x240.png
--------------------------------------------------------------------------------
/WebContent/css/jquery-ui-timepicker-addon.min.css:
--------------------------------------------------------------------------------
1 | /*! jQuery Timepicker Addon - v1.6.1 - 2015-11-14
2 | * http://trentrichardson.com/examples/timepicker
3 | * Copyright (c) 2015 Trent Richardson; Licensed MIT */
4 |
5 | .ui-timepicker-div .ui-widget-header{margin-bottom:8px}.ui-timepicker-div dl{text-align:left}.ui-timepicker-div dl dt{float:left;clear:left;padding:0 0 0 5px}.ui-timepicker-div dl dd{margin:0 10px 10px 40%}.ui-timepicker-div td{font-size:90%}.ui-tpicker-grid-label{background:0 0;border:0;margin:0;padding:0}.ui-timepicker-div .ui_tpicker_unit_hide{display:none}.ui-timepicker-div .ui_tpicker_time .ui_tpicker_time_input{background:0 0;color:inherit;border:0;outline:0;border-bottom:solid 1px #555;width:95%}.ui-timepicker-div .ui_tpicker_time .ui_tpicker_time_input:focus{border-bottom-color:#aaa}.ui-timepicker-rtl{direction:rtl}.ui-timepicker-rtl dl{text-align:right;padding:0 5px 0 0}.ui-timepicker-rtl dl dt{float:right;clear:right}.ui-timepicker-rtl dl dd{margin:0 40% 10px 10px}.ui-timepicker-div.ui-timepicker-oneLine{padding-right:2px}.ui-timepicker-div.ui-timepicker-oneLine .ui_tpicker_time,.ui-timepicker-div.ui-timepicker-oneLine dt{display:none}.ui-timepicker-div.ui-timepicker-oneLine .ui_tpicker_time_label{display:block;padding-top:2px}.ui-timepicker-div.ui-timepicker-oneLine dl{text-align:right}.ui-timepicker-div.ui-timepicker-oneLine dl dd,.ui-timepicker-div.ui-timepicker-oneLine dl dd>div{display:inline-block;margin:0}.ui-timepicker-div.ui-timepicker-oneLine dl dd.ui_tpicker_minute:before,.ui-timepicker-div.ui-timepicker-oneLine dl dd.ui_tpicker_second:before{content:':';display:inline-block}.ui-timepicker-div.ui-timepicker-oneLine dl dd.ui_tpicker_millisec:before,.ui-timepicker-div.ui-timepicker-oneLine dl dd.ui_tpicker_microsec:before{content:'.';display:inline-block}.ui-timepicker-div.ui-timepicker-oneLine .ui_tpicker_unit_hide,.ui-timepicker-div.ui-timepicker-oneLine .ui_tpicker_unit_hide:before{display:none}
--------------------------------------------------------------------------------
/WebContent/css/styles.css:
--------------------------------------------------------------------------------
1 | .axis {
2 | shape-rendering: crispEdges;
3 | }
4 |
5 | .x.axis path {
6 | stroke: #ddd;
7 | }
8 |
9 | .x.axis line {
10 | stroke: #ddd;
11 | stroke-opacity: .5;
12 | }
13 |
14 | .y.axis line {
15 | stroke: #ddd;
16 | }
17 |
18 | path.line {
19 | fill: none;
20 | stroke: #000;
21 | stroke-width: .5px;
22 | }
23 |
24 | rect.pane {
25 | cursor: move;
26 | fill: none;
27 | pointer-events: all;
28 | }
29 |
30 | .d3-tip {
31 | z-index: 901;
32 | line-height: 1;
33 | font-weight: bold;
34 | padding: 6px;
35 | background: rgba(0, 0, 0, 1);
36 | color: #fff;
37 | border-radius: 4px;
38 |
39 | font-family: sans-serif;
40 | font-size: 13px;
41 | }
42 |
43 | .d3-tip:after {
44 | z-index: 901;
45 | box-sizing: border-box;
46 | display: inline;
47 | font-size: 10px;
48 | width: 100%;
49 | line-height: 1;
50 | color: rgba(0, 0, 0, 1);
51 | content: "\25BC";
52 | position: absolute;
53 | text-align: center;
54 | }
55 |
56 | .d3-tip.n:after {
57 | z-index: 901;
58 | margin: -1px 0 0 0;
59 | top: 100%;
60 | left: 0;
61 | }
62 |
63 | body, html {
64 | margin: 0;
65 | padding: 0;
66 | height: 100%;
67 | position: relative;
68 | background: rgba(0.3, 0.3, 0.3, 1);
69 | font-family: sans-serif;
70 |
71 | overflow-y:hidden;
72 | overflow-x:hidden;
73 | }
74 |
75 | #container {
76 | display: none;
77 |
78 | width: 100vw;
79 | height: 100vh;
80 | position: relative;
81 | }
82 |
83 | #right-section {
84 |
85 | width: 100vw;
86 | height: 100vh;
87 | position: relative;
88 |
89 |
90 | float: right;
91 | background: rgba(0, 0, 0, .75);
92 | }
93 |
94 | #loading {
95 | display: block;
96 | position: absolute;
97 | top: 0;
98 | left: 0;
99 | z-index: 100;
100 | width: 100vw;
101 | height: 100vh;
102 | background-color: white;
103 | background-image: url("/images/loading.gif");
104 | background-repeat: no-repeat;
105 | background-position: center;
106 | }
107 |
108 | #map {
109 | width: 100%;
110 | height: 80%;
111 | position: absolute;
112 | top: 0;
113 | left: 0;
114 | }
115 |
116 | #progressbar {
117 | width: 400px;
118 | position: absolute;
119 | left: 42px;
120 | z-index: 900;
121 | font-size: 70%;
122 | margin-top: 10px;
123 | background: rgba(0, 0, 0, .5);
124 | text-align: center;
125 | }
126 |
127 | #slider {
128 | z-index: 900;
129 | position: absolute;
130 | left: 192px;
131 | margin-top: 45px;
132 |
133 | width: 238px;
134 | }
135 |
136 | #label-slider {
137 | z-index: 900;
138 | position: absolute;
139 | left: 42px;
140 | margin-top: 40px;
141 |
142 |
143 | font: 12px sans-serif;
144 |
145 | text-align: center;
146 | float: left;
147 |
148 | line-height: 200%;
149 | font-weight: bold;
150 | color: black;
151 | background-color : #d1d1d1;
152 | }
153 |
154 | #label {
155 | width: 400px;
156 | position: absolute;
157 | left: 32px;
158 | z-index: 900;
159 | font: 12px sans-serif;
160 | margin-top: 11px;
161 |
162 | text-align: center;
163 | float: left;
164 |
165 | line-height: 200%;
166 | font-weight: bold;
167 | color: white;
168 | }
169 |
170 | #tabs {
171 | width: 370px;
172 | position: absolute;
173 | right: 50px;
174 | z-index: 900;
175 | font-size: 70%;
176 | margin-top: 10px;
177 | background: rgba(0, 0, 0, .1);
178 | }
179 |
180 | #section {
181 | position: absolute;
182 | z-index: 900;
183 | margin-top: 80vh;
184 | width: 100vw;
185 | height: 20vh;
186 | float: bottom;
187 | background: rgba(0, 0, 0, .75);
188 | }
189 |
190 | #top-section {
191 | position: absolute;
192 | margin-top: 65vh;
193 | left: 0vw;
194 | width: 100vw;
195 | height: 15vh;
196 | float: bottom;
197 | z-index: 900;
198 | background: rgba(0, 0, 0, .35);
199 | }
200 |
201 | .main text {
202 | font: 10px sans-serif;
203 | }
204 |
205 | .axis path,
206 | .axis line {
207 | fill: none;
208 | stroke: #000;
209 | shape-rendering: crispEdges;
210 | }
211 |
212 | .line {
213 | fill: none;
214 | stroke: steelblue;
215 | stroke-width: 1.5px;
216 | }
217 |
218 | .leaflet-container {
219 | background: rgba(255, 255, 255, .72) !important;
220 | }
--------------------------------------------------------------------------------
/WebContent/images/android-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cicerolp/hashedcubes/ff15e60f4449762c8282b66387dcb7bab836bf77/WebContent/images/android-icon.png
--------------------------------------------------------------------------------
/WebContent/images/apple-icon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cicerolp/hashedcubes/ff15e60f4449762c8282b66387dcb7bab836bf77/WebContent/images/apple-icon.ico
--------------------------------------------------------------------------------
/WebContent/images/chrome-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cicerolp/hashedcubes/ff15e60f4449762c8282b66387dcb7bab836bf77/WebContent/images/chrome-icon.png
--------------------------------------------------------------------------------
/WebContent/images/loading.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cicerolp/hashedcubes/ff15e60f4449762c8282b66387dcb7bab836bf77/WebContent/images/loading.gif
--------------------------------------------------------------------------------
/WebContent/images/other-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cicerolp/hashedcubes/ff15e60f4449762c8282b66387dcb7bab836bf77/WebContent/images/other-icon.png
--------------------------------------------------------------------------------
/WebContent/images/twitter-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cicerolp/hashedcubes/ff15e60f4449762c8282b66387dcb7bab836bf77/WebContent/images/twitter-icon.png
--------------------------------------------------------------------------------
/WebContent/images/windows-icon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cicerolp/hashedcubes/ff15e60f4449762c8282b66387dcb7bab836bf77/WebContent/images/windows-icon.ico
--------------------------------------------------------------------------------
/WebContent/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
33 |
34 |
35 |
36 |
37 |
40 |
41 |
42 |
43 |
44 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
...
60 |
61 |
62 |
63 |
64 |
65 |
66 |
69 |
70 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
--------------------------------------------------------------------------------
/WebContent/js/d3.tip.js:
--------------------------------------------------------------------------------
1 | !function(t,e){"function"==typeof define&&define.amd?define(["d3"],e):"object"==typeof module&&module.exports?module.exports=function(t){return t.tip=e(t),t.tip}:t.d3.tip=e(t.d3)}(this,function(t){return function(){function e(t){T=d(t),b=T.createSVGPoint(),document.body.appendChild(w)}function n(){return"n"}function r(){return[0,0]}function o(){return" "}function u(){var t=g();return{top:t.n.y-w.offsetHeight,left:t.n.x-w.offsetWidth/2}}function f(){var t=g();return{top:t.s.y,left:t.s.x-w.offsetWidth/2}}function i(){var t=g();return{top:t.e.y-w.offsetHeight/2,left:t.e.x}}function l(){var t=g();return{top:t.w.y-w.offsetHeight/2,left:t.w.x-w.offsetWidth}}function s(){var t=g();return{top:t.nw.y-w.offsetHeight,left:t.nw.x-w.offsetWidth}}function a(){var t=g();return{top:t.ne.y-w.offsetHeight,left:t.ne.x}}function c(){var t=g();return{top:t.sw.y,left:t.sw.x-w.offsetWidth}}function p(){var t=g();return{top:t.se.y,left:t.e.x}}function y(){var e=t.select(document.createElement("div"));return e.style({position:"absolute",top:0,opacity:0,"pointer-events":"none","box-sizing":"border-box"}),e.node()}function d(t){return t=t.node(),"svg"===t.tagName.toLowerCase()?t:t.ownerSVGElement}function m(){return null===w&&(w=y(),document.body.appendChild(w)),t.select(w)}function g(){for(var e=C||t.event.target;"undefined"==typeof e.getScreenCTM&&"undefined"===e.parentNode;)e=e.parentNode;var n={},r=e.getScreenCTM(),o=e.getBBox(),u=o.width,f=o.height,i=o.x,l=o.y;return b.x=i,b.y=l,n.nw=b.matrixTransform(r),b.x+=u,n.ne=b.matrixTransform(r),b.y+=f,n.se=b.matrixTransform(r),b.x-=u,n.sw=b.matrixTransform(r),b.y-=f/2,n.w=b.matrixTransform(r),b.x+=u,n.e=b.matrixTransform(r),b.x-=u/2,b.y-=f/2,n.n=b.matrixTransform(r),b.y+=f,n.s=b.matrixTransform(r),n}var h=n,x=r,v=o,w=y(),T=null,b=null,C=null;e.show=function(){var t=Array.prototype.slice.call(arguments);t[t.length-1]instanceof SVGElement&&(C=t.pop());var n,r=v.apply(this,t),o=x.apply(this,t),u=h.apply(this,t),f=m(),i=H.length,l=document.documentElement.scrollTop||document.body.scrollTop,s=document.documentElement.scrollLeft||document.body.scrollLeft;for(f.html(r).style({opacity:1,"pointer-events":"all"});i--;)f.classed(H[i],!1);return n=E.get(u).apply(this),f.classed(u,!0).style({top:n.top+o[0]+l+"px",left:n.left+o[1]+s+"px"}),e},e.hide=function(){var t=m();return t.style({opacity:0,"pointer-events":"none"}),e},e.attr=function(n,r){if(arguments.length<2&&"string"==typeof n)return m().attr(n);var o=Array.prototype.slice.call(arguments);return t.selection.prototype.attr.apply(m(),o),e},e.style=function(n,r){if(arguments.length<2&&"string"==typeof n)return m().style(n);var o=Array.prototype.slice.call(arguments);return t.selection.prototype.style.apply(m(),o),e},e.direction=function(n){return arguments.length?(h=null==n?n:t.functor(n),e):h},e.offset=function(n){return arguments.length?(x=null==n?n:t.functor(n),e):x},e.html=function(n){return arguments.length?(v=null==n?n:t.functor(n),e):v},e.destroy=function(){return w&&(m().remove(),w=null),e};var E=t.map({n:u,s:f,e:i,w:l,nw:s,ne:a,sw:c,se:p}),H=E.keys();return e}});
--------------------------------------------------------------------------------
/WebContent/js/d3/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2010-2015, Michael Bostock
2 | All rights reserved.
3 |
4 | Redistribution and use in source and binary forms, with or without
5 | modification, are permitted provided that the following conditions are met:
6 |
7 | * Redistributions of source code must retain the above copyright notice, this
8 | list of conditions and the following disclaimer.
9 |
10 | * Redistributions in binary form must reproduce the above copyright notice,
11 | this list of conditions and the following disclaimer in the documentation
12 | and/or other materials provided with the distribution.
13 |
14 | * The name Michael Bostock may not be used to endorse or promote products
15 | derived from this software without specific prior written permission.
16 |
17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 | DISCLAIMED. IN NO EVENT SHALL MICHAEL BOSTOCK BE LIABLE FOR ANY DIRECT,
21 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
22 | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
24 | OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
25 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
26 | EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 |
--------------------------------------------------------------------------------
/WebContent/js/global.js:
--------------------------------------------------------------------------------
1 | var callbacks = null;
2 |
3 | var region = null, where = "", tseries = "", tile = null;
4 | var curr_region = null, curr_where = null, curr_tseries = null;
5 |
6 | var update = false;
7 | var update_tile = false;
8 |
9 | var curr_heatmap_resolution = 8, heatmap_resolution = 8;
10 |
11 | var total_count = 0, curr_count = 0;
12 | var lower_bound = null, upper_bound = null;
13 | var curr_lower_bound = null, curr_upper_bound = null;
14 |
15 | var currTile = 0;
16 |
17 | function roundtile(v, z) {
18 | v = Math.floor(v);
19 | while (v < 0) v += 1 << z;
20 | return v % (1 << z);
21 | }
22 |
23 | function tilex2lon(x, z) {
24 | return x / Math.pow(2.0, z) * 360.0 - 180;
25 | }
26 |
27 | function tiley2lat(y, z) {
28 | var n = Math.PI - 2.0 * Math.PI * y / Math.pow(2.0, z);
29 | return 180.0 / Math.PI * Math.atan(0.5 * (Math.exp(n) - Math.exp(-n)));
30 | }
31 |
32 | function lon2tilex(lon, z) {
33 | return ((lon + 180.0) / 360.0 * Math.pow(2.0, z));
34 | }
35 |
36 | function lat2tiley(lat, z) {
37 | return ((1.0 - Math.log(Math.tan(lat * Math.PI / 180.0) + 1.0 / Math.cos(lat * Math.PI / 180.0)) / Math.PI) / 2.0 * Math.pow(2.0, z));
38 | }
--------------------------------------------------------------------------------
/WebContent/js/histogram.js:
--------------------------------------------------------------------------------
1 | function setHistogramData(data, entry) {
2 |
3 | var margin = {
4 | top : 10,
5 | right : 20,
6 | bottom : 33,
7 | left : 20
8 | };
9 |
10 | var div = d3.select("#" + entry.field.name);
11 |
12 | var maxValue = -1;
13 | for (var index in data) {
14 |
15 | if (data[index][1] > maxValue)
16 | maxValue = data[index][1];
17 | }
18 |
19 | var w = div.node().getBoundingClientRect().width - margin.left - margin.right;
20 | var h = div.node().getBoundingClientRect().height - margin.top - margin.bottom;
21 |
22 | var barPadding = 1;
23 |
24 | div.selectAll("*").remove();
25 |
26 | var tip = d3.tip()
27 | .attr('class', 'd3-tip')
28 | .offset([-10, 0])
29 | .html(function(d) {
30 | return "Value: " + d[1] + "";
31 | });
32 |
33 |
34 | div = div.append("svg").attr("width", w + margin.left + margin.right).attr("height", h + margin.top + margin.bottom).append("g").attr("transform", "translate(" + margin.left + "," + margin.top + ")").call(tip);
35 |
36 |
37 | var colors = ['#007399', 'Gray']
38 |
39 | div.selectAll("rect").data(data).enter().append("rect")
40 | .attr("x", function(d, i) {
41 | return i * (w / data.length);
42 | }).attr("y", function(d) {
43 | return h - (d[1] / maxValue * h);
44 | }).attr("width", w / data.length - barPadding).attr("height", function(d) {
45 | return d[1] / maxValue * h;
46 | }).attr("fill", function(d) {
47 | return colors[0];
48 | })
49 | .on('mouseover', tip.show)
50 | .on('mouseout', tip.hide)
51 | .on('mouseup', function () { console.log("update"); })
52 | .each(function () {
53 | var selection = d3.select(this);
54 | var state = true;
55 | selection.on('mousedown', function () {
56 | if (state) {
57 | selection.style('fill', colors[1]);
58 | } else {
59 | selection.style('fill', colors[0]);
60 | }
61 | state = !state;
62 | div.selectAll("rect").each(function (d) { console.log(d3.select(this).style("fill")) });
63 |
64 | });
65 | });
66 |
67 | div.selectAll("text").data(data).enter().append("text")
68 | .text(function (d, i) {
69 | return entry.field.values[d[0]];
70 | }).attr("cx", "0").attr("cy", "0")
71 | .attr("font-family", "sans-serif")
72 | .attr("font-size", "11px")
73 | .attr("fill", "white")
74 | .attr("text-anchor", "start")
75 | .attr("transform", function (d, i) {
76 | var x = Math.max(4, h - (d[1] / maxValue * h) - this.getComputedTextLength() - 4);
77 | var y = - (i * (w / data.length) + (w / data.length - barPadding) / 2) + 4;
78 | return 'rotate(90)translate(' + x + ',' + y + ')';
79 | });
80 | }
--------------------------------------------------------------------------------
/WebContent/js/i18n/jquery-ui-timepicker-af.js:
--------------------------------------------------------------------------------
1 | /* Afrikaans translation for the jQuery Timepicker Addon */
2 | /* Written by Deon Heyns */
3 | (function($) {
4 | $.timepicker.regional['af'] = {
5 | timeOnlyTitle: 'Kies Tyd',
6 | timeText: 'Tyd ',
7 | hourText: 'Ure ',
8 | minuteText: 'Minute',
9 | secondText: 'Sekondes',
10 | millisecText: 'Millisekondes',
11 | microsecText: 'Mikrosekondes',
12 | timezoneText: 'Tydsone',
13 | currentText: 'Huidige Tyd',
14 | closeText: 'Klaar',
15 | timeFormat: 'HH:mm',
16 | timeSuffix: '',
17 | amNames: ['AM', 'A'],
18 | pmNames: ['PM', 'P'],
19 | isRTL: false
20 | };
21 | $.timepicker.setDefaults($.timepicker.regional['af']);
22 | })(jQuery);
23 |
--------------------------------------------------------------------------------
/WebContent/js/i18n/jquery-ui-timepicker-am.js:
--------------------------------------------------------------------------------
1 | /* Armenian translation for the jQuery Timepicker Addon */
2 | /* Written by Artavazd Avetisyan artavazda@hotmail.com */
3 | (function($) {
4 | $.timepicker.regional['am'] = {
5 | timeOnlyTitle: 'Ընտրեք ժամանակը',
6 | timeText: 'Ժամանակը',
7 | hourText: 'Ժամ',
8 | minuteText: 'Րոպե',
9 | secondText: 'Վարկյան',
10 | millisecText: 'Միլիվարկյան',
11 | microsecText: 'Միկրովարկյան',
12 | timezoneText: 'Ժամային գոտին',
13 | currentText: 'Այժմ',
14 | closeText: 'Փակել',
15 | timeFormat: 'HH:mm',
16 | timeSuffix: '',
17 | amNames: ['AM', 'A'],
18 | pmNames: ['PM', 'P'],
19 | isRTL: false
20 | };
21 | $.timepicker.setDefaults($.timepicker.regional['am']);
22 | })(jQuery);
23 |
--------------------------------------------------------------------------------
/WebContent/js/i18n/jquery-ui-timepicker-bg.js:
--------------------------------------------------------------------------------
1 | /* Bulgarian translation for the jQuery Timepicker Addon */
2 | /* Written by Plamen Kovandjiev */
3 | (function($) {
4 | $.timepicker.regional['bg'] = {
5 | timeOnlyTitle: 'Изберете време',
6 | timeText: 'Време',
7 | hourText: 'Час',
8 | minuteText: 'Минути',
9 | secondText: 'Секунди',
10 | millisecText: 'Милисекунди',
11 | microsecText: 'Микросекунди',
12 | timezoneText: 'Часови пояс',
13 | currentText: 'Сега',
14 | closeText: 'Затвори',
15 | timeFormat: 'HH:mm',
16 | timeSuffix: '',
17 | amNames: ['AM', 'A'],
18 | pmNames: ['PM', 'P'],
19 | isRTL: false
20 | };
21 | $.timepicker.setDefaults($.timepicker.regional['bg']);
22 | })(jQuery);
--------------------------------------------------------------------------------
/WebContent/js/i18n/jquery-ui-timepicker-ca.js:
--------------------------------------------------------------------------------
1 | /* Catalan translation for the jQuery Timepicker Addon */
2 | /* Written by Sergi Faber */
3 | (function($) {
4 | $.timepicker.regional['ca'] = {
5 | timeOnlyTitle: 'Escollir una hora',
6 | timeText: 'Hora',
7 | hourText: 'Hores',
8 | minuteText: 'Minuts',
9 | secondText: 'Segons',
10 | millisecText: 'Milisegons',
11 | microsecText: 'Microsegons',
12 | timezoneText: 'Fus horari',
13 | currentText: 'Ara',
14 | closeText: 'Tancar',
15 | timeFormat: 'HH:mm',
16 | timeSuffix: '',
17 | amNames: ['AM', 'A'],
18 | pmNames: ['PM', 'P'],
19 | isRTL: false
20 | };
21 | $.timepicker.setDefaults($.timepicker.regional['ca']);
22 | })(jQuery);
23 |
--------------------------------------------------------------------------------
/WebContent/js/i18n/jquery-ui-timepicker-cs.js:
--------------------------------------------------------------------------------
1 | /* Czech translation for the jQuery Timepicker Addon */
2 | /* Written by Ondřej Vodáček */
3 | (function($) {
4 | $.timepicker.regional['cs'] = {
5 | timeOnlyTitle: 'Vyberte čas',
6 | timeText: 'Čas',
7 | hourText: 'Hodiny',
8 | minuteText: 'Minuty',
9 | secondText: 'Vteřiny',
10 | millisecText: 'Milisekundy',
11 | microsecText: 'Mikrosekundy',
12 | timezoneText: 'Časové pásmo',
13 | currentText: 'Nyní',
14 | closeText: 'Zavřít',
15 | timeFormat: 'HH:mm',
16 | timeSuffix: '',
17 | amNames: ['dop.', 'AM', 'A'],
18 | pmNames: ['odp.', 'PM', 'P'],
19 | isRTL: false
20 | };
21 | $.timepicker.setDefaults($.timepicker.regional['cs']);
22 | })(jQuery);
23 |
--------------------------------------------------------------------------------
/WebContent/js/i18n/jquery-ui-timepicker-da.js:
--------------------------------------------------------------------------------
1 | /* Danish translation for the jQuery Timepicker Addon */
2 | /* Written by Lars H. Jensen (http://www.larshj.dk) */
3 | (function ($) {
4 | $.timepicker.regional['da'] = {
5 | timeOnlyTitle: 'Vælg tid',
6 | timeText: 'Tid',
7 | hourText: 'Time',
8 | minuteText: 'Minut',
9 | secondText: 'Sekund',
10 | millisecText: 'Millisekund',
11 | microsecText: 'Mikrosekund',
12 | timezoneText: 'Tidszone',
13 | currentText: 'Nu',
14 | closeText: 'Luk',
15 | timeFormat: 'HH:mm',
16 | timeSuffix: '',
17 | amNames: ['am', 'AM', 'A'],
18 | pmNames: ['pm', 'PM', 'P'],
19 | isRTL: false
20 | };
21 | $.timepicker.setDefaults($.timepicker.regional['da']);
22 | })(jQuery);
23 |
--------------------------------------------------------------------------------
/WebContent/js/i18n/jquery-ui-timepicker-de.js:
--------------------------------------------------------------------------------
1 | /* German translation for the jQuery Timepicker Addon */
2 | /* Written by Marvin */
3 | (function($) {
4 | $.timepicker.regional['de'] = {
5 | timeOnlyTitle: 'Zeit wählen',
6 | timeText: 'Zeit',
7 | hourText: 'Stunde',
8 | minuteText: 'Minute',
9 | secondText: 'Sekunde',
10 | millisecText: 'Millisekunde',
11 | microsecText: 'Mikrosekunde',
12 | timezoneText: 'Zeitzone',
13 | currentText: 'Jetzt',
14 | closeText: 'Fertig',
15 | timeFormat: 'HH:mm',
16 | timeSuffix: '',
17 | amNames: ['vorm.', 'AM', 'A'],
18 | pmNames: ['nachm.', 'PM', 'P'],
19 | isRTL: false
20 | };
21 | $.timepicker.setDefaults($.timepicker.regional['de']);
22 | })(jQuery);
23 |
--------------------------------------------------------------------------------
/WebContent/js/i18n/jquery-ui-timepicker-el.js:
--------------------------------------------------------------------------------
1 | /* Hellenic translation for the jQuery Timepicker Addon */
2 | /* Written by Christos Pontikis */
3 | (function($) {
4 | $.timepicker.regional['el'] = {
5 | timeOnlyTitle: 'Επιλογή ώρας',
6 | timeText: 'Ώρα',
7 | hourText: 'Ώρες',
8 | minuteText: 'Λεπτά',
9 | secondText: 'Δευτερόλεπτα',
10 | millisecText: 'μιλιδευτερόλεπτο',
11 | microsecText: 'Microseconds',
12 | timezoneText: 'Ζώνη ώρας',
13 | currentText: 'Τώρα',
14 | closeText: 'Κλείσιμο',
15 | timeFormat: 'HH:mm',
16 | timeSuffix: '',
17 | amNames: ['π.μ.', 'AM', 'A'],
18 | pmNames: ['μ.μ.', 'PM', 'P'],
19 | isRTL: false
20 | };
21 | $.timepicker.setDefaults($.timepicker.regional['el']);
22 | })(jQuery);
23 |
--------------------------------------------------------------------------------
/WebContent/js/i18n/jquery-ui-timepicker-es.js:
--------------------------------------------------------------------------------
1 | /* Spanish translation for the jQuery Timepicker Addon */
2 | /* Written by Ianaré Sévi */
3 | /* Modified by Carlos Martínez */
4 | (function($) {
5 | $.timepicker.regional['es'] = {
6 | timeOnlyTitle: 'Elegir una hora',
7 | timeText: 'Hora',
8 | hourText: 'Horas',
9 | minuteText: 'Minutos',
10 | secondText: 'Segundos',
11 | millisecText: 'Milisegundos',
12 | microsecText: 'Microsegundos',
13 | timezoneText: 'Uso horario',
14 | currentText: 'Hoy',
15 | closeText: 'Cerrar',
16 | timeFormat: 'HH:mm',
17 | timeSuffix: '',
18 | amNames: ['a.m.', 'AM', 'A'],
19 | pmNames: ['p.m.', 'PM', 'P'],
20 | isRTL: false
21 | };
22 | $.timepicker.setDefaults($.timepicker.regional['es']);
23 | })(jQuery);
24 |
--------------------------------------------------------------------------------
/WebContent/js/i18n/jquery-ui-timepicker-et.js:
--------------------------------------------------------------------------------
1 | /* Estonian translation for the jQuery Timepicker Addon */
2 | /* Written by Karl Sutt (karl@sutt.ee) */
3 | (function($) {
4 | $.timepicker.regional['et'] = {
5 | timeOnlyTitle: 'Vali aeg',
6 | timeText: 'Aeg',
7 | hourText: 'Tund',
8 | minuteText: 'Minut',
9 | secondText: 'Sekund',
10 | millisecText: 'Millisekundis',
11 | microsecText: 'Mikrosekundis',
12 | timezoneText: 'Ajavöönd',
13 | currentText: 'Praegu',
14 | closeText: 'Valmis',
15 | timeFormat: 'HH:mm',
16 | timeSuffix: '',
17 | amNames: ['AM', 'A'],
18 | pmNames: ['PM', 'P'],
19 | isRTL: false
20 | };
21 | $.timepicker.setDefaults($.timepicker.regional['et']);
22 | })(jQuery);
23 |
--------------------------------------------------------------------------------
/WebContent/js/i18n/jquery-ui-timepicker-eu.js:
--------------------------------------------------------------------------------
1 | /* Basque trannslation for JQuery Timepicker Addon */
2 | /* Translated by Xabi Fer */
3 | /* Fixed by Asier Iturralde Sarasola - iametza interaktiboa */
4 | (function($) {
5 | $.timepicker.regional['eu'] = {
6 | timeOnlyTitle: 'Aukeratu ordua',
7 | timeText: 'Ordua',
8 | hourText: 'Orduak',
9 | minuteText: 'Minutuak',
10 | secondText: 'Segundoak',
11 | millisecText: 'Milisegundoak',
12 | microsecText: 'Mikrosegundoak',
13 | timezoneText: 'Ordu-eremua',
14 | currentText: 'Orain',
15 | closeText: 'Itxi',
16 | timeFormat: 'HH:mm',
17 | timeSuffix: '',
18 | amNames: ['a.m.', 'AM', 'A'],
19 | pmNames: ['p.m.', 'PM', 'P'],
20 | isRTL: false
21 | };
22 | $.timepicker.setDefaults($.timepicker.regional['eu']);
23 | })(jQuery);
--------------------------------------------------------------------------------
/WebContent/js/i18n/jquery-ui-timepicker-fa.js:
--------------------------------------------------------------------------------
1 | /* Persian translation for the jQuery Timepicker Addon */
2 | /* Written by Meysam Pour Ganji */
3 | (function($) {
4 | $.timepicker.regional['fa'] = {
5 | timeOnlyTitle: 'انتخاب زمان',
6 | timeText: 'زمان',
7 | hourText: 'ساعت',
8 | minuteText: 'دقیقه',
9 | secondText: 'ثانیه',
10 | millisecText: 'میلی ثانیه',
11 | microsecText: 'میکرو ثانیه',
12 | timezoneText: 'منطقه زمانی',
13 | currentText: 'الان',
14 | closeText: 'انتخاب',
15 | timeFormat: 'HH:mm',
16 | timeSuffix: '',
17 | amNames: ['قبل ظهر', 'AM', 'A'],
18 | pmNames: ['بعد ظهر', 'PM', 'P'],
19 | isRTL: true
20 | };
21 | $.timepicker.setDefaults($.timepicker.regional['fa']);
22 | })(jQuery);
23 |
--------------------------------------------------------------------------------
/WebContent/js/i18n/jquery-ui-timepicker-fi.js:
--------------------------------------------------------------------------------
1 | /* Finnish translation for the jQuery Timepicker Addon */
2 | /* Written by Juga Paazmaya (http://github.com/paazmaya) */
3 | (function($) {
4 | $.timepicker.regional['fi'] = {
5 | timeOnlyTitle: 'Valitse aika',
6 | timeText: 'Aika',
7 | hourText: 'Tunti',
8 | minuteText: 'Minuutti',
9 | secondText: 'Sekunti',
10 | millisecText: 'Millisekunnin',
11 | microsecText: 'Mikrosekuntia',
12 | timezoneText: 'Aikavyöhyke',
13 | currentText: 'Nyt',
14 | closeText: 'Sulje',
15 | timeFormat: 'HH:mm',
16 | timeSuffix: '',
17 | amNames: ['ap.', 'AM', 'A'],
18 | pmNames: ['ip.', 'PM', 'P'],
19 | isRTL: false
20 | };
21 | $.timepicker.setDefaults($.timepicker.regional['fi']);
22 | })(jQuery);
23 |
--------------------------------------------------------------------------------
/WebContent/js/i18n/jquery-ui-timepicker-fr.js:
--------------------------------------------------------------------------------
1 | /* French translation for the jQuery Timepicker Addon */
2 | /* Written by Thomas Lété */
3 | (function($) {
4 | $.timepicker.regional['fr'] = {
5 | timeOnlyTitle: 'Choisir une heure',
6 | timeText: 'Heure',
7 | hourText: 'Heures',
8 | minuteText: 'Minutes',
9 | secondText: 'Secondes',
10 | millisecText: 'Millisecondes',
11 | microsecText: 'Microsecondes',
12 | timezoneText: 'Fuseau horaire',
13 | currentText: 'Maintenant',
14 | closeText: 'Terminé',
15 | timeFormat: 'HH:mm',
16 | timeSuffix: '',
17 | amNames: ['AM', 'A'],
18 | pmNames: ['PM', 'P'],
19 | isRTL: false
20 | };
21 | $.timepicker.setDefaults($.timepicker.regional['fr']);
22 | })(jQuery);
23 |
--------------------------------------------------------------------------------
/WebContent/js/i18n/jquery-ui-timepicker-gl.js:
--------------------------------------------------------------------------------
1 | /* Galician translation for the jQuery Timepicker Addon */
2 | /* Written by David Barral */
3 | (function($) {
4 | $.timepicker.regional['gl'] = {
5 | timeOnlyTitle: 'Elixir unha hora',
6 | timeText: 'Hora',
7 | hourText: 'Horas',
8 | minuteText: 'Minutos',
9 | secondText: 'Segundos',
10 | millisecText: 'Milisegundos',
11 | microsecText: 'Microssegundos',
12 | timezoneText: 'Fuso horario',
13 | currentText: 'Agora',
14 | closeText: 'Pechar',
15 | timeFormat: 'HH:mm',
16 | timeSuffix: '',
17 | amNames: ['a.m.', 'AM', 'A'],
18 | pmNames: ['p.m.', 'PM', 'P'],
19 | isRTL: false
20 | };
21 | $.timepicker.setDefaults($.timepicker.regional['gl']);
22 | })(jQuery);
23 |
--------------------------------------------------------------------------------
/WebContent/js/i18n/jquery-ui-timepicker-he.js:
--------------------------------------------------------------------------------
1 | /* Hebrew translation for the jQuery Timepicker Addon */
2 | /* Written by Lior Lapid */
3 | (function($) {
4 | $.timepicker.regional["he"] = {
5 | timeOnlyTitle: "בחירת זמן",
6 | timeText: "שעה",
7 | hourText: "שעות",
8 | minuteText: "דקות",
9 | secondText: "שניות",
10 | millisecText: "אלפית השנייה",
11 | microsecText: "מיקרו",
12 | timezoneText: "אזור זמן",
13 | currentText: "עכשיו",
14 | closeText:"סגור",
15 | timeFormat: "HH:mm",
16 | timeSuffix: '',
17 | amNames: ['לפנה"צ', 'AM', 'A'],
18 | pmNames: ['אחה"צ', 'PM', 'P'],
19 | isRTL: true
20 | };
21 | $.timepicker.setDefaults($.timepicker.regional["he"]);
22 | })(jQuery);
23 |
--------------------------------------------------------------------------------
/WebContent/js/i18n/jquery-ui-timepicker-hr.js:
--------------------------------------------------------------------------------
1 | /* Croatian translation for the jQuery Timepicker Addon */
2 | /* Written by Mladen */
3 | (function($) {
4 | $.timepicker.regional['hr'] = {
5 | timeOnlyTitle: 'Odaberi vrijeme',
6 | timeText: 'Vrijeme',
7 | hourText: 'Sati',
8 | minuteText: 'Minute',
9 | secondText: 'Sekunde',
10 | millisecText: 'Milisekunde',
11 | microsecText: 'Mikrosekunde',
12 | timezoneText: 'Vremenska zona',
13 | currentText: 'Sada',
14 | closeText: 'Gotovo',
15 | timeFormat: 'HH:mm',
16 | timeSuffix: '',
17 | amNames: ['a.m.', 'AM', 'A'],
18 | pmNames: ['p.m.', 'PM', 'P'],
19 | isRTL: false
20 | };
21 | $.timepicker.setDefaults($.timepicker.regional['hr']);
22 | })(jQuery);
--------------------------------------------------------------------------------
/WebContent/js/i18n/jquery-ui-timepicker-hu.js:
--------------------------------------------------------------------------------
1 | /* Hungarian translation for the jQuery Timepicker Addon */
2 | /* Written by Vas Gábor */
3 | (function($) {
4 | $.timepicker.regional['hu'] = {
5 | timeOnlyTitle: 'Válasszon időpontot',
6 | timeText: 'Idő',
7 | hourText: 'Óra',
8 | minuteText: 'Perc',
9 | secondText: 'Másodperc',
10 | millisecText: 'Milliszekundumos',
11 | microsecText: 'Ezredmásodperc',
12 | timezoneText: 'Időzóna',
13 | currentText: 'Most',
14 | closeText: 'Kész',
15 | timeFormat: 'HH:mm',
16 | timeSuffix: '',
17 | amNames: ['de.', 'AM', 'A'],
18 | pmNames: ['du.', 'PM', 'P'],
19 | isRTL: false
20 | };
21 | $.timepicker.setDefaults($.timepicker.regional['hu']);
22 | })(jQuery);
23 |
--------------------------------------------------------------------------------
/WebContent/js/i18n/jquery-ui-timepicker-id.js:
--------------------------------------------------------------------------------
1 | /* Indonesian translation for the jQuery Timepicker Addon */
2 | /* Written by Nia */
3 | (function($) {
4 | $.timepicker.regional['id'] = {
5 | timeOnlyTitle: 'Pilih Waktu',
6 | timeText: 'Waktu',
7 | hourText: 'Pukul',
8 | minuteText: 'Menit',
9 | secondText: 'Detik',
10 | millisecText: 'Milidetik',
11 | microsecText: 'Mikrodetik',
12 | timezoneText: 'Zona Waktu',
13 | currentText: 'Sekarang',
14 | closeText: 'OK',
15 | timeFormat: 'HH:mm',
16 | timeSuffix: '',
17 | amNames: ['AM', 'A'],
18 | pmNames: ['PM', 'P'],
19 | isRTL: false
20 | };
21 | $.timepicker.setDefaults($.timepicker.regional['id']);
22 | })(jQuery);
23 |
--------------------------------------------------------------------------------
/WebContent/js/i18n/jquery-ui-timepicker-it.js:
--------------------------------------------------------------------------------
1 | /* Italian translation for the jQuery Timepicker Addon */
2 | /* Written by Marco "logicoder" Del Tongo */
3 | (function($) {
4 | $.timepicker.regional['it'] = {
5 | timeOnlyTitle: 'Scegli orario',
6 | timeText: 'Orario',
7 | hourText: 'Ora',
8 | minuteText: 'Minuti',
9 | secondText: 'Secondi',
10 | millisecText: 'Millisecondi',
11 | microsecText: 'Microsecondi',
12 | timezoneText: 'Fuso orario',
13 | currentText: 'Adesso',
14 | closeText: 'Chiudi',
15 | timeFormat: 'HH:mm',
16 | timeSuffix: '',
17 | amNames: ['m.', 'AM', 'A'],
18 | pmNames: ['p.', 'PM', 'P'],
19 | isRTL: false
20 | };
21 | $.timepicker.setDefaults($.timepicker.regional['it']);
22 | })(jQuery);
23 |
--------------------------------------------------------------------------------
/WebContent/js/i18n/jquery-ui-timepicker-ja.js:
--------------------------------------------------------------------------------
1 | /* Japanese translation for the jQuery Timepicker Addon */
2 | /* Written by Jun Omae */
3 | (function($) {
4 | $.timepicker.regional['ja'] = {
5 | timeOnlyTitle: '時間を選択',
6 | timeText: '時間',
7 | hourText: '時',
8 | minuteText: '分',
9 | secondText: '秒',
10 | millisecText: 'ミリ秒',
11 | microsecText: 'マイクロ秒',
12 | timezoneText: 'タイムゾーン',
13 | currentText: '現時刻',
14 | closeText: '閉じる',
15 | timeFormat: 'HH:mm',
16 | timeSuffix: '',
17 | amNames: ['午前', 'AM', 'A'],
18 | pmNames: ['午後', 'PM', 'P'],
19 | isRTL: false
20 | };
21 | $.timepicker.setDefaults($.timepicker.regional['ja']);
22 | })(jQuery);
23 |
--------------------------------------------------------------------------------
/WebContent/js/i18n/jquery-ui-timepicker-ko.js:
--------------------------------------------------------------------------------
1 | /* Korean translation for the jQuery Timepicker Addon */
2 | /* Written by Genie */
3 | (function($) {
4 | $.timepicker.regional['ko'] = {
5 | timeOnlyTitle: '시간 선택',
6 | timeText: '시간',
7 | hourText: '시',
8 | minuteText: '분',
9 | secondText: '초',
10 | millisecText: '밀리초',
11 | microsecText: '마이크로',
12 | timezoneText: '표준 시간대',
13 | currentText: '현재 시각',
14 | closeText: '닫기',
15 | timeFormat: 'tt h:mm',
16 | timeSuffix: '',
17 | amNames: ['오전', 'AM', 'A'],
18 | pmNames: ['오후', 'PM', 'P'],
19 | isRTL: false
20 | };
21 | $.timepicker.setDefaults($.timepicker.regional['ko']);
22 | })(jQuery);
23 |
--------------------------------------------------------------------------------
/WebContent/js/i18n/jquery-ui-timepicker-lt.js:
--------------------------------------------------------------------------------
1 | /* Lithuanian translation for the jQuery Timepicker Addon */
2 | /* Written by Irmantas Šiupšinskas */
3 | (function($) {
4 | $.timepicker.regional['lt'] = {
5 | timeOnlyTitle: 'Pasirinkite laiką',
6 | timeText: 'Laikas',
7 | hourText: 'Valandos',
8 | minuteText: 'Minutės',
9 | secondText: 'Sekundės',
10 | millisecText: 'Milisekundės',
11 | microsecText: 'Mikrosekundės',
12 | timezoneText: 'Laiko zona',
13 | currentText: 'Dabar',
14 | closeText: 'Uždaryti',
15 | timeFormat: 'HH:mm',
16 | timeSuffix: '',
17 | amNames: ['priešpiet', 'AM', 'A'],
18 | pmNames: ['popiet', 'PM', 'P'],
19 | isRTL: false
20 | };
21 | $.timepicker.setDefaults($.timepicker.regional['lt']);
22 | })(jQuery);
23 |
--------------------------------------------------------------------------------
/WebContent/js/i18n/jquery-ui-timepicker-lv.js:
--------------------------------------------------------------------------------
1 | /* Latvian translation for the jQuery Timepicker Addon */
2 | /* Written by Dmitry Bogatykh */
3 | (function($) {
4 | $.timepicker.regional['lv'] = {
5 | timeOnlyTitle: 'Ievadiet laiku',
6 | timeText: 'Laiks',
7 | hourText: 'Stundas',
8 | minuteText: 'Minūtes',
9 | secondText: 'Sekundes',
10 | millisecText: 'Milisekundes',
11 | microsecText: 'Mikrosekundes',
12 | timezoneText: 'Laika josla',
13 | currentText: 'Tagad',
14 | closeText: 'Aizvērt',
15 | timeFormat: 'HH:mm',
16 | timeSuffix: '',
17 | amNames: ['AM', 'AM', 'A'],
18 | pmNames: ['PM', 'PM', 'P'],
19 | isRTL: false
20 | };
21 | $.timepicker.setDefaults($.timepicker.regional['lv']);
22 | })(jQuery);
--------------------------------------------------------------------------------
/WebContent/js/i18n/jquery-ui-timepicker-mk.js:
--------------------------------------------------------------------------------
1 | /* Macedonian cyrilic translation for the jQuery Timepicker Addon */
2 | /* Written by Vlatko Ristovski */
3 | (function($) {
4 | $.timepicker.regional['mk'] = {
5 | timeOnlyTitle: 'Одберете време',
6 | timeText: 'Време',
7 | hourText: 'Час',
8 | minuteText: 'Минути',
9 | secondText: 'Секунди',
10 | millisecText: 'Милисекунди',
11 | microsecText: 'Микросекунди',
12 | timezoneText: 'Временска зона',
13 | currentText: 'Сега',
14 | closeText: 'Затвори',
15 | timeFormat: 'HH:mm',
16 | timeSuffix: '',
17 | amNames: ['AM', 'A'],
18 | pmNames: ['PM', 'P'],
19 | isRTL: false
20 | };
21 | $.timepicker.setDefaults($.timepicker.regional['mk']);
22 | })(jQuery);
--------------------------------------------------------------------------------
/WebContent/js/i18n/jquery-ui-timepicker-nl.js:
--------------------------------------------------------------------------------
1 | /* Dutch translation for the jQuery Timepicker Addon */
2 | /* Written by Martijn van der Lee */
3 | (function($) {
4 | $.timepicker.regional['nl'] = {
5 | timeOnlyTitle: 'Tijdstip',
6 | timeText: 'Tijd',
7 | hourText: 'Uur',
8 | minuteText: 'Minuut',
9 | secondText: 'Seconde',
10 | millisecText: 'Milliseconde',
11 | microsecText: 'Microseconde',
12 | timezoneText: 'Tijdzone',
13 | currentText: 'Vandaag',
14 | closeText: 'Sluiten',
15 | timeFormat: 'HH:mm',
16 | timeSuffix: '',
17 | amNames: ['AM', 'A'],
18 | pmNames: ['PM', 'P'],
19 | isRTL: false
20 | };
21 | $.timepicker.setDefaults($.timepicker.regional['nl']);
22 | })(jQuery);
23 |
--------------------------------------------------------------------------------
/WebContent/js/i18n/jquery-ui-timepicker-no.js:
--------------------------------------------------------------------------------
1 | /* Norwegian translation for the jQuery Timepicker Addon */
2 | /* Written by Morten Hauan (http://hauan.me) */
3 | (function($) {
4 | $.timepicker.regional['no'] = {
5 | timeOnlyTitle: 'Velg tid',
6 | timeText: 'Tid',
7 | hourText: 'Time',
8 | minuteText: 'Minutt',
9 | secondText: 'Sekund',
10 | millisecText: 'Millisekund',
11 | microsecText: 'mikrosekund',
12 | timezoneText: 'Tidssone',
13 | currentText: 'Nå',
14 | closeText: 'Lukk',
15 | timeFormat: 'HH:mm',
16 | timeSuffix: '',
17 | amNames: ['am', 'AM', 'A'],
18 | pmNames: ['pm', 'PM', 'P'],
19 | isRTL: false
20 | };
21 | $.timepicker.setDefaults($.timepicker.regional['no']);
22 | })(jQuery);
23 |
--------------------------------------------------------------------------------
/WebContent/js/i18n/jquery-ui-timepicker-pl.js:
--------------------------------------------------------------------------------
1 | /* Polish translation for the jQuery Timepicker Addon */
2 | /* Written by Michał Pena */
3 | (function($) {
4 | $.timepicker.regional['pl'] = {
5 | timeOnlyTitle: 'Wybierz godzinę',
6 | timeText: 'Czas',
7 | hourText: 'Godzina',
8 | minuteText: 'Minuta',
9 | secondText: 'Sekunda',
10 | millisecText: 'Milisekunda',
11 | microsecText: 'Mikrosekunda',
12 | timezoneText: 'Strefa czasowa',
13 | currentText: 'Teraz',
14 | closeText: 'Gotowe',
15 | timeFormat: 'HH:mm',
16 | timeSuffix: '',
17 | amNames: ['AM', 'A'],
18 | pmNames: ['PM', 'P'],
19 | isRTL: false
20 | };
21 | $.timepicker.setDefaults($.timepicker.regional['pl']);
22 | })(jQuery);
23 |
--------------------------------------------------------------------------------
/WebContent/js/i18n/jquery-ui-timepicker-pt-BR.js:
--------------------------------------------------------------------------------
1 | /* Brazilian Portuguese translation for the jQuery Timepicker Addon */
2 | /* Written by Diogo Damiani (diogodamiani@gmail.com) */
3 | (function ($) {
4 | $.timepicker.regional['pt-BR'] = {
5 | timeOnlyTitle: 'Escolha o horário',
6 | timeText: 'Horário',
7 | hourText: 'Hora',
8 | minuteText: 'Minutos',
9 | secondText: 'Segundos',
10 | millisecText: 'Milissegundos',
11 | microsecText: 'Microssegundos',
12 | timezoneText: 'Fuso horário',
13 | currentText: 'Agora',
14 | closeText: 'Fechar',
15 | timeFormat: 'HH:mm',
16 | timeSuffix: '',
17 | amNames: ['a.m.', 'AM', 'A'],
18 | pmNames: ['p.m.', 'PM', 'P'],
19 | isRTL: false
20 | };
21 | $.timepicker.setDefaults($.timepicker.regional['pt-BR']);
22 | })(jQuery);
23 |
--------------------------------------------------------------------------------
/WebContent/js/i18n/jquery-ui-timepicker-pt.js:
--------------------------------------------------------------------------------
1 | /* Portuguese translation for the jQuery Timepicker Addon */
2 | /* Written by Luan Almeida */
3 | (function($) {
4 | $.timepicker.regional['pt'] = {
5 | timeOnlyTitle: 'Escolha uma hora',
6 | timeText: 'Hora',
7 | hourText: 'Horas',
8 | minuteText: 'Minutos',
9 | secondText: 'Segundos',
10 | millisecText: 'Milissegundos',
11 | microsecText: 'Microssegundos',
12 | timezoneText: 'Fuso horário',
13 | currentText: 'Agora',
14 | closeText: 'Fechar',
15 | timeFormat: 'HH:mm',
16 | timeSuffix: '',
17 | amNames: ['a.m.', 'AM', 'A'],
18 | pmNames: ['p.m.', 'PM', 'P'],
19 | isRTL: false
20 | };
21 | $.timepicker.setDefaults($.timepicker.regional['pt']);
22 | })(jQuery);
23 |
--------------------------------------------------------------------------------
/WebContent/js/i18n/jquery-ui-timepicker-ro.js:
--------------------------------------------------------------------------------
1 | /* Romanian translation for the jQuery Timepicker Addon */
2 | /* Written by Romeo Adrian Cioaba */
3 | (function($) {
4 | $.timepicker.regional['ro'] = {
5 | timeOnlyTitle: 'Alegeţi o oră',
6 | timeText: 'Timp',
7 | hourText: 'Ore',
8 | minuteText: 'Minute',
9 | secondText: 'Secunde',
10 | millisecText: 'Milisecunde',
11 | microsecText: 'Microsecunde',
12 | timezoneText: 'Fus orar',
13 | currentText: 'Acum',
14 | closeText: 'Închide',
15 | timeFormat: 'HH:mm',
16 | timeSuffix: '',
17 | amNames: ['AM', 'A'],
18 | pmNames: ['PM', 'P'],
19 | isRTL: false
20 | };
21 | $.timepicker.setDefaults($.timepicker.regional['ro']);
22 | })(jQuery);
23 |
--------------------------------------------------------------------------------
/WebContent/js/i18n/jquery-ui-timepicker-ru.js:
--------------------------------------------------------------------------------
1 | /* Russian translation for the jQuery Timepicker Addon */
2 | /* Written by Trent Richardson */
3 | (function($) {
4 | $.timepicker.regional['ru'] = {
5 | timeOnlyTitle: 'Выберите время',
6 | timeText: 'Время',
7 | hourText: 'Часы',
8 | minuteText: 'Минуты',
9 | secondText: 'Секунды',
10 | millisecText: 'Миллисекунды',
11 | microsecText: 'Микросекунды',
12 | timezoneText: 'Часовой пояс',
13 | currentText: 'Сейчас',
14 | closeText: 'Закрыть',
15 | timeFormat: 'HH:mm',
16 | timeSuffix: '',
17 | amNames: ['AM', 'A'],
18 | pmNames: ['PM', 'P'],
19 | isRTL: false
20 | };
21 | $.timepicker.setDefaults($.timepicker.regional['ru']);
22 | })(jQuery);
23 |
--------------------------------------------------------------------------------
/WebContent/js/i18n/jquery-ui-timepicker-sk.js:
--------------------------------------------------------------------------------
1 | /* Slovak translation for the jQuery Timepicker Addon */
2 | /* Written by David Vallner */
3 | (function($) {
4 | $.timepicker.regional['sk'] = {
5 | timeOnlyTitle: 'Zvoľte čas',
6 | timeText: 'Čas',
7 | hourText: 'Hodiny',
8 | minuteText: 'Minúty',
9 | secondText: 'Sekundy',
10 | millisecText: 'Milisekundy',
11 | microsecText: 'Mikrosekundy',
12 | timezoneText: 'Časové pásmo',
13 | currentText: 'Teraz',
14 | closeText: 'Zavrieť',
15 | timeFormat: 'H:m',
16 | timeSuffix: '',
17 | amNames: ['dop.', 'AM', 'A'],
18 | pmNames: ['pop.', 'PM', 'P'],
19 | isRTL: false
20 | };
21 | $.timepicker.setDefaults($.timepicker.regional['sk']);
22 | })(jQuery);
23 |
--------------------------------------------------------------------------------
/WebContent/js/i18n/jquery-ui-timepicker-sl.js:
--------------------------------------------------------------------------------
1 | /* Slovenian translation for the jQuery Timepicker Addon */
2 | /* Written by Hadalin (https://github.com/hadalin) */
3 | (function($) {
4 | $.timepicker.regional['sl'] = {
5 | timeOnlyTitle: 'Izberite čas',
6 | timeText: 'Čas',
7 | hourText: 'Ura',
8 | minuteText: 'Minute',
9 | secondText: 'Sekunde',
10 | millisecText: 'Milisekunde',
11 | microsecText: 'Mikrosekunde',
12 | timezoneText: 'Časovni pas',
13 | currentText: 'Sedaj',
14 | closeText: 'Zapri',
15 | timeFormat: 'HH:mm',
16 | timeSuffix: '',
17 | amNames: ['dop.', 'AM', 'A'],
18 | pmNames: ['pop.', 'PM', 'P'],
19 | isRTL: false
20 | };
21 | $.timepicker.setDefaults($.timepicker.regional['sl']);
22 | })(jQuery);
23 |
--------------------------------------------------------------------------------
/WebContent/js/i18n/jquery-ui-timepicker-sr-RS.js:
--------------------------------------------------------------------------------
1 | /* Serbian cyrilic translation for the jQuery Timepicker Addon */
2 | /* Written by Vladimir Jelovac */
3 | (function($) {
4 | $.timepicker.regional['sr-RS'] = {
5 | timeOnlyTitle: 'Одаберите време',
6 | timeText: 'Време',
7 | hourText: 'Сати',
8 | minuteText: 'Минути',
9 | secondText: 'Секунде',
10 | millisecText: 'Милисекунде',
11 | microsecText: 'Микросекунде',
12 | timezoneText: 'Временска зона',
13 | currentText: 'Сада',
14 | closeText: 'Затвори',
15 | timeFormat: 'HH:mm',
16 | timeSuffix: '',
17 | amNames: ['AM', 'A'],
18 | pmNames: ['PM', 'P'],
19 | isRTL: false
20 | };
21 | $.timepicker.setDefaults($.timepicker.regional['sr-RS']);
22 | })(jQuery);
23 |
--------------------------------------------------------------------------------
/WebContent/js/i18n/jquery-ui-timepicker-sr-YU.js:
--------------------------------------------------------------------------------
1 | /* Serbian latin translation for the jQuery Timepicker Addon */
2 | /* Written by Vladimir Jelovac */
3 | (function($) {
4 | $.timepicker.regional['sr-YU'] = {
5 | timeOnlyTitle: 'Odaberite vreme',
6 | timeText: 'Vreme',
7 | hourText: 'Sati',
8 | minuteText: 'Minuti',
9 | secondText: 'Sekunde',
10 | millisecText: 'Milisekunde',
11 | microsecText: 'Mikrosekunde',
12 | timezoneText: 'Vremenska zona',
13 | currentText: 'Sada',
14 | closeText: 'Zatvori',
15 | timeFormat: 'HH:mm',
16 | timeSuffix: '',
17 | amNames: ['AM', 'A'],
18 | pmNames: ['PM', 'P'],
19 | isRTL: false
20 | };
21 | $.timepicker.setDefaults($.timepicker.regional['sr-YU']);
22 | })(jQuery);
23 |
--------------------------------------------------------------------------------
/WebContent/js/i18n/jquery-ui-timepicker-sv.js:
--------------------------------------------------------------------------------
1 | /* Swedish translation for the jQuery Timepicker Addon */
2 | /* Written by Nevon */
3 | (function($) {
4 | $.timepicker.regional['sv'] = {
5 | timeOnlyTitle: 'Välj en tid',
6 | timeText: 'Tid',
7 | hourText: 'Timme',
8 | minuteText: 'Minut',
9 | secondText: 'Sekund',
10 | millisecText: 'Millisekund',
11 | microsecText: 'Mikrosekund',
12 | timezoneText: 'Tidszon',
13 | currentText: 'Nu',
14 | closeText: 'Stäng',
15 | timeFormat: 'HH:mm',
16 | timeSuffix: '',
17 | amNames: ['AM', 'A'],
18 | pmNames: ['PM', 'P'],
19 | isRTL: false
20 | };
21 | $.timepicker.setDefaults($.timepicker.regional['sv']);
22 | })(jQuery);
23 |
--------------------------------------------------------------------------------
/WebContent/js/i18n/jquery-ui-timepicker-th.js:
--------------------------------------------------------------------------------
1 | /* Thai translation for the jQuery Timepicker Addon */
2 | /* Written by Yote Wachirapornpongsa */
3 | (function($) {
4 | $.timepicker.regional['th'] = {
5 | timeOnlyTitle: 'เลือกเวลา',
6 | timeText: 'เวลา ',
7 | hourText: 'ชั่วโมง ',
8 | minuteText: 'นาที',
9 | secondText: 'วินาที',
10 | millisecText: 'มิลลิวินาที',
11 | microsecText: 'ไมโคริวินาที',
12 | timezoneText: 'เขตเวลา',
13 | currentText: 'เวลาปัจจุบัน',
14 | closeText: 'ปิด',
15 | timeFormat: 'hh:mm tt',
16 | timeSuffix: ''
17 | };
18 | $.timepicker.setDefaults($.timepicker.regional['th']);
19 | })(jQuery);
--------------------------------------------------------------------------------
/WebContent/js/i18n/jquery-ui-timepicker-tr.js:
--------------------------------------------------------------------------------
1 | /* Turkish translation for the jQuery Timepicker Addon */
2 | /* Written by Fehmi Can Saglam, Edited by Goktug Ozturk */
3 | (function($) {
4 | $.timepicker.regional['tr'] = {
5 | timeOnlyTitle: 'Zaman Seçiniz',
6 | timeText: 'Zaman',
7 | hourText: 'Saat',
8 | minuteText: 'Dakika',
9 | secondText: 'Saniye',
10 | millisecText: 'Milisaniye',
11 | microsecText: 'Mikrosaniye',
12 | timezoneText: 'Zaman Dilimi',
13 | currentText: 'Şu an',
14 | closeText: 'Tamam',
15 | timeFormat: 'HH:mm',
16 | timeSuffix: '',
17 | amNames: ['ÖÖ', 'Ö'],
18 | pmNames: ['ÖS', 'S'],
19 | isRTL: false
20 | };
21 | $.timepicker.setDefaults($.timepicker.regional['tr']);
22 | })(jQuery);
23 |
--------------------------------------------------------------------------------
/WebContent/js/i18n/jquery-ui-timepicker-uk.js:
--------------------------------------------------------------------------------
1 | /* Ukrainian translation for the jQuery Timepicker Addon */
2 | /* Written by Sergey Noskov */
3 | (function($) {
4 | $.timepicker.regional['uk'] = {
5 | timeOnlyTitle: 'Виберіть час',
6 | timeText: 'Час',
7 | hourText: 'Години',
8 | minuteText: 'Хвилини',
9 | secondText: 'Секунди',
10 | millisecText: 'Мілісекунди',
11 | microsecText: 'Мікросекунди',
12 | timezoneText: 'Часовий пояс',
13 | currentText: 'Зараз',
14 | closeText: 'Закрити',
15 | timeFormat: 'HH:mm',
16 | timeSuffix: '',
17 | amNames: ['AM', 'A'],
18 | pmNames: ['PM', 'P'],
19 | isRTL: false
20 | };
21 | $.timepicker.setDefaults($.timepicker.regional['uk']);
22 | })(jQuery);
23 |
--------------------------------------------------------------------------------
/WebContent/js/i18n/jquery-ui-timepicker-vi.js:
--------------------------------------------------------------------------------
1 | /* Vietnamese translation for the jQuery Timepicker Addon */
2 | /* Written by Nguyen Dinh Trung */
3 | (function($) {
4 | $.timepicker.regional['vi'] = {
5 | timeOnlyTitle: 'Chọn giờ',
6 | timeText: 'Thời gian',
7 | hourText: 'Giờ',
8 | minuteText: 'Phút',
9 | secondText: 'Giây',
10 | millisecText: 'Mili giây',
11 | microsecText: 'Micrô giây',
12 | timezoneText: 'Múi giờ',
13 | currentText: 'Hiện thời',
14 | closeText: 'Đóng',
15 | timeFormat: 'HH:mm',
16 | timeSuffix: '',
17 | amNames: ['SA', 'S'],
18 | pmNames: ['CH', 'C'],
19 | isRTL: false
20 | };
21 | $.timepicker.setDefaults($.timepicker.regional['vi']);
22 | })(jQuery);
23 |
--------------------------------------------------------------------------------
/WebContent/js/i18n/jquery-ui-timepicker-zh-CN.js:
--------------------------------------------------------------------------------
1 | /* Simplified Chinese translation for the jQuery Timepicker Addon /
2 | / Written by Will Lu */
3 | (function($) {
4 | $.timepicker.regional['zh-CN'] = {
5 | timeOnlyTitle: '选择时间',
6 | timeText: '时间',
7 | hourText: '小时',
8 | minuteText: '分钟',
9 | secondText: '秒钟',
10 | millisecText: '毫秒',
11 | microsecText: '微秒',
12 | timezoneText: '时区',
13 | currentText: '现在时间',
14 | closeText: '关闭',
15 | timeFormat: 'HH:mm',
16 | timeSuffix: '',
17 | amNames: ['AM', 'A'],
18 | pmNames: ['PM', 'P'],
19 | isRTL: false
20 | };
21 | $.timepicker.setDefaults($.timepicker.regional['zh-CN']);
22 | })(jQuery);
23 |
--------------------------------------------------------------------------------
/WebContent/js/i18n/jquery-ui-timepicker-zh-TW.js:
--------------------------------------------------------------------------------
1 | /* Chinese translation for the jQuery Timepicker Addon */
2 | /* Written by Alang.lin */
3 | (function($) {
4 | $.timepicker.regional['zh-TW'] = {
5 | timeOnlyTitle: '選擇時分秒',
6 | timeText: '時間',
7 | hourText: '時',
8 | minuteText: '分',
9 | secondText: '秒',
10 | millisecText: '毫秒',
11 | microsecText: '微秒',
12 | timezoneText: '時區',
13 | currentText: '現在時間',
14 | closeText: '確定',
15 | timeFormat: 'HH:mm',
16 | timeSuffix: '',
17 | amNames: ['上午', 'AM', 'A'],
18 | pmNames: ['下午', 'PM', 'P'],
19 | isRTL: false
20 | };
21 | $.timepicker.setDefaults($.timepicker.regional['zh-TW']);
22 | })(jQuery);
23 |
--------------------------------------------------------------------------------
/WebContent/js/images/layers-2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cicerolp/hashedcubes/ff15e60f4449762c8282b66387dcb7bab836bf77/WebContent/js/images/layers-2x.png
--------------------------------------------------------------------------------
/WebContent/js/images/layers.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cicerolp/hashedcubes/ff15e60f4449762c8282b66387dcb7bab836bf77/WebContent/js/images/layers.png
--------------------------------------------------------------------------------
/WebContent/js/images/marker-icon-2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cicerolp/hashedcubes/ff15e60f4449762c8282b66387dcb7bab836bf77/WebContent/js/images/marker-icon-2x.png
--------------------------------------------------------------------------------
/WebContent/js/images/marker-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cicerolp/hashedcubes/ff15e60f4449762c8282b66387dcb7bab836bf77/WebContent/js/images/marker-icon.png
--------------------------------------------------------------------------------
/WebContent/js/images/marker-shadow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cicerolp/hashedcubes/ff15e60f4449762c8282b66387dcb7bab836bf77/WebContent/js/images/marker-shadow.png
--------------------------------------------------------------------------------
/WebContent/js/jquery-ui-sliderAccess.js:
--------------------------------------------------------------------------------
1 | /*
2 | * jQuery UI Slider Access
3 | * By: Trent Richardson [http://trentrichardson.com]
4 | * Version 0.3
5 | * Last Modified: 10/20/2012
6 | *
7 | * Copyright 2011 Trent Richardson
8 | * Dual licensed under the MIT and GPL licenses.
9 | * http://trentrichardson.com/Impromptu/GPL-LICENSE.txt
10 | * http://trentrichardson.com/Impromptu/MIT-LICENSE.txt
11 | *
12 | */
13 | (function($){
14 |
15 | $.fn.extend({
16 | sliderAccess: function(options){
17 | options = options || {};
18 | options.touchonly = options.touchonly !== undefined? options.touchonly : true; // by default only show it if touch device
19 |
20 | if(options.touchonly === true && !("ontouchend" in document)){
21 | return $(this);
22 | }
23 |
24 | return $(this).each(function(i,obj){
25 | var $t = $(this),
26 | o = $.extend({},{
27 | where: 'after',
28 | step: $t.slider('option','step'),
29 | upIcon: 'ui-icon-plus',
30 | downIcon: 'ui-icon-minus',
31 | text: false,
32 | upText: '+',
33 | downText: '-',
34 | buttonset: true,
35 | buttonsetTag: 'span',
36 | isRTL: false
37 | }, options),
38 | $buttons = $('<'+ o.buttonsetTag +' class="ui-slider-access">'+
39 | ''+
40 | ''+
41 | ''+ o.buttonsetTag +'>');
42 |
43 | $buttons.children('button').each(function(j, jobj){
44 | var $jt = $(this);
45 | $jt.button({
46 | text: o.text,
47 | icons: { primary: $jt.data('icon') }
48 | })
49 | .click(function(e){
50 | var step = $jt.data('step'),
51 | curr = $t.slider('value'),
52 | newval = curr += step*1,
53 | minval = $t.slider('option','min'),
54 | maxval = $t.slider('option','max'),
55 | slidee = $t.slider("option", "slide") || function(){},
56 | stope = $t.slider("option", "stop") || function(){};
57 |
58 | e.preventDefault();
59 |
60 | if(newval < minval || newval > maxval){
61 | return;
62 | }
63 |
64 | $t.slider('value', newval);
65 |
66 | slidee.call($t, null, { value: newval });
67 | stope.call($t, null, { value: newval });
68 | });
69 | });
70 |
71 | // before or after
72 | $t[o.where]($buttons);
73 |
74 | if(o.buttonset){
75 | $buttons.removeClass('ui-corner-right').removeClass('ui-corner-left').buttonset();
76 | $buttons.eq(0).addClass('ui-corner-left');
77 | $buttons.eq(1).addClass('ui-corner-right');
78 | }
79 |
80 | // adjust the width so we don't break the original layout
81 | var bOuterWidth = $buttons.css({
82 | marginLeft: ((o.where === 'after' && !o.isRTL) || (o.where === 'before' && o.isRTL)? 10:0),
83 | marginRight: ((o.where === 'before' && !o.isRTL) || (o.where === 'after' && o.isRTL)? 10:0)
84 | }).outerWidth(true) + 5;
85 | var tOuterWidth = $t.outerWidth(true);
86 | $t.css('display','inline-block').width(tOuterWidth-bOuterWidth);
87 | });
88 | }
89 | });
90 |
91 | })(jQuery);
--------------------------------------------------------------------------------
/WebContent/js/scatterchart.js:
--------------------------------------------------------------------------------
1 | function setSctterChart(data, entry) {
2 |
3 | var margin = {
4 | top : 0,
5 | right : 15,
6 | bottom : 23,
7 | left : 25
8 | };
9 |
10 | var div = d3.select("#" + entry.field.name);
11 |
12 | var width = div.node().getBoundingClientRect().width;
13 | var height = div.node().getBoundingClientRect().height - 32;
14 |
15 | var scatter_width = width - margin.left -margin.right;
16 | var scatter_height = height - margin.top - margin.bottom;
17 |
18 | var max = d3.max(data, function(d) { return d[2]; });
19 |
20 | var x = d3.scale.linear()
21 | .domain([0, 23])
22 | .range([ 0, scatter_width - (scatter_width / 24)]);
23 |
24 | var y = d3.scale.linear()
25 | .domain([0, 6])
26 | .range([ scatter_height - (scatter_height / 7), 0 ]);
27 |
28 | div.selectAll("*").remove();
29 |
30 | var tip = d3.tip()
31 | .attr('class', 'd3-tip')
32 | .offset([-10, 0])
33 | .html(function(d) {
34 | return "Day: " + d[1] + "" +
35 | "Hour: " + d[0] + "" +
36 | "Value: " + d[2] + "";
37 | });
38 |
39 | var main = div
40 | .append("svg")
41 | .attr("width", width)
42 | .attr('height', height)
43 | .attr("class", "chart");
44 |
45 | var chart = main.append("g")
46 | .attr("transform", "translate(" + (margin.left)+ "," + (margin.top) + ")")
47 | .attr("width", scatter_width)
48 | .attr("height", scatter_height)
49 | .attr("class", "main")
50 | .call(tip);
51 |
52 | // draw the x axis
53 | var xAxis = d3.svg.axis()
54 | .scale(x)
55 | .ticks(24)
56 | .orient('bottom');
57 |
58 | main.append('svg:g')
59 | .attr('transform', 'translate(' + (margin.left + (scatter_width / 48)) + ',' + (height - margin.bottom) + ')')
60 | .attr('class', 'main axis a')
61 | .call(xAxis).attr("font-family", "sans-serif").attr("font-size", "11px").attr("fill", "white").attr("text-anchor", "middle");;
62 |
63 | // draw the y axis
64 | var yAxis = d3.svg.axis()
65 | .scale(y)
66 | .ticks(7)
67 | .orient('left');
68 |
69 | main.append('svg:g')
70 | .attr('transform', 'translate(' + (margin.left) + ',' + (margin.top + (scatter_height / 14)) + ')')
71 | .attr('class', 'main axis b')
72 | .call(yAxis).attr("font-family", "sans-serif").attr("font-size", "11px").attr("fill", "white").attr("text-anchor", "middle");;
73 |
74 | var color = d3.scale.linear()
75 | .domain([0.3, 1])
76 | .range(["black", "steelblue"]);
77 |
78 | chart.selectAll("scatter-dots")
79 | .data(data)
80 | .enter().append("rect")
81 | .attr("x", function(d) { return d[0] * (scatter_width / 24); })
82 | .attr("y", function(d) { return (6 - d[1]) * (scatter_height / 7); })
83 | .attr("width", (scatter_width / 24) + .5)
84 | .attr("height", (scatter_height / 7) + .5)
85 | .attr("fill", function(d) { return color((d[2] / max)); })
86 | .on('mouseover', tip.show)
87 | .on('mouseout', tip.hide);
88 | }
--------------------------------------------------------------------------------
/WebContent/js/sql.js:
--------------------------------------------------------------------------------
1 | function loadMySQLPanel(data, entry) {
2 |
3 | var div = d3.select("#right-section");
4 | div.selectAll("*").remove();
5 |
6 | $("#right-section").append($(''));
7 | $("#right-section").append($(''));
8 |
9 | var names = [];
10 | var model = [];
11 | entry.field.values.forEach(function (value) {
12 | names.push(value.label);
13 | model.push({ align: value.align, width: value.width, /*label: value.label,*/ name: value.name, formatter: value.formatter });
14 | });
15 |
16 | $("#jqGrid").jqGrid({
17 | datatype: "clientSide",
18 | data: data,
19 | colNames: names,
20 | colModel: model,
21 | caption: entry.title,
22 | pager: "#jqGridPager",
23 | rowNum: 100,
24 | viewrecords: true,
25 | loadonce: true,
26 | width: div.node().getBoundingClientRect().width,
27 | height: div.node().getBoundingClientRect().height - 84,
28 | });
29 |
30 |
31 |
32 | $("#jqGrid").jqGrid('navGrid', '#jqGridPager', {
33 | add: false,
34 | del: false,
35 | edit: false,
36 | refresh: false,
37 | search: true,
38 | view: true,
39 | position: "left"
40 | });
41 | }
--------------------------------------------------------------------------------
/csv.7z:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cicerolp/hashedcubes/ff15e60f4449762c8282b66387dcb7bab836bf77/csv.7z
--------------------------------------------------------------------------------
/data.7z:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cicerolp/hashedcubes/ff15e60f4449762c8282b66387dcb7bab836bf77/data.7z
--------------------------------------------------------------------------------
/include/SQLiteCpp/Assertion.h:
--------------------------------------------------------------------------------
1 | /**
2 | * @file Assertion.h
3 | * @ingroup SQLiteCpp
4 | * @brief Definition of the SQLITECPP_ASSERT() macro.
5 | *
6 | * Copyright (c) 2012-2013 Sebastien Rombauts (sebastien.rombauts@gmail.com)
7 | *
8 | * Distributed under the MIT License (MIT) (See accompanying file LICENSE.txt
9 | * or copy at http://opensource.org/licenses/MIT)
10 | */
11 | #pragma once
12 |
13 | #include
14 |
15 |
16 | /**
17 | * SQLITECPP_ASSERT SQLITECPP_ASSERT() is used in destructors, where exceptions shall not be thrown
18 | *
19 | * Define SQLITECPP_ENABLE_ASSERT_HANDLER at the project level
20 | * and define a SQLite::assertion_failed() assertion handler
21 | * to tell SQLiteC++ to use it instead of assert() when an assertion fail.
22 | */
23 | #ifdef SQLITECPP_ENABLE_ASSERT_HANDLER
24 |
25 | // if an assert handler is provided by user code, use it instead of assert()
26 | namespace SQLite
27 | {
28 | // declaration of the assert handler to define in user code
29 | void assertion_failed(const char* apFile, const long apLine, const char* apFunc,
30 | const char* apExpr, const char* apMsg);
31 |
32 | #ifdef _MSC_VER
33 | #define __func__ __FUNCTION__
34 | #endif
35 | // call the assert handler provided by user code
36 | #define SQLITECPP_ASSERT(expression, message) \
37 | if (!(expression)) SQLite::assertion_failed(__FILE__, __LINE__, __func__, #expression, message)
38 | } // namespace SQLite
39 |
40 | #else
41 |
42 | // if no assert handler provided by user code, use standard assert()
43 | // (note: in release mode assert() does nothing)
44 | #define SQLITECPP_ASSERT(expression, message) assert(expression && message)
45 |
46 | #endif
47 |
--------------------------------------------------------------------------------
/include/SQLiteCpp/Backup.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * @file Backup.cpp
3 | * @ingroup SQLiteCpp
4 | * @brief Backup is used to backup a database file in a safe and online way.
5 | *
6 | * Copyright (c) 2015-2015 Shibao HONG (shibaohong@outlook.com)
7 | *
8 | * Distributed under the MIT License (MIT) (See accompanying file LICENSE.txt
9 | * or copy at http://opensource.org/licenses/MIT)
10 | */
11 |
12 | #include
13 |
14 | #include
15 |
16 | #include
17 |
18 | namespace SQLite
19 | {
20 |
21 | // Initialize resource for SQLite database backup
22 | Backup::Backup(Database& aDestDatabase,
23 | const char *apDestDatabaseName,
24 | Database& aSrcDatabase,
25 | const char *apSrcDatabaseName) :
26 | mpSQLiteBackup(NULL)
27 | {
28 | mpSQLiteBackup = sqlite3_backup_init(aDestDatabase.getHandle(),
29 | apDestDatabaseName,
30 | aSrcDatabase.getHandle(),
31 | apSrcDatabaseName);
32 | if (NULL == mpSQLiteBackup)
33 | {
34 | std::string strerr = sqlite3_errmsg(aDestDatabase.getHandle());
35 | throw SQLite::Exception(strerr);
36 | }
37 | }
38 |
39 | // Initialize resource for SQLite database backup
40 | Backup::Backup(Database &aDestDatabase,
41 | const std::string &aDestDatabaseName,
42 | Database &aSrcDatabase,
43 | const std::string &aSrcDatabaseName) :
44 | mpSQLiteBackup(NULL)
45 | {
46 | mpSQLiteBackup = sqlite3_backup_init(aDestDatabase.getHandle(),
47 | aDestDatabaseName.c_str(),
48 | aSrcDatabase.getHandle(),
49 | aSrcDatabaseName.c_str());
50 | if (NULL == mpSQLiteBackup)
51 | {
52 | std::string strerr = sqlite3_errmsg(aDestDatabase.getHandle());
53 | throw SQLite::Exception(strerr);
54 | }
55 | }
56 |
57 | // Initialize resource for SQLite database backup
58 | Backup::Backup(Database &aDestDatabase, Database &aSrcDatabase) :
59 | mpSQLiteBackup(NULL)
60 | {
61 | mpSQLiteBackup = sqlite3_backup_init(aDestDatabase.getHandle(),
62 | "main",
63 | aSrcDatabase.getHandle(),
64 | "main");
65 | if (NULL == mpSQLiteBackup)
66 | {
67 | std::string strerr = sqlite3_errmsg(aDestDatabase.getHandle());
68 | throw SQLite::Exception(strerr);
69 | }
70 | }
71 |
72 | // Release resource for SQLite database backup
73 | Backup::~Backup() noexcept
74 | {
75 | if (NULL != mpSQLiteBackup)
76 | {
77 | sqlite3_backup_finish(mpSQLiteBackup);
78 | }
79 | }
80 |
81 | // Execute backup step with a given number of source pages to be copied
82 | int Backup::executeStep(const int aNumPage /* = -1 */)
83 | {
84 | const int res = sqlite3_backup_step(mpSQLiteBackup, aNumPage);
85 | if (SQLITE_OK != res && SQLITE_DONE != res &&
86 | SQLITE_BUSY != res && SQLITE_LOCKED != res)
87 | {
88 | std::string strerr = sqlite3_errstr(res);
89 | throw SQLite::Exception(strerr);
90 | }
91 | return res;
92 | }
93 |
94 | // Get the number of remaining source pages to be copied in this backup process
95 | int Backup::remainingPageCount()
96 | {
97 | return sqlite3_backup_remaining(mpSQLiteBackup);
98 | }
99 |
100 | // Get the number of total source pages to be copied in this backup process
101 | int Backup::totalPageCount()
102 | {
103 | return sqlite3_backup_pagecount(mpSQLiteBackup);
104 | }
105 |
106 | } // namespace SQLite
107 |
--------------------------------------------------------------------------------
/include/SQLiteCpp/Column.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * @file Column.cpp
3 | * @ingroup SQLiteCpp
4 | * @brief Encapsulation of a Column in a row of the result pointed by the prepared SQLite::Statement.
5 | *
6 | * Copyright (c) 2012-2016 Sebastien Rombauts (sebastien.rombauts@gmail.com)
7 | *
8 | * Distributed under the MIT License (MIT) (See accompanying file LICENSE.txt
9 | * or copy at http://opensource.org/licenses/MIT)
10 | */
11 | #include
12 |
13 | #include
14 |
15 |
16 | namespace SQLite
17 | {
18 |
19 |
20 | // Encapsulation of a Column in a row of the result pointed by the prepared Statement.
21 | Column::Column(Statement::Ptr& aStmtPtr, int aIndex) noexcept : // nothrow
22 | mStmtPtr(aStmtPtr),
23 | mIndex(aIndex)
24 | {
25 | }
26 |
27 | // Finalize and unregister the SQL query from the SQLite Database Connection.
28 | Column::~Column() noexcept // nothrow
29 | {
30 | // the finalization will be done by the destructor of the last shared pointer
31 | }
32 |
33 | // Return the named assigned to this result column (potentially aliased)
34 | const char* Column::getName() const noexcept // nothrow
35 | {
36 | return sqlite3_column_name(mStmtPtr, mIndex);
37 | }
38 |
39 | #ifdef SQLITE_ENABLE_COLUMN_METADATA
40 | // Return the name of the table column that is the origin of this result column
41 | const char* Column::getOriginName() const noexcept // nothrow
42 | {
43 | return sqlite3_column_origin_name(mStmtPtr, mIndex);
44 | }
45 | #endif
46 |
47 | // Return the integer value of the column specified by its index starting at 0
48 | int Column::getInt() const noexcept // nothrow
49 | {
50 | return sqlite3_column_int(mStmtPtr, mIndex);
51 | }
52 |
53 | // Return the 64bits integer value of the column specified by its index starting at 0
54 | sqlite3_int64 Column::getInt64() const noexcept // nothrow
55 | {
56 | return sqlite3_column_int64(mStmtPtr, mIndex);
57 | }
58 |
59 | // Return the double value of the column specified by its index starting at 0
60 | double Column::getDouble() const noexcept // nothrow
61 | {
62 | return sqlite3_column_double(mStmtPtr, mIndex);
63 | }
64 |
65 | // Return a pointer to the text value (NULL terminated string) of the column specified by its index starting at 0
66 | const char* Column::getText(const char* apDefaultValue /* = "" */) const noexcept // nothrow
67 | {
68 | const char* pText = reinterpret_cast(sqlite3_column_text(mStmtPtr, mIndex));
69 | return (pText?pText:apDefaultValue);
70 | }
71 |
72 | // Return a pointer to the text value (NULL terminated string) of the column specified by its index starting at 0
73 | const void* Column::getBlob() const noexcept // nothrow
74 | {
75 | return sqlite3_column_blob(mStmtPtr, mIndex);
76 | }
77 |
78 | // Return the type of the value of the column
79 | int Column::getType() const noexcept // nothrow
80 | {
81 | return sqlite3_column_type(mStmtPtr, mIndex);
82 | }
83 |
84 | // Return the number of bytes used by the text value of the column
85 | int Column::getBytes() const noexcept // nothrow
86 | {
87 | return sqlite3_column_bytes(mStmtPtr, mIndex);
88 | }
89 |
90 | // Standard std::ostream inserter
91 | std::ostream& operator<<(std::ostream& aStream, const Column& aColumn)
92 | {
93 | aStream << aColumn.getText();
94 | return aStream;
95 | }
96 |
97 |
98 | } // namespace SQLite
99 |
--------------------------------------------------------------------------------
/include/SQLiteCpp/Exception.h:
--------------------------------------------------------------------------------
1 | /**
2 | * @file Exception.h
3 | * @ingroup SQLiteCpp
4 | * @brief Encapsulation of the error message from SQLite3 on a std::runtime_error.
5 | *
6 | * Copyright (c) 2012-2013 Sebastien Rombauts (sebastien.rombauts@gmail.com)
7 | *
8 | * Distributed under the MIT License (MIT) (See accompanying file LICENSE.txt
9 | * or copy at http://opensource.org/licenses/MIT)
10 | */
11 | #pragma once
12 |
13 | #include
14 | #include
15 |
16 |
17 | namespace SQLite
18 | {
19 |
20 |
21 | /**
22 | * @brief Encapsulation of the error message from SQLite3, based on std::runtime_error.
23 | */
24 | class Exception : public std::runtime_error
25 | {
26 | public:
27 | /**
28 | * @brief Encapsulation of the error message from SQLite3, based on std::runtime_error.
29 | *
30 | * @param[in] aErrorMessage The string message describing the SQLite error
31 | */
32 | explicit Exception(const std::string& aErrorMessage) :
33 | std::runtime_error(aErrorMessage)
34 | {
35 | }
36 | };
37 |
38 |
39 | } // namespace SQLite
40 |
41 |
42 | /// Compatibility with non-clang compilers.
43 | #ifndef __has_feature
44 | #define __has_feature(x) 0
45 | #endif
46 |
47 | // Detect whether the compiler supports C++11 noexcept exception specifications.
48 | #if ( defined(__GNUC__) && ((__GNUC__ == 4 && __GNUC_MINOR__ >= 7) || (__GNUC__ > 4)) \
49 | && defined(__GXX_EXPERIMENTAL_CXX0X__))
50 | // GCC 4.7 and following have noexcept
51 | #elif defined(__clang__) && __has_feature(cxx_noexcept)
52 | // Clang 3.0 and above have noexcept
53 | #elif defined(_MSC_VER) && _MSC_VER > 1800
54 | // Visual Studio 2015 and above have noexcept
55 | #else
56 | // Visual Studio 2013 does not support noexcept, and "throw()" is deprecated by C++11
57 | #define noexcept
58 | #endif
59 |
--------------------------------------------------------------------------------
/include/SQLiteCpp/SQLiteCpp.h:
--------------------------------------------------------------------------------
1 | /**
2 | * @file SQLiteCpp.h
3 | * @ingroup SQLiteCpp
4 | * @brief SQLiteC++ is a smart and simple C++ SQLite3 wrapper. This file is only "easy include" for other files.
5 | *
6 | * Include this main header file in your project to gain access to all functionality provided by the wrapper.
7 | *
8 | * Copyright (c) 2012-2016 Sebastien Rombauts (sebastien.rombauts@gmail.com)
9 | *
10 | * Distributed under the MIT License (MIT) (See accompanying file LICENSE.txt
11 | * or copy at http://opensource.org/licenses/MIT)
12 | */
13 | /**
14 | * @defgroup SQLiteCpp SQLiteC++
15 | * @brief SQLiteC++ is a smart and simple C++ SQLite3 wrapper. This file is only "easy include" for other files.
16 | */
17 | #pragma once
18 |
19 |
20 | // Include useful headers of SQLiteC++
21 | #include
22 | #include
23 | #include
24 | #include
25 | #include
26 | #include
27 |
28 |
29 | /**
30 | * @brief Version numbers for SQLiteC++ are provided in the same way as sqlite3.h
31 | *
32 | * The [SQLITECPP_VERSION] C preprocessor macro in the SQLiteC++.h header
33 | * evaluates to a string literal that is the SQLite version in the
34 | * format "X.Y.Z" where X is the major version number
35 | * and Y is the minor version number and Z is the release number.
36 | *
37 | * The [SQLITECPP_VERSION_NUMBER] C preprocessor macro resolves to an integer
38 | * with the value (X*1000000 + Y*1000 + Z) where X, Y, and Z are the same
39 | * numbers used in [SQLITECPP_VERSION].
40 | */
41 | #define SQLITECPP_VERSION "1.3.1"
42 | #define SQLITECPP_VERSION_NUMBER 1003001
43 |
--------------------------------------------------------------------------------
/include/SQLiteCpp/Transaction.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * @file Transaction.cpp
3 | * @ingroup SQLiteCpp
4 | * @brief A Transaction is way to group multiple SQL statements into an atomic secured operation.
5 | *
6 | * Copyright (c) 2012-2013 Sebastien Rombauts (sebastien.rombauts@gmail.com)
7 | *
8 | * Distributed under the MIT License (MIT) (See accompanying file LICENSE.txt
9 | * or copy at http://opensource.org/licenses/MIT)
10 | */
11 | #include
12 |
13 | #include
14 | #include
15 |
16 |
17 | namespace SQLite
18 | {
19 |
20 |
21 | // Begins the SQLite transaction
22 | Transaction::Transaction(Database& aDatabase) :
23 | mDatabase(aDatabase),
24 | mbCommited(false)
25 | {
26 | mDatabase.exec("BEGIN");
27 | }
28 |
29 | // Safely rollback the transaction if it has not been committed.
30 | Transaction::~Transaction() noexcept // nothrow
31 | {
32 | if (false == mbCommited)
33 | {
34 | try
35 | {
36 | mDatabase.exec("ROLLBACK");
37 | }
38 | catch (SQLite::Exception& e)
39 | {
40 | // Never throw an exception in a destructor
41 | (void)e; // warning proof
42 | SQLITECPP_ASSERT(false, e.what()); // See SQLITECPP_ENABLE_ASSERT_HANDLER
43 | }
44 | }
45 | }
46 |
47 | // Commit the transaction.
48 | void Transaction::commit()
49 | {
50 | if (false == mbCommited)
51 | {
52 | mDatabase.exec("COMMIT");
53 | mbCommited = true;
54 | }
55 | else
56 | {
57 | throw SQLite::Exception("Transaction already commited.");
58 | }
59 | }
60 |
61 |
62 | } // namespace SQLite
63 |
--------------------------------------------------------------------------------
/include/SQLiteCpp/Transaction.h:
--------------------------------------------------------------------------------
1 | /**
2 | * @file Transaction.h
3 | * @ingroup SQLiteCpp
4 | * @brief A Transaction is way to group multiple SQL statements into an atomic secured operation.
5 | *
6 | * Copyright (c) 2012-2013 Sebastien Rombauts (sebastien.rombauts@gmail.com)
7 | *
8 | * Distributed under the MIT License (MIT) (See accompanying file LICENSE.txt
9 | * or copy at http://opensource.org/licenses/MIT)
10 | */
11 | #pragma once
12 |
13 | #include
14 |
15 |
16 | namespace SQLite
17 | {
18 |
19 |
20 | // Forward declaration
21 | class Database;
22 |
23 | /**
24 | * @brief RAII encapsulation of a SQLite Transaction.
25 | *
26 | * A Transaction is a way to group multiple SQL statements into an atomic secured operation;
27 | * either it succeeds, with all the changes committed to the database file,
28 | * or if it fails, all the changes are rolled back to the initial state.
29 | *
30 | * Resource Acquisition Is Initialization (RAII) means that the Transaction
31 | * begins in the constructor and is rollbacked in the destructor, so that there is
32 | * no need to worry about memory management or the validity of the underlying SQLite Connection.
33 | *
34 | * This method also offers big performances improvements compared to individually executed statements.
35 | *
36 | * Thread-safety: a Transaction object shall not be shared by multiple threads, because :
37 | * 1) in the SQLite "Thread Safe" mode, "SQLite can be safely used by multiple threads
38 | * provided that no single database connection is used simultaneously in two or more threads."
39 | * 2) the SQLite "Serialized" mode is not supported by SQLiteC++,
40 | * because of the way it shares the underling SQLite precompiled statement
41 | * in a custom shared pointer (See the inner class "Statement::Ptr").
42 | */
43 | class Transaction
44 | {
45 | public:
46 | /**
47 | * @brief Begins the SQLite transaction
48 | *
49 | * @param[in] aDatabase the SQLite Database Connection
50 | *
51 | * Exception is thrown in case of error, then the Transaction is NOT initiated.
52 | */
53 | explicit Transaction(Database& aDatabase);
54 |
55 | /**
56 | * @brief Safely rollback the transaction if it has not been committed.
57 | */
58 | virtual ~Transaction() noexcept; // nothrow
59 |
60 | /**
61 | * @brief Commit the transaction.
62 | */
63 | void commit();
64 |
65 | private:
66 | // Transaction must be non-copyable
67 | Transaction(const Transaction&);
68 | Transaction& operator=(const Transaction&);
69 | /// @}
70 |
71 | private:
72 | Database& mDatabase; //!< Reference to the SQLite Database Connection
73 | bool mbCommited; //!< True when commit has been called
74 | };
75 |
76 |
77 | } // namespace SQLite
78 |
--------------------------------------------------------------------------------
/include/boost/serialization/tuple.hpp:
--------------------------------------------------------------------------------
1 | #ifndef BOOST_SERIALIZATION_TUPLE_HPP
2 | #define BOOST_SERIALIZATION_TUPLE_HPP
3 |
4 | // MS compatible compilers support #pragma once
5 | #if defined(_MSC_VER)
6 | # pragma once
7 | #endif
8 |
9 | /*
10 | Copyright 2011 Christopher Allen Ogden. All rights reserved.
11 |
12 | Redistribution and use in source and binary forms, with or without modification, are
13 | permitted provided that the following conditions are met:
14 |
15 | 1. Redistributions of source code must retain the above copyright notice, this list of
16 | conditions and the following disclaimer.
17 |
18 | 2. Redistributions in binary form must reproduce the above copyright notice, this list
19 | of conditions and the following disclaimer in the documentation and/or other materials
20 | provided with the distribution.
21 |
22 | THIS SOFTWARE IS PROVIDED BY CHRISTOPHER ALLEN OGDEN ``AS IS'' AND ANY EXPRESS OR IMPLIED
23 | WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
24 | FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL CHRISTOPHER ALLEN OGDEN OR
25 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
28 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
30 | ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 |
32 | The views and conclusions contained in the software and documentation are those of the
33 | authors and should not be interpreted as representing official policies, either expressed
34 | or implied, of Christopher Allen Ogden.
35 | */
36 |
37 | #include
38 |
39 | namespace boost {
40 | namespace serialization {
41 |
42 | template
43 | struct Serialize
44 | {
45 | template
46 | static void serialize(Archive & ar, std::tuple & t, const unsigned int version)
47 | {
48 | ar & std::get(t);
49 | Serialize::serialize(ar, t, version);
50 | }
51 | };
52 |
53 | template<>
54 | struct Serialize<0>
55 | {
56 | template
57 | static void serialize(Archive & ar, std::tuple & t, const unsigned int version)
58 | {
59 | }
60 | };
61 |
62 | template
63 | void serialize(Archive & ar, std::tuple & t, const unsigned int version)
64 | {
65 | Serialize::serialize(ar, t, version);
66 | }
67 |
68 | } // namespace serialization
69 | } // namespace boost
70 |
71 | #endif //BOOST_SERIALIZATION_TUPLE_HPP
--------------------------------------------------------------------------------
/include/meerkat/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2014 Cesanta Software Limited
2 | All rights reserved
3 |
4 | This code is dual-licensed: you can redistribute it and/or modify
5 | it under the terms of the GNU General Public License version 2 as
6 | published by the Free Software Foundation. For the terms of this
7 | license, see .
8 |
9 | You are free to use this code under the terms of the GNU General
10 | Public License, but WITHOUT ANY WARRANTY; without even the implied
11 | warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12 | See the GNU General Public License for more details.
13 |
14 | Alternatively, you can license this code under a commercial
15 | license, as set out in .
16 |
--------------------------------------------------------------------------------
/include/rapidjson/error/en.h:
--------------------------------------------------------------------------------
1 | // Tencent is pleased to support the open source community by making RapidJSON available.
2 | //
3 | // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
4 | //
5 | // Licensed under the MIT License (the "License"); you may not use this file except
6 | // in compliance with the License. You may obtain a copy of the License at
7 | //
8 | // http://opensource.org/licenses/MIT
9 | //
10 | // Unless required by applicable law or agreed to in writing, software distributed
11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the
13 | // specific language governing permissions and limitations under the License.
14 |
15 | #ifndef RAPIDJSON_ERROR_EN_H__
16 | #define RAPIDJSON_ERROR_EN_H__
17 |
18 | #include "error.h"
19 |
20 | RAPIDJSON_NAMESPACE_BEGIN
21 |
22 | //! Maps error code of parsing into error message.
23 | /*!
24 | \ingroup RAPIDJSON_ERRORS
25 | \param parseErrorCode Error code obtained in parsing.
26 | \return the error message.
27 | \note User can make a copy of this function for localization.
28 | Using switch-case is safer for future modification of error codes.
29 | */
30 | inline const RAPIDJSON_ERROR_CHARTYPE* GetParseError_En(ParseErrorCode parseErrorCode) {
31 | switch (parseErrorCode) {
32 | case kParseErrorNone: return RAPIDJSON_ERROR_STRING("No error.");
33 |
34 | case kParseErrorDocumentEmpty: return RAPIDJSON_ERROR_STRING("The document is empty.");
35 | case kParseErrorDocumentRootNotSingular: return RAPIDJSON_ERROR_STRING("The document root must not follow by other values.");
36 |
37 | case kParseErrorValueInvalid: return RAPIDJSON_ERROR_STRING("Invalid value.");
38 |
39 | case kParseErrorObjectMissName: return RAPIDJSON_ERROR_STRING("Missing a name for object member.");
40 | case kParseErrorObjectMissColon: return RAPIDJSON_ERROR_STRING("Missing a colon after a name of object member.");
41 | case kParseErrorObjectMissCommaOrCurlyBracket: return RAPIDJSON_ERROR_STRING("Missing a comma or '}' after an object member.");
42 |
43 | case kParseErrorArrayMissCommaOrSquareBracket: return RAPIDJSON_ERROR_STRING("Missing a comma or ']' after an array element.");
44 |
45 | case kParseErrorStringUnicodeEscapeInvalidHex: return RAPIDJSON_ERROR_STRING("Incorrect hex digit after \\u escape in string.");
46 | case kParseErrorStringUnicodeSurrogateInvalid: return RAPIDJSON_ERROR_STRING("The surrogate pair in string is invalid.");
47 | case kParseErrorStringEscapeInvalid: return RAPIDJSON_ERROR_STRING("Invalid escape character in string.");
48 | case kParseErrorStringMissQuotationMark: return RAPIDJSON_ERROR_STRING("Missing a closing quotation mark in string.");
49 | case kParseErrorStringInvalidEncoding: return RAPIDJSON_ERROR_STRING("Invalid encoding in string.");
50 |
51 | case kParseErrorNumberTooBig: return RAPIDJSON_ERROR_STRING("Number too big to be stored in double.");
52 | case kParseErrorNumberMissFraction: return RAPIDJSON_ERROR_STRING("Miss fraction part in number.");
53 | case kParseErrorNumberMissExponent: return RAPIDJSON_ERROR_STRING("Miss exponent in number.");
54 |
55 | case kParseErrorTermination: return RAPIDJSON_ERROR_STRING("Terminate parsing due to Handler error.");
56 | case kParseErrorUnspecificSyntaxError: return RAPIDJSON_ERROR_STRING("Unspecific syntax error.");
57 |
58 | default:
59 | return RAPIDJSON_ERROR_STRING("Unknown error.");
60 | }
61 | }
62 |
63 | RAPIDJSON_NAMESPACE_END
64 |
65 | #endif // RAPIDJSON_ERROR_EN_H__
66 |
--------------------------------------------------------------------------------
/include/rapidjson/filereadstream.h:
--------------------------------------------------------------------------------
1 | // Tencent is pleased to support the open source community by making RapidJSON available.
2 | //
3 | // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
4 | //
5 | // Licensed under the MIT License (the "License"); you may not use this file except
6 | // in compliance with the License. You may obtain a copy of the License at
7 | //
8 | // http://opensource.org/licenses/MIT
9 | //
10 | // Unless required by applicable law or agreed to in writing, software distributed
11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the
13 | // specific language governing permissions and limitations under the License.
14 |
15 | #ifndef RAPIDJSON_FILEREADSTREAM_H_
16 | #define RAPIDJSON_FILEREADSTREAM_H_
17 |
18 | #include "rapidjson.h"
19 | #include
20 |
21 | RAPIDJSON_NAMESPACE_BEGIN
22 |
23 | //! File byte stream for input using fread().
24 | /*!
25 | \note implements Stream concept
26 | */
27 | class FileReadStream {
28 | public:
29 | typedef char Ch; //!< Character type (byte).
30 |
31 | //! Constructor.
32 | /*!
33 | \param fp File pointer opened for read.
34 | \param buffer user-supplied buffer.
35 | \param bufferSize size of buffer in bytes. Must >=4 bytes.
36 | */
37 | FileReadStream(std::FILE* fp, char* buffer, size_t bufferSize) : fp_(fp), buffer_(buffer), bufferSize_(bufferSize), bufferLast_(0), current_(buffer_), readCount_(0), count_(0), eof_(false) {
38 | RAPIDJSON_ASSERT(fp_ != 0);
39 | RAPIDJSON_ASSERT(bufferSize >= 4);
40 | Read();
41 | }
42 |
43 | Ch Peek() const { return *current_; }
44 | Ch Take() { Ch c = *current_; Read(); return c; }
45 | size_t Tell() const { return count_ + static_cast(current_ - buffer_); }
46 |
47 | // Not implemented
48 | void Put(Ch) { RAPIDJSON_ASSERT(false); }
49 | void Flush() { RAPIDJSON_ASSERT(false); }
50 | Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }
51 | size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; }
52 |
53 | // For encoding detection only.
54 | const Ch* Peek4() const {
55 | return (current_ + 4 <= bufferLast_) ? current_ : 0;
56 | }
57 |
58 | private:
59 | void Read() {
60 | if (current_ < bufferLast_)
61 | ++current_;
62 | else if (!eof_) {
63 | count_ += readCount_;
64 | readCount_ = fread(buffer_, 1, bufferSize_, fp_);
65 | bufferLast_ = buffer_ + readCount_ - 1;
66 | current_ = buffer_;
67 |
68 | if (readCount_ < bufferSize_) {
69 | buffer_[readCount_] = '\0';
70 | ++bufferLast_;
71 | eof_ = true;
72 | }
73 | }
74 | }
75 |
76 | std::FILE* fp_;
77 | Ch *buffer_;
78 | size_t bufferSize_;
79 | Ch *bufferLast_;
80 | Ch *current_;
81 | size_t readCount_;
82 | size_t count_; //!< Number of characters read
83 | bool eof_;
84 | };
85 |
86 | RAPIDJSON_NAMESPACE_END
87 |
88 | #endif // RAPIDJSON_FILESTREAM_H_
89 |
--------------------------------------------------------------------------------
/include/rapidjson/filewritestream.h:
--------------------------------------------------------------------------------
1 | // Tencent is pleased to support the open source community by making RapidJSON available.
2 | //
3 | // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
4 | //
5 | // Licensed under the MIT License (the "License"); you may not use this file except
6 | // in compliance with the License. You may obtain a copy of the License at
7 | //
8 | // http://opensource.org/licenses/MIT
9 | //
10 | // Unless required by applicable law or agreed to in writing, software distributed
11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the
13 | // specific language governing permissions and limitations under the License.
14 |
15 | #ifndef RAPIDJSON_FILEWRITESTREAM_H_
16 | #define RAPIDJSON_FILEWRITESTREAM_H_
17 |
18 | #include "rapidjson.h"
19 | #include
20 |
21 | RAPIDJSON_NAMESPACE_BEGIN
22 |
23 | //! Wrapper of C file stream for input using fread().
24 | /*!
25 | \note implements Stream concept
26 | */
27 | class FileWriteStream {
28 | public:
29 | typedef char Ch; //!< Character type. Only support char.
30 |
31 | FileWriteStream(std::FILE* fp, char* buffer, size_t bufferSize) : fp_(fp), buffer_(buffer), bufferEnd_(buffer + bufferSize), current_(buffer_) {
32 | RAPIDJSON_ASSERT(fp_ != 0);
33 | }
34 |
35 | void Put(char c) {
36 | if (current_ >= bufferEnd_)
37 | Flush();
38 |
39 | *current_++ = c;
40 | }
41 |
42 | void PutN(char c, size_t n) {
43 | size_t avail = static_cast(bufferEnd_ - current_);
44 | while (n > avail) {
45 | std::memset(current_, c, avail);
46 | current_ += avail;
47 | Flush();
48 | n -= avail;
49 | avail = static_cast(bufferEnd_ - current_);
50 | }
51 |
52 | if (n > 0) {
53 | std::memset(current_, c, n);
54 | current_ += n;
55 | }
56 | }
57 |
58 | void Flush() {
59 | if (current_ != buffer_) {
60 | fwrite(buffer_, 1, static_cast(current_ - buffer_), fp_);
61 | current_ = buffer_;
62 | }
63 | }
64 |
65 | // Not implemented
66 | char Peek() const { RAPIDJSON_ASSERT(false); return 0; }
67 | char Take() { RAPIDJSON_ASSERT(false); return 0; }
68 | size_t Tell() const { RAPIDJSON_ASSERT(false); return 0; }
69 | char* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }
70 | size_t PutEnd(char*) { RAPIDJSON_ASSERT(false); return 0; }
71 |
72 | private:
73 | // Prohibit copy constructor & assignment operator.
74 | FileWriteStream(const FileWriteStream&);
75 | FileWriteStream& operator=(const FileWriteStream&);
76 |
77 | std::FILE* fp_;
78 | char *buffer_;
79 | char *bufferEnd_;
80 | char *current_;
81 | };
82 |
83 | //! Implement specialized version of PutN() with memset() for better performance.
84 | template<>
85 | inline void PutN(FileWriteStream& stream, char c, size_t n) {
86 | stream.PutN(c, n);
87 | }
88 |
89 | RAPIDJSON_NAMESPACE_END
90 |
91 | #endif // RAPIDJSON_FILESTREAM_H_
92 |
--------------------------------------------------------------------------------
/include/rapidjson/internal/ieee754.h:
--------------------------------------------------------------------------------
1 | // Tencent is pleased to support the open source community by making RapidJSON available.
2 | //
3 | // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
4 | //
5 | // Licensed under the MIT License (the "License"); you may not use this file except
6 | // in compliance with the License. You may obtain a copy of the License at
7 | //
8 | // http://opensource.org/licenses/MIT
9 | //
10 | // Unless required by applicable law or agreed to in writing, software distributed
11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the
13 | // specific language governing permissions and limitations under the License.
14 |
15 | #ifndef RAPIDJSON_IEEE754_
16 | #define RAPIDJSON_IEEE754_
17 |
18 | #include "../rapidjson.h"
19 |
20 | RAPIDJSON_NAMESPACE_BEGIN
21 | namespace internal {
22 |
23 | class Double {
24 | public:
25 | Double() {}
26 | Double(double d) : d_(d) {}
27 | Double(uint64_t u) : u_(u) {}
28 |
29 | double Value() const { return d_; }
30 | uint64_t Uint64Value() const { return u_; }
31 |
32 | double NextPositiveDouble() const {
33 | RAPIDJSON_ASSERT(!Sign());
34 | return Double(u_ + 1).Value();
35 | }
36 |
37 | bool Sign() const { return (u_ & kSignMask) != 0; }
38 | uint64_t Significand() const { return u_ & kSignificandMask; }
39 | int Exponent() const { return static_cast(((u_ & kExponentMask) >> kSignificandSize) - kExponentBias); }
40 |
41 | bool IsNan() const { return (u_ & kExponentMask) == kExponentMask && Significand() != 0; }
42 | bool IsInf() const { return (u_ & kExponentMask) == kExponentMask && Significand() == 0; }
43 | bool IsNormal() const { return (u_ & kExponentMask) != 0 || Significand() == 0; }
44 | bool IsZero() const { return (u_ & (kExponentMask | kSignificandMask)) == 0; }
45 |
46 | uint64_t IntegerSignificand() const { return IsNormal() ? Significand() | kHiddenBit : Significand(); }
47 | int IntegerExponent() const { return (IsNormal() ? Exponent() : kDenormalExponent) - kSignificandSize; }
48 | uint64_t ToBias() const { return (u_ & kSignMask) ? ~u_ + 1 : u_ | kSignMask; }
49 |
50 | static unsigned EffectiveSignificandSize(int order) {
51 | if (order >= -1021)
52 | return 53;
53 | else if (order <= -1074)
54 | return 0;
55 | else
56 | return order + 1074;
57 | }
58 |
59 | private:
60 | static const int kSignificandSize = 52;
61 | static const int kExponentBias = 0x3FF;
62 | static const int kDenormalExponent = 1 - kExponentBias;
63 | static const uint64_t kSignMask = RAPIDJSON_UINT64_C2(0x80000000, 0x00000000);
64 | static const uint64_t kExponentMask = RAPIDJSON_UINT64_C2(0x7FF00000, 0x00000000);
65 | static const uint64_t kSignificandMask = RAPIDJSON_UINT64_C2(0x000FFFFF, 0xFFFFFFFF);
66 | static const uint64_t kHiddenBit = RAPIDJSON_UINT64_C2(0x00100000, 0x00000000);
67 |
68 | union {
69 | double d_;
70 | uint64_t u_;
71 | };
72 | };
73 |
74 | } // namespace internal
75 | RAPIDJSON_NAMESPACE_END
76 |
77 | #endif // RAPIDJSON_IEEE754_
78 |
--------------------------------------------------------------------------------
/include/rapidjson/internal/pow10.h:
--------------------------------------------------------------------------------
1 | // Tencent is pleased to support the open source community by making RapidJSON available.
2 | //
3 | // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
4 | //
5 | // Licensed under the MIT License (the "License"); you may not use this file except
6 | // in compliance with the License. You may obtain a copy of the License at
7 | //
8 | // http://opensource.org/licenses/MIT
9 | //
10 | // Unless required by applicable law or agreed to in writing, software distributed
11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the
13 | // specific language governing permissions and limitations under the License.
14 |
15 | #ifndef RAPIDJSON_POW10_
16 | #define RAPIDJSON_POW10_
17 |
18 | #include "../rapidjson.h"
19 |
20 | RAPIDJSON_NAMESPACE_BEGIN
21 | namespace internal {
22 |
23 | //! Computes integer powers of 10 in double (10.0^n).
24 | /*! This function uses lookup table for fast and accurate results.
25 | \param n non-negative exponent. Must <= 308.
26 | \return 10.0^n
27 | */
28 | inline double Pow10(int n) {
29 | static const double e[] = { // 1e-0...1e308: 309 * 8 bytes = 2472 bytes
30 | 1e+0,
31 | 1e+1, 1e+2, 1e+3, 1e+4, 1e+5, 1e+6, 1e+7, 1e+8, 1e+9, 1e+10, 1e+11, 1e+12, 1e+13, 1e+14, 1e+15, 1e+16, 1e+17, 1e+18, 1e+19, 1e+20,
32 | 1e+21, 1e+22, 1e+23, 1e+24, 1e+25, 1e+26, 1e+27, 1e+28, 1e+29, 1e+30, 1e+31, 1e+32, 1e+33, 1e+34, 1e+35, 1e+36, 1e+37, 1e+38, 1e+39, 1e+40,
33 | 1e+41, 1e+42, 1e+43, 1e+44, 1e+45, 1e+46, 1e+47, 1e+48, 1e+49, 1e+50, 1e+51, 1e+52, 1e+53, 1e+54, 1e+55, 1e+56, 1e+57, 1e+58, 1e+59, 1e+60,
34 | 1e+61, 1e+62, 1e+63, 1e+64, 1e+65, 1e+66, 1e+67, 1e+68, 1e+69, 1e+70, 1e+71, 1e+72, 1e+73, 1e+74, 1e+75, 1e+76, 1e+77, 1e+78, 1e+79, 1e+80,
35 | 1e+81, 1e+82, 1e+83, 1e+84, 1e+85, 1e+86, 1e+87, 1e+88, 1e+89, 1e+90, 1e+91, 1e+92, 1e+93, 1e+94, 1e+95, 1e+96, 1e+97, 1e+98, 1e+99, 1e+100,
36 | 1e+101,1e+102,1e+103,1e+104,1e+105,1e+106,1e+107,1e+108,1e+109,1e+110,1e+111,1e+112,1e+113,1e+114,1e+115,1e+116,1e+117,1e+118,1e+119,1e+120,
37 | 1e+121,1e+122,1e+123,1e+124,1e+125,1e+126,1e+127,1e+128,1e+129,1e+130,1e+131,1e+132,1e+133,1e+134,1e+135,1e+136,1e+137,1e+138,1e+139,1e+140,
38 | 1e+141,1e+142,1e+143,1e+144,1e+145,1e+146,1e+147,1e+148,1e+149,1e+150,1e+151,1e+152,1e+153,1e+154,1e+155,1e+156,1e+157,1e+158,1e+159,1e+160,
39 | 1e+161,1e+162,1e+163,1e+164,1e+165,1e+166,1e+167,1e+168,1e+169,1e+170,1e+171,1e+172,1e+173,1e+174,1e+175,1e+176,1e+177,1e+178,1e+179,1e+180,
40 | 1e+181,1e+182,1e+183,1e+184,1e+185,1e+186,1e+187,1e+188,1e+189,1e+190,1e+191,1e+192,1e+193,1e+194,1e+195,1e+196,1e+197,1e+198,1e+199,1e+200,
41 | 1e+201,1e+202,1e+203,1e+204,1e+205,1e+206,1e+207,1e+208,1e+209,1e+210,1e+211,1e+212,1e+213,1e+214,1e+215,1e+216,1e+217,1e+218,1e+219,1e+220,
42 | 1e+221,1e+222,1e+223,1e+224,1e+225,1e+226,1e+227,1e+228,1e+229,1e+230,1e+231,1e+232,1e+233,1e+234,1e+235,1e+236,1e+237,1e+238,1e+239,1e+240,
43 | 1e+241,1e+242,1e+243,1e+244,1e+245,1e+246,1e+247,1e+248,1e+249,1e+250,1e+251,1e+252,1e+253,1e+254,1e+255,1e+256,1e+257,1e+258,1e+259,1e+260,
44 | 1e+261,1e+262,1e+263,1e+264,1e+265,1e+266,1e+267,1e+268,1e+269,1e+270,1e+271,1e+272,1e+273,1e+274,1e+275,1e+276,1e+277,1e+278,1e+279,1e+280,
45 | 1e+281,1e+282,1e+283,1e+284,1e+285,1e+286,1e+287,1e+288,1e+289,1e+290,1e+291,1e+292,1e+293,1e+294,1e+295,1e+296,1e+297,1e+298,1e+299,1e+300,
46 | 1e+301,1e+302,1e+303,1e+304,1e+305,1e+306,1e+307,1e+308
47 | };
48 | RAPIDJSON_ASSERT(n >= 0 && n <= 308);
49 | return e[n];
50 | }
51 |
52 | } // namespace internal
53 | RAPIDJSON_NAMESPACE_END
54 |
55 | #endif // RAPIDJSON_POW10_
56 |
--------------------------------------------------------------------------------
/include/rapidjson/internal/strfunc.h:
--------------------------------------------------------------------------------
1 | // Tencent is pleased to support the open source community by making RapidJSON available.
2 | //
3 | // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
4 | //
5 | // Licensed under the MIT License (the "License"); you may not use this file except
6 | // in compliance with the License. You may obtain a copy of the License at
7 | //
8 | // http://opensource.org/licenses/MIT
9 | //
10 | // Unless required by applicable law or agreed to in writing, software distributed
11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the
13 | // specific language governing permissions and limitations under the License.
14 |
15 | #ifndef RAPIDJSON_INTERNAL_STRFUNC_H_
16 | #define RAPIDJSON_INTERNAL_STRFUNC_H_
17 |
18 | #include "../rapidjson.h"
19 |
20 | RAPIDJSON_NAMESPACE_BEGIN
21 | namespace internal {
22 |
23 | //! Custom strlen() which works on different character types.
24 | /*! \tparam Ch Character type (e.g. char, wchar_t, short)
25 | \param s Null-terminated input string.
26 | \return Number of characters in the string.
27 | \note This has the same semantics as strlen(), the return value is not number of Unicode codepoints.
28 | */
29 | template
30 | inline SizeType StrLen(const Ch* s) {
31 | const Ch* p = s;
32 | while (*p) ++p;
33 | return SizeType(p - s);
34 | }
35 |
36 | } // namespace internal
37 | RAPIDJSON_NAMESPACE_END
38 |
39 | #endif // RAPIDJSON_INTERNAL_STRFUNC_H_
40 |
--------------------------------------------------------------------------------
/include/rapidjson/memorybuffer.h:
--------------------------------------------------------------------------------
1 | // Tencent is pleased to support the open source community by making RapidJSON available.
2 | //
3 | // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
4 | //
5 | // Licensed under the MIT License (the "License"); you may not use this file except
6 | // in compliance with the License. You may obtain a copy of the License at
7 | //
8 | // http://opensource.org/licenses/MIT
9 | //
10 | // Unless required by applicable law or agreed to in writing, software distributed
11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the
13 | // specific language governing permissions and limitations under the License.
14 |
15 | #ifndef RAPIDJSON_MEMORYBUFFER_H_
16 | #define RAPIDJSON_MEMORYBUFFER_H_
17 |
18 | #include "rapidjson.h"
19 | #include "internal/stack.h"
20 |
21 | RAPIDJSON_NAMESPACE_BEGIN
22 |
23 | //! Represents an in-memory output byte stream.
24 | /*!
25 | This class is mainly for being wrapped by EncodedOutputStream or AutoUTFOutputStream.
26 |
27 | It is similar to FileWriteBuffer but the destination is an in-memory buffer instead of a file.
28 |
29 | Differences between MemoryBuffer and StringBuffer:
30 | 1. StringBuffer has Encoding but MemoryBuffer is only a byte buffer.
31 | 2. StringBuffer::GetString() returns a null-terminated string. MemoryBuffer::GetBuffer() returns a buffer without terminator.
32 |
33 | \tparam Allocator type for allocating memory buffer.
34 | \note implements Stream concept
35 | */
36 | template
37 | struct GenericMemoryBuffer {
38 | typedef char Ch; // byte
39 |
40 | GenericMemoryBuffer(Allocator* allocator = 0, size_t capacity = kDefaultCapacity) : stack_(allocator, capacity) {}
41 |
42 | void Put(Ch c) { *stack_.template Push() = c; }
43 | void Flush() {}
44 |
45 | void Clear() { stack_.Clear(); }
46 | void ShrinkToFit() { stack_.ShrinkToFit(); }
47 | Ch* Push(size_t count) { return stack_.template Push(count); }
48 | void Pop(size_t count) { stack_.template Pop(count); }
49 |
50 | const Ch* GetBuffer() const {
51 | return stack_.template Bottom();
52 | }
53 |
54 | size_t GetSize() const { return stack_.GetSize(); }
55 |
56 | static const size_t kDefaultCapacity = 256;
57 | mutable internal::Stack stack_;
58 | };
59 |
60 | typedef GenericMemoryBuffer<> MemoryBuffer;
61 |
62 | //! Implement specialized version of PutN() with memset() for better performance.
63 | template<>
64 | inline void PutN(MemoryBuffer& memoryBuffer, char c, size_t n) {
65 | std::memset(memoryBuffer.stack_.Push(n), c, n * sizeof(c));
66 | }
67 |
68 | RAPIDJSON_NAMESPACE_END
69 |
70 | #endif // RAPIDJSON_MEMORYBUFFER_H_
71 |
--------------------------------------------------------------------------------
/include/rapidjson/memorystream.h:
--------------------------------------------------------------------------------
1 | // Tencent is pleased to support the open source community by making RapidJSON available.
2 | //
3 | // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
4 | //
5 | // Licensed under the MIT License (the "License"); you may not use this file except
6 | // in compliance with the License. You may obtain a copy of the License at
7 | //
8 | // http://opensource.org/licenses/MIT
9 | //
10 | // Unless required by applicable law or agreed to in writing, software distributed
11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the
13 | // specific language governing permissions and limitations under the License.
14 |
15 | #ifndef RAPIDJSON_MEMORYSTREAM_H_
16 | #define RAPIDJSON_MEMORYSTREAM_H_
17 |
18 | #include "rapidjson.h"
19 |
20 | RAPIDJSON_NAMESPACE_BEGIN
21 |
22 | //! Represents an in-memory input byte stream.
23 | /*!
24 | This class is mainly for being wrapped by EncodedInputStream or AutoUTFInputStream.
25 |
26 | It is similar to FileReadBuffer but the source is an in-memory buffer instead of a file.
27 |
28 | Differences between MemoryStream and StringStream:
29 | 1. StringStream has encoding but MemoryStream is a byte stream.
30 | 2. MemoryStream needs size of the source buffer and the buffer don't need to be null terminated. StringStream assume null-terminated string as source.
31 | 3. MemoryStream supports Peek4() for encoding detection. StringStream is specified with an encoding so it should not have Peek4().
32 | \note implements Stream concept
33 | */
34 | struct MemoryStream {
35 | typedef char Ch; // byte
36 |
37 | MemoryStream(const Ch *src, size_t size) : src_(src), begin_(src), end_(src + size), size_(size) {}
38 |
39 | Ch Peek() const { return (src_ == end_) ? '\0' : *src_; }
40 | Ch Take() { return (src_ == end_) ? '\0' : *src_++; }
41 | size_t Tell() const { return static_cast(src_ - begin_); }
42 |
43 | Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }
44 | void Put(Ch) { RAPIDJSON_ASSERT(false); }
45 | void Flush() { RAPIDJSON_ASSERT(false); }
46 | size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; }
47 |
48 | // For encoding detection only.
49 | const Ch* Peek4() const {
50 | return Tell() + 4 <= size_ ? src_ : 0;
51 | }
52 |
53 | const Ch* src_; //!< Current read position.
54 | const Ch* begin_; //!< Original head of the string.
55 | const Ch* end_; //!< End of stream.
56 | size_t size_; //!< Size of the stream.
57 | };
58 |
59 | RAPIDJSON_NAMESPACE_END
60 |
61 | #endif // RAPIDJSON_MEMORYBUFFER_H_
62 |
--------------------------------------------------------------------------------
/include/rapidjson/stringbuffer.h:
--------------------------------------------------------------------------------
1 | // Tencent is pleased to support the open source community by making RapidJSON available.
2 | //
3 | // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
4 | //
5 | // Licensed under the MIT License (the "License"); you may not use this file except
6 | // in compliance with the License. You may obtain a copy of the License at
7 | //
8 | // http://opensource.org/licenses/MIT
9 | //
10 | // Unless required by applicable law or agreed to in writing, software distributed
11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the
13 | // specific language governing permissions and limitations under the License.
14 |
15 | #ifndef RAPIDJSON_STRINGBUFFER_H_
16 | #define RAPIDJSON_STRINGBUFFER_H_
17 |
18 | #include "rapidjson.h"
19 |
20 | #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
21 | #include // std::move
22 | #endif
23 |
24 | #include "internal/stack.h"
25 |
26 | RAPIDJSON_NAMESPACE_BEGIN
27 |
28 | //! Represents an in-memory output stream.
29 | /*!
30 | \tparam Encoding Encoding of the stream.
31 | \tparam Allocator type for allocating memory buffer.
32 | \note implements Stream concept
33 | */
34 | template
35 | class GenericStringBuffer {
36 | public:
37 | typedef typename Encoding::Ch Ch;
38 |
39 | GenericStringBuffer(Allocator* allocator = 0, size_t capacity = kDefaultCapacity) : stack_(allocator, capacity) {}
40 |
41 | #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
42 | GenericStringBuffer(GenericStringBuffer&& rhs) : stack_(std::move(rhs.stack_)) {}
43 | GenericStringBuffer& operator=(GenericStringBuffer&& rhs) {
44 | if (&rhs != this)
45 | stack_ = std::move(rhs.stack_);
46 | return *this;
47 | }
48 | #endif
49 |
50 | void Put(Ch c) { *stack_.template Push() = c; }
51 | void Flush() {}
52 |
53 | void Clear() { stack_.Clear(); }
54 | void ShrinkToFit() {
55 | // Push and pop a null terminator. This is safe.
56 | *stack_.template Push() = '\0';
57 | stack_.ShrinkToFit();
58 | stack_.template Pop(1);
59 | }
60 | Ch* Push(size_t count) { return stack_.template Push(count); }
61 | void Pop(size_t count) { stack_.template Pop(count); }
62 |
63 | const Ch* GetString() const {
64 | // Push and pop a null terminator. This is safe.
65 | *stack_.template Push() = '\0';
66 | stack_.template Pop(1);
67 |
68 | return stack_.template Bottom();
69 | }
70 |
71 | size_t GetSize() const { return stack_.GetSize(); }
72 |
73 | static const size_t kDefaultCapacity = 256;
74 | mutable internal::Stack stack_;
75 |
76 | private:
77 | // Prohibit copy constructor & assignment operator.
78 | GenericStringBuffer(const GenericStringBuffer&);
79 | GenericStringBuffer& operator=(const GenericStringBuffer&);
80 | };
81 |
82 | //! String buffer with UTF8 encoding
83 | typedef GenericStringBuffer > StringBuffer;
84 |
85 | //! Implement specialized version of PutN() with memset() for better performance.
86 | template<>
87 | inline void PutN(GenericStringBuffer >& stream, char c, size_t n) {
88 | std::memset(stream.stack_.Push(n), c, n * sizeof(c));
89 | }
90 |
91 | RAPIDJSON_NAMESPACE_END
92 |
93 | #endif // RAPIDJSON_STRINGBUFFER_H_
94 |
--------------------------------------------------------------------------------
/src/CategoricalDimension.cpp:
--------------------------------------------------------------------------------
1 | #include "stdafx.h"
2 | #include "CategoricalDimension.h"
3 |
4 | CategoricalDimension::CategoricalDimension(const std::string& key, ulong numberOfValues)
5 | : Hashing(key), _numberOfValues(numberOfValues) { }
6 |
7 | bool CategoricalDimension::query(const Query& query, const Response& range, Response& response) const {
8 |
9 | if (query.evalWhere(_key)) {
10 |
11 | auto& values = query.getWhere(_key);
12 |
13 | auto note_it = _nodes.begin();
14 | for (auto range_it = range.begin(); range_it != range.end(); ++range_it) {
15 |
16 | nextNode(*range_it, note_it);
17 |
18 | while ((**range_it).endAfter((*note_it)->front())) {
19 |
20 | (*note_it)->queryWhere(values, response);
21 |
22 | if (++note_it == _nodes.end()) return true;
23 | }
24 | }
25 | return true;
26 |
27 | } else if (query.evalGroup(_key)) {
28 |
29 | auto node_it = _nodes.begin();
30 | for (auto range_it = range.begin(); range_it != range.end(); ++range_it) {
31 |
32 | nextNode(*range_it, node_it);
33 |
34 | while ((**range_it).endAfter((*node_it)->front())) {
35 |
36 | (*node_it)->queryGroup(response);
37 |
38 | if (++node_it == _nodes.end()) return true;
39 | }
40 | }
41 | return true;
42 |
43 | } else {
44 | return false;
45 | }
46 | }
47 |
48 | size_t CategoricalDimension::hash(const response_container& container, response_container& response, Data& data) {
49 | std::cout << "\tHashing Categorical Dimension: " + _key + "... ";
50 |
51 | data.prepareKey(_key);
52 |
53 | size_t pivots_count = 0;
54 |
55 | for (const auto& ptr : container) {
56 | if (ptr == nullptr || (*ptr).empty()) continue;
57 |
58 | _nodes.emplace_back(std::make_unique());
59 |
60 | pivots_count += _nodes.back()->hash(this, response, data, *(Pivot*)ptr);
61 | }
62 | _nodes.shrink_to_fit();
63 |
64 | std::cout << "Done." << std::endl;
65 | data.dispose();
66 |
67 | return pivots_count;
68 | }
69 |
70 | ulong CategoricalDimension::numberOfValues() const {
71 | return _numberOfValues;
72 | }
73 |
--------------------------------------------------------------------------------
/src/CategoricalDimension.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "Hashing.h"
4 | #include "CategoricalNode.h"
5 |
6 | class CategoricalDimension : public Hashing {
7 | public:
8 | CategoricalDimension(const std::string& key, ulong numberOfValues);
9 | CategoricalDimension(CategoricalDimension&&) = default;
10 | CategoricalDimension(const CategoricalDimension&) = delete;
11 |
12 | ~CategoricalDimension() = default;
13 |
14 | CategoricalDimension& operator=(CategoricalDimension&&) = default;
15 | CategoricalDimension& operator=(const CategoricalDimension&) = delete;
16 |
17 | bool query(const Query& query, const Response& range, Response& response) const override;
18 | size_t hash(const response_container& container, response_container& response, Data& data) override;
19 |
20 | ulong numberOfValues() const;
21 |
22 | protected:
23 |
24 | const ulong _numberOfValues{ 0 };
25 | };
--------------------------------------------------------------------------------
/src/CategoricalNode.cpp:
--------------------------------------------------------------------------------
1 | #include "stdafx.h"
2 | #include "CategoricalNode.h"
3 |
4 | #include "CategoricalDimension.h"
5 |
6 | void CategoricalNode::queryGroup(Response& response) const {
7 | response.insert(_container.begin(), _container.end());
8 | }
9 |
10 | void CategoricalNode::queryWhere(const std::vector& values, Response& response) const {
11 | for (auto& ptr : _container) {
12 | if (values[ptr.value()]) response.addElement(&ptr);
13 | }
14 | }
15 |
16 | size_t CategoricalNode::hash(const CategoricalDimension* hashing, response_container& response, Data& data, const Pivot& pivot) {
17 | auto size = ((CategoricalDimension*)hashing)->numberOfValues();
18 |
19 | std::vector used(size, 0);
20 |
21 | for (auto i = pivot.front(); i < pivot.back(); ++i) {
22 | int value = data.getIntProperty(i);
23 |
24 | data.setHash(i, value);
25 | used[value]++;
26 | }
27 |
28 | ulong accum = pivot.front();
29 | for (ulong i = 0; i < size; ++i) {
30 |
31 | if (used[i] == 0) continue;
32 |
33 | int first = accum;
34 | accum += used[i];
35 | int second = accum;
36 |
37 | _container.emplace_back(first, second, static_cast(i));
38 | }
39 | _container.shrink_to_fit();
40 |
41 | for (auto& ptr : _container) {
42 | response.emplace_back(&ptr);
43 | }
44 |
45 | data.sortHash(pivot.front(), pivot.back());
46 |
47 | return _container.size();
48 | }
49 |
--------------------------------------------------------------------------------
/src/CategoricalNode.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "CategoricalPivot.h"
4 |
5 | #include "Data.h"
6 | #include "Query.h"
7 | #include "Response.h"
8 |
9 | class CategoricalDimension;
10 |
11 | class CategoricalNode {
12 | public:
13 | CategoricalNode() = default;
14 |
15 | CategoricalNode(CategoricalNode&&) = default;
16 | CategoricalNode(const CategoricalNode&) = delete;
17 |
18 | ~CategoricalNode() = default;
19 |
20 | CategoricalNode& operator=(CategoricalNode&&) = delete;
21 | CategoricalNode& operator=(const CategoricalNode&) = delete;
22 |
23 | void queryGroup(Response& response) const;
24 | void queryWhere(const std::vector& values, Response& response) const;
25 |
26 | size_t hash(const CategoricalDimension* hashing, response_container& response, Data& data, const Pivot& pivot);
27 |
28 | inline const ulong front() const;
29 | inline const ulong back() const;
30 |
31 | protected:
32 | ulong value;
33 | std::vector _container;
34 | };
35 |
36 | const ulong CategoricalNode::front() const {
37 | return _container.front().front();
38 | }
39 |
40 | const ulong CategoricalNode::back() const {
41 | return _container.back().back();
42 | }
43 |
--------------------------------------------------------------------------------
/src/CategoricalPivot.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "Pivot.h"
4 | #include "Types.h"
5 |
6 | class CategoricalPivot : public Pivot {
7 | public:
8 | CategoricalPivot(ulong first, ulong second, const categorical_t& value) : Pivot(first, second), _value(value) { }
9 | CategoricalPivot(const Pivot& pivot, const categorical_t& value) : Pivot(pivot), _value(value) { }
10 | ~CategoricalPivot() = default;
11 |
12 | inline const categorical_t& value() const;
13 |
14 | protected:
15 | categorical_t _value;
16 | };
17 |
18 | const categorical_t& CategoricalPivot::value() const {
19 | return _value;
20 | }
21 |
--------------------------------------------------------------------------------
/src/CategoricalSerializer.cpp:
--------------------------------------------------------------------------------
1 | #include "stdafx.h"
2 | #include "CategoricalSerializer.h"
3 | #include "CategoricalPivot.h"
4 | #include "CategoricalDimension.h"
5 |
6 | CategoricalSerializer& CategoricalSerializer::getInstance() {
7 | static CategoricalSerializer instance;
8 | return instance;
9 | }
10 |
11 | std::string CategoricalSerializer::serialize(const CategoricalDimension* hashing, const Response& response, std::chrono::milliseconds& duration) {
12 |
13 | std::chrono::time_point start, end;
14 | start = std::chrono::high_resolution_clock::now();
15 |
16 | std::vector aggregate((hashing)->numberOfValues(), 0);
17 |
18 | rapidjson::StringBuffer buffer;
19 | rapidjson::Writer writer(buffer);
20 |
21 | for (const auto& pivot : response.container()) {
22 | aggregate[((CategoricalPivot*)pivot)->value()] += pivot->size();
23 | }
24 |
25 | end = std::chrono::high_resolution_clock::now();
26 | duration = std::chrono::duration_cast(end - start);
27 |
28 | writer.StartArray();
29 | for (ulong i = 0; i < aggregate.size(); ++i) {
30 | if (aggregate[i] == 0) continue;
31 |
32 | writer.StartArray();
33 | writer.Uint(i);
34 | writer.Uint(aggregate[i]);
35 | writer.EndArray();
36 | }
37 | writer.EndArray();
38 | return buffer.GetString();
39 | }
40 |
41 | std::string CategoricalSerializer::serialize(const CategoricalDimension* hashing, const std::pair& tuple, std::chrono::milliseconds& duration) {
42 |
43 | std::chrono::time_point start, end;
44 | start = std::chrono::high_resolution_clock::now();
45 |
46 | std::vector aggregate((hashing)->numberOfValues(), 0);
47 |
48 | rapidjson::StringBuffer buffer;
49 | rapidjson::Writer writer(buffer);
50 |
51 | auto it = tuple.second.begin();
52 | for (const auto& pivot : tuple.first.container()) {
53 | int size = 0;
54 |
55 | while (it != tuple.second.end() && (*pivot) > (**it) ) {
56 | size += (**it).size();
57 | it++;
58 | }
59 |
60 | aggregate[((CategoricalPivot*)pivot)->value()] += size;
61 | }
62 |
63 | end = std::chrono::high_resolution_clock::now();
64 | duration = std::chrono::duration_cast(end - start);
65 |
66 | writer.StartArray();
67 | for (ulong i = 0; i < aggregate.size(); ++i) {
68 | if (aggregate[i] == 0) continue;
69 |
70 | writer.StartArray();
71 | writer.Uint(i);
72 | writer.Uint(aggregate[i]);
73 | writer.EndArray();
74 | }
75 | writer.EndArray();
76 | return buffer.GetString();
77 | }
78 |
--------------------------------------------------------------------------------
/src/CategoricalSerializer.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "Serializer.h"
4 | #include "Response.h"
5 |
6 | class CategoricalDimension;
7 |
8 | class CategoricalSerializer : public Serializer {
9 | public:
10 | static CategoricalSerializer& getInstance();
11 |
12 | virtual std::string serialize(const CategoricalDimension* hashing, const Response& response, std::chrono::milliseconds& duration) override;
13 | virtual std::string serialize(const CategoricalDimension* hashing, const std::pair& tuple, std::chrono::milliseconds& duration) override;
14 |
15 | protected:
16 |
17 | private:
18 | };
19 |
--------------------------------------------------------------------------------
/src/DMPLoader.cpp:
--------------------------------------------------------------------------------
1 | #include "stdafx.h"
2 | #include "DMPLoader.h"
3 |
4 | DMPLoader& DMPLoader::getInstance() {
5 | static DMPLoader instance;
6 | return instance;
7 | }
8 |
9 | void DMPLoader::write(const std::string& path) {
10 |
11 | auto generator = getInMemoryGenerator(path);
12 |
13 | struct tweet {
14 | float latitude;
15 | float longitude;
16 | uint64_t time;
17 | uint8_t language;
18 | uint8_t device;
19 | uint8_t app;
20 | };
21 |
22 | boost::filesystem::path boost_path(generator.path());
23 |
24 | if (!exists(boost_path) || !is_directory(boost_path)) {
25 | std::cout << boost_path << " is a invalid path." << std::endl;
26 | return;
27 | }
28 |
29 | for (auto& x : boost::filesystem::directory_iterator(boost_path)) {
30 |
31 | if (is_directory(x)) continue;
32 |
33 | std::ifstream infile(x.path().string(), std::ios::binary);
34 |
35 | std::cout << x.path().string() << std::endl;
36 |
37 | infile.unsetf(std::ios_base::skipws);
38 |
39 | for (int i = 0; i < 32; ++i) {
40 | infile.ignore(std::numeric_limits::max(), '\n');
41 | }
42 |
43 | while (!infile.eof()) {
44 | try {
45 | tweet record;
46 | infile.read((char*)&record, 19);
47 |
48 | time_t time(record.time);
49 | struct tm * ptm = std::gmtime(&time);
50 |
51 | generator.addFloat("lat0", record.latitude);
52 | generator.addFloat("lon0", record.longitude);
53 |
54 | generator.addInt("language", record.language);
55 | generator.addInt("device", record.device);
56 | generator.addInt("app", record.app);
57 |
58 | generator.addInt("tseries", util::mkgmtime(ptm));
59 |
60 | generator.execute();
61 | } catch (...) {
62 | break;
63 | }
64 | }
65 |
66 | infile.close();
67 | }
68 |
69 | generator.commit();
70 | }
71 |
72 | InMemoryDataGenerator DMPLoader::getInMemoryGenerator(const std::string& path) {
73 | std::vector tokens;
74 |
75 | tokens.emplace_back("lat0", "lat0", Spatial);
76 | tokens.emplace_back("lon0", "lon0", Spatial);
77 |
78 | tokens.emplace_back("language", "cat0", Categorical);
79 | tokens.emplace_back("device" , "cat1", Categorical);
80 | tokens.emplace_back("app" , "cat2", Categorical);
81 |
82 | tokens.emplace_back("tseries", "tseries", Temporal);
83 |
84 | return InMemoryDataGenerator(path, tokens);
85 | }
86 |
--------------------------------------------------------------------------------
/src/DMPLoader.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "DataLoader.h"
4 | #include "InMemoryDataGenerator.h"
5 |
6 | class DMPLoader : public DataLoader {
7 | public:
8 | static DMPLoader& getInstance();
9 | virtual void write(const std::string& path) override;
10 |
11 | protected:
12 | virtual InMemoryDataGenerator getInMemoryGenerator(const std::string& path) override;
13 |
14 | private:
15 | DMPLoader() = default;
16 | ~DMPLoader() = default;
17 | };
18 |
--------------------------------------------------------------------------------
/src/Data.cpp:
--------------------------------------------------------------------------------
1 | #include "stdafx.h"
2 | #include "Data.h"
3 |
4 | void Data::initialize(ulong size) {
5 | _hash = data_container::result(size);
6 | _index = data_container::result(size);
7 |
8 | for (ulong i = 0; i < _index.size(); i++) {
9 | _hash[i] = 0;
10 | _index[i] = i;
11 | }
12 | }
13 |
14 | void Data::sortHash(ulong fromIndex, ulong toIndex) {
15 | const auto functor = std::bind(&Data::comparator, this, std::placeholders::_1, std::placeholders::_2);
16 | std::sort(_index.begin() + fromIndex, _index.begin() + toIndex, functor);
17 | }
18 |
19 | void Data::setHash(ulong id, unsigned short value) {
20 | _hash[_index[id]] = value;
21 | }
22 |
23 | unsigned long Data::getHash(ulong index) const {
24 | return _hash[index];
25 | }
26 |
27 |
28 | /* Local Variables: */
29 | /* mode: c */
30 | /* indent-tabs-mode: t */
31 | /* c-basic-offset: 8 */
32 | /* tab-width: 8 */
33 | /* End: */
34 |
--------------------------------------------------------------------------------
/src/Data.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | class Data {
4 | public:
5 | Data() = default;
6 | virtual ~Data() = default;
7 |
8 | void initialize(ulong size);
9 |
10 | void sortHash(ulong fromIndex, ulong toIndex);
11 |
12 | virtual void dispose() = 0;
13 |
14 | virtual void prepareKey(const std::string& key) = 0;
15 | virtual void prepareKey(const std::string& str, const std::vector& key) = 0;
16 |
17 | inline int getIntProperty(ulong id) { return getIntProperty(id, 0); };
18 | inline float getFloatProperty(ulong id) { return getFloatProperty(id, 0); };
19 |
20 | virtual int getIntProperty(ulong id, ulong key) = 0;
21 | virtual float getFloatProperty(ulong id, ulong key) = 0;
22 |
23 | void setHash(ulong id, unsigned short value);
24 |
25 | inline bool comparator(ulong bit0, ulong bit1) const {
26 | return _hash[bit0] < _hash[bit1];
27 | }
28 |
29 | virtual ulong size() const = 0;
30 |
31 | protected:
32 | unsigned long getHash(ulong index) const;
33 |
34 | data_container::result _index;
35 | data_container::result _hash;
36 |
37 | private:
38 | };
39 |
40 | /* Local Variables: */
41 | /* mode: c */
42 | /* indent-tabs-mode: t */
43 | /* c-basic-offset: 8 */
44 | /* tab-width: 8 */
45 | /* End: */
46 |
--------------------------------------------------------------------------------
/src/DataGenerator.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | class DataGenerator {
4 | public:
5 | DataGenerator(const std::string& path, const std::vector tokens) : _path(path), _tokens(tokens) { }
6 | virtual ~DataGenerator() = default;
7 |
8 | inline const std::string& path() const;
9 |
10 | virtual void addInt(const std::string& key, ulong value) = 0;
11 | virtual void addFloat(const std::string& key, float value) = 0;
12 |
13 | virtual void execute() = 0;
14 | virtual void commit() = 0;
15 |
16 | protected:
17 | std::string _path;
18 | const std::vector _tokens;
19 |
20 | private:
21 | };
22 |
23 | const std::string& DataGenerator::path() const {
24 | return _path;
25 | }
26 |
--------------------------------------------------------------------------------
/src/DataLoader.cpp:
--------------------------------------------------------------------------------
1 | #include "stdafx.h"
2 | #include "DataLoader.h"
3 |
4 | std::tuple, long long, size_t> DataLoader::build(const Schema& schema) {
5 |
6 | size_t pivots_count = 0;
7 |
8 | std::chrono::time_point start, end;
9 |
10 | std::unique_ptr data = nullptr;
11 |
12 | if (schema.loader == "sql") {
13 | data = getSQLData(schema);
14 | } else {
15 | data = getInMemoryData(schema);
16 | }
17 |
18 | std::cout << "\nBuildind HashedCube: " << std::endl;
19 | std::cout << "\tName: " << schema.name << std::endl;
20 | std::cout << "\tSize: " << data->size() << std::endl;
21 | std::cout << "\tLeaf Threshold: " << schema.leaf << "\n" << std::endl;
22 |
23 | std::shared_ptrcube = std::make_shared(data->size());
24 |
25 | response_container current, response;
26 | current = cube->root();
27 |
28 | start = std::chrono::high_resolution_clock::now();
29 |
30 | // spatial
31 | pivots_count += cube->setSpatial(schema.spatial, schema.leaf)->hash(current, response, *data.get());
32 | current.swap(response);
33 | response.clear();
34 | std::cout << "\t\tNumber of Pivots: " << current.size() << std::endl;
35 |
36 | // categorical
37 | for (auto& pair : schema.categorical) {
38 | pivots_count += cube->addCategorical(pair.first, pair.second)->hash(current, response, *data.get());
39 | current.swap(response);
40 | response.clear();
41 | std::cout << "\t\tNumber of Pivots: " << current.size() << std::endl;
42 | }
43 |
44 | // temporal
45 | for (auto& pair : schema.temporal) {
46 | pivots_count += cube->addTemporal(pair.first, pair.second)->hash(current, response, *data.get());
47 | current.swap(response);
48 | response.clear();
49 | std::cout << "\t\tNumber of Pivots: " << current.size() << std::endl;
50 | }
51 |
52 | end = std::chrono::high_resolution_clock::now();
53 | long long duration = std::chrono::duration_cast(end - start).count();
54 |
55 | std::cout << "\n\tDuration: "+ std::to_string(duration) + "s\n" << std::endl;
56 |
57 | data->dispose();
58 |
59 | if (schema.loader == "sql") {
60 | cube->setSQLData(data);
61 | }
62 | return std::make_tuple(cube , duration, pivots_count);
63 | }
64 |
65 | std::unique_ptr DataLoader::getInMemoryData(const Schema& schema) {
66 | return std::make_unique(InMemoryDataDescriptor(schema));
67 | }
68 |
69 | std::unique_ptr DataLoader::getSQLData(const Schema& schema) {
70 | return std::make_unique(schema, InMemoryDataDescriptor(schema));
71 | }
72 |
--------------------------------------------------------------------------------
/src/DataLoader.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "HashedCube.h"
4 |
5 | #include "Data.h"
6 | #include "DataGenerator.h"
7 |
8 | #include "SQLData.h"
9 |
10 | #include "InMemoryData.h"
11 | #include "InMemoryDataGenerator.h"
12 |
13 | class DataLoader {
14 | public:
15 | static std::tuple, long long, size_t> build(const Schema& schema);
16 | virtual void write(const std::string& path) = 0;
17 |
18 | protected:
19 | static std::unique_ptr getInMemoryData(const Schema& schema);
20 | static std::unique_ptr getSQLData(const Schema& schema);
21 |
22 | virtual InMemoryDataGenerator getInMemoryGenerator(const std::string& path) = 0;
23 | };
24 |
--------------------------------------------------------------------------------
/src/FlightsDelayLoader.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "DataLoader.h"
4 | #include "InMemoryDataGenerator.h"
5 |
6 | #include "FlightsLoader.h"
7 |
8 | class FlightsDelayLoader : public DataLoader, public FlightsLoader {
9 | public:
10 | static FlightsDelayLoader& getInstance();
11 | virtual void write(const std::string& path) override;
12 |
13 | protected:
14 | virtual InMemoryDataGenerator getInMemoryGenerator(const std::string& path) override;
15 |
16 | private:
17 | FlightsDelayLoader() = default;
18 | ~FlightsDelayLoader() = default;
19 | };
20 |
--------------------------------------------------------------------------------
/src/FlightsLoader.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | class FlightsLoader {
4 | public:
5 | FlightsLoader() = default;
6 | ~FlightsLoader() = default;
7 |
8 | protected:
9 | inline void loadMap(const std::string& path);
10 | std::unordered_map> map;
11 | };
12 |
13 | void FlightsLoader::loadMap(const std::string & pathStr) {
14 | boost::filesystem::path path(pathStr + "csv/");
15 |
16 | if (!exists(path) || !is_directory(path)) {
17 | std::cout << path << " is a invalid path." << std::endl;
18 | return;
19 | }
20 |
21 | for (auto& x : boost::filesystem::directory_iterator(path)) {
22 |
23 | if (is_directory(x)) continue;
24 |
25 | std::ifstream infile(x.path().string());
26 |
27 | std::string line;
28 | while (std::getline(infile, line)) {
29 | if (line == "") continue;
30 |
31 | auto record = util::split(line, ",");
32 |
33 | try {
34 | if (record[4] == "\"\"") continue;
35 | map[record[4].substr(1, record[4].size() - 2)] = { std::stof(record[6]), std::stof(record[7]) };
36 | }
37 | catch (std::invalid_argument) {
38 | continue;
39 | }
40 | }
41 |
42 | infile.close();
43 | }
44 | }
--------------------------------------------------------------------------------
/src/FlightsPerformanceLoader.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "DataLoader.h"
4 | #include "InMemoryDataGenerator.h"
5 |
6 | #include "FlightsLoader.h"
7 |
8 | class FlightsPerformanceLoader : public DataLoader, public FlightsLoader {
9 | public:
10 | static FlightsPerformanceLoader& getInstance();
11 | virtual void write(const std::string& path) override;
12 |
13 | protected:
14 | virtual InMemoryDataGenerator getInMemoryGenerator(const std::string& path) override;
15 |
16 | private:
17 | FlightsPerformanceLoader() = default;
18 | ~FlightsPerformanceLoader() = default;
19 | };
20 |
--------------------------------------------------------------------------------
/src/HashedCube.cpp:
--------------------------------------------------------------------------------
1 | #include "stdafx.h"
2 | #include "HashedCube.h"
3 |
4 | HashedCube::HashedCube(ulong size){
5 | _root = std::make_unique(Pivot(size));
6 | _root_container.emplace_back(_root.get());
7 | }
8 |
9 | std::shared_ptr HashedCube::setSpatial(const std::vector& key, ulong leaf) {
10 | _spatial = std::make_shared(key, leaf);
11 | return _spatial;
12 | }
13 |
14 | std::shared_ptr HashedCube::addCategorical(const std::string& key, ulong numberOfValues) {
15 | _categorical.emplace_back(std::make_shared(key, numberOfValues));
16 | return _categorical.back();
17 | }
18 |
19 | std::shared_ptr HashedCube::addTemporal(const std::string& key, ulong bucketSize) {
20 | _temporal.emplace_back(std::make_shared(key, bucketSize));
21 | return _temporal.back();
22 | }
23 |
24 |
25 |
--------------------------------------------------------------------------------
/src/HashedCube.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "SQLData.h"
4 | #include "SpatialDimension.h"
5 | #include "TemporalDimension.h"
6 | #include "CategoricalDimension.h"
7 |
8 | class HashedCube {
9 | public:
10 | HashedCube(ulong size);
11 |
12 | HashedCube(HashedCube&&) = default;
13 | HashedCube(const HashedCube&) = delete;
14 |
15 | ~HashedCube() = default;
16 |
17 | HashedCube& operator=(HashedCube&&) = default;
18 | HashedCube& operator=(const HashedCube&) = delete;
19 |
20 | std::shared_ptr setSpatial(const std::vector& key, ulong leaf);
21 | std::shared_ptr addCategorical(const std::string& key, ulong numberOfValues);
22 | std::shared_ptr addTemporal(const std::string& key, ulong bucketSize);
23 |
24 | inline std::shared_ptr& spatial();
25 | inline std::vector>& categorical();
26 | inline std::vector>& temporal();
27 |
28 | inline void setSQLData(std::unique_ptr& data);
29 | inline SQLData* getSQLData(void) const;
30 |
31 | inline const response_container& root() const;
32 | inline ulong size() const;
33 |
34 | inline ulong getCategoricalValues(const std::string& key) const;
35 |
36 | protected:
37 | std::unique_ptr _root;
38 | response_container _root_container;
39 |
40 | std::unique_ptr _data{ nullptr };
41 |
42 | std::shared_ptr _spatial { nullptr };
43 | std::vector> _categorical;
44 | std::vector> _temporal;
45 | };
46 |
47 | ulong HashedCube::getCategoricalValues(const std::string& key) const {
48 | for (const auto& hashing : _categorical) {
49 | if (hashing->key() == key) {
50 | return hashing->numberOfValues();
51 | }
52 | }
53 | return 0;
54 | }
55 |
56 | void HashedCube::setSQLData(std::unique_ptr& data) {
57 | _data = std::move(data);
58 | }
59 |
60 | SQLData* HashedCube::getSQLData(void) const {
61 | return (_data != nullptr)? (SQLData*)_data.get() : nullptr;
62 | }
63 |
64 | const response_container& HashedCube::root() const {
65 | return _root_container;
66 | }
67 |
68 | ulong HashedCube::size() const {
69 | return _root->size();
70 | }
71 |
72 | std::shared_ptr& HashedCube::spatial() {
73 | return _spatial;
74 | }
75 |
76 | std::vector>& HashedCube::categorical() {
77 | return _categorical;
78 | }
79 |
80 | std::vector>& HashedCube::temporal() {
81 | return _temporal;
82 | }
--------------------------------------------------------------------------------
/src/HashedCubeInstances.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "HashedCube.h"
4 | #include "Query.h"
5 |
6 | class HashedCubeInstances {
7 | public:
8 |
9 | static HashedCubeInstances& getInstance();
10 |
11 | static void run(const std::vector& args);
12 | static void write(const std::vector& args);
13 |
14 | ~HashedCubeInstances();
15 |
16 | inline bool ready() const { return _ready; };
17 | inline void setReady() { _ready = true; };
18 |
19 | inline std::shared_ptr get(std::string instance) const {
20 | auto it = _container.find(instance);
21 | if (it != _container.end()) {
22 | return (*it).second;
23 | } else {
24 | return nullptr;
25 | }
26 | }
27 |
28 | std::string query(const Query& query);
29 | std::string schema(const std::string& instance);
30 |
31 | inline void enableTelemetry(const std::string& file) {
32 | _telemetry = true;
33 |
34 | auto time = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
35 | std::stringstream stream;
36 | stream << std::put_time(std::localtime(&time), "-%Y-%m-%d-%H-%M-%S.csv");
37 |
38 | _telemetry_file = std::make_shared(file + stream.str(), std::ofstream::out);
39 | }
40 | inline bool telemetry() { return _telemetry; }
41 |
42 | std::unordered_map> _container;
43 |
44 | protected:
45 | bool _ready{ false };
46 |
47 | bool _telemetry{ false };
48 | std::shared_ptr _telemetry_file;
49 | };
50 |
--------------------------------------------------------------------------------
/src/Hashing.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "Data.h"
4 | #include "Query.h"
5 | #include "Response.h"
6 |
7 | template using node_container = std::vector>;
8 | template using node_iterator = typename std::vector>::const_iterator;
9 |
10 | template
11 | class Hashing {
12 | public:
13 | Hashing(const KeyType& key) : _key(key) { }
14 |
15 | Hashing(Hashing&&) = default;
16 | Hashing(const Hashing&) = delete;
17 |
18 | virtual ~Hashing() = default;
19 |
20 | Hashing& operator=(Hashing&&) = default;
21 | Hashing& operator=(const Hashing&) = delete;
22 |
23 | const KeyType& key() const { return _key; }
24 |
25 | virtual bool query(const Query& query, const Response& range, Response& response) const = 0;
26 | virtual size_t hash(const response_container& container, response_container& response, Data& data) = 0;
27 |
28 | inline void nextNode(const Pivot* range, node_iterator& node) const {
29 | if (range->front() <= (*node)->front() && range->back() >= (*node)->front()) return;
30 | node = std::lower_bound(node, _nodes.end(), range->front(),
31 | [](const std::unique_ptr& o1, const size_t& o2) { return o1->front() < o2; });
32 | }
33 |
34 | protected:
35 |
36 | KeyType _key;
37 | node_container _nodes;
38 | };
39 |
--------------------------------------------------------------------------------
/src/InMemoryData.cpp:
--------------------------------------------------------------------------------
1 | #include "stdafx.h"
2 | #include "InMemoryData.h"
3 |
4 | InMemoryData::InMemoryData(const InMemoryDataDescriptor& descriptor) : _descriptor(descriptor) {
5 | initialize(_descriptor.size());
6 | }
7 |
8 | void InMemoryData::dispose() {
9 | _data.clear();
10 | }
11 |
12 | void InMemoryData::prepareKey(const std::string& key) {
13 | auto tuple = _descriptor.get(key);
14 |
15 | std::ifstream is(_descriptor.schema().path + "hcf/" + std::get<0>(tuple), std::ios::in | std::ifstream::binary);
16 |
17 | if (is.is_open()) {
18 | try {
19 | switch (std::get<1>(tuple)) {
20 | case Spatial:
21 | _data.emplace_back(size() * sizeof(float));
22 | is.read(&_data.back()[0], size() * sizeof(float));
23 | break;
24 | case Categorical:
25 | case Temporal:
26 | default:
27 | _data.emplace_back(size() * sizeof(int));
28 | is.read(&_data.back()[0], size() * sizeof(int));
29 | break;
30 | }
31 |
32 | is.close();
33 | } catch (const std::exception& e) {
34 | std::cout << e.what() << std::endl;
35 | exit(0);
36 | }
37 | } else {
38 | std::cout << "!error opening file" << std::endl;
39 | exit(0);
40 | }
41 | }
42 |
43 | void InMemoryData::prepareKey(const std::string& str, const std::vector& key) {
44 | for (auto& k : key) {
45 | prepareKey(str + std::to_string(k));
46 | }
47 | }
48 |
49 | int InMemoryData::getIntProperty(ulong id, ulong key) {
50 | return *((int*)&_data[key][_index[id] * sizeof(int)]);
51 | }
52 |
53 | float InMemoryData::getFloatProperty(ulong id, ulong key) {
54 | return *((float*)&_data[key][_index[id] * sizeof(float)]);
55 | }
56 |
57 | ulong InMemoryData::size() const {
58 | return _descriptor.size();
59 | }
60 |
61 |
--------------------------------------------------------------------------------
/src/InMemoryData.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "Data.h"
4 | #include "InMemoryDataDescriptor.h"
5 |
6 | class InMemoryData : public Data {
7 | public:
8 | InMemoryData(const InMemoryDataDescriptor& descriptor);
9 | virtual ~InMemoryData() = default;
10 |
11 | virtual void dispose() override;
12 |
13 | virtual void prepareKey(const std::string& key) override;
14 | virtual void prepareKey(const std::string& str, const std::vector& key) override;
15 |
16 | virtual int getIntProperty(ulong id, ulong key) override;
17 | virtual float getFloatProperty(ulong id, ulong key) override;
18 |
19 | virtual ulong size() const override;
20 |
21 | protected:
22 | std::vector> _data;
23 | InMemoryDataDescriptor _descriptor;
24 | };
25 |
--------------------------------------------------------------------------------
/src/InMemoryDataDescriptor.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | class InMemoryDataDescriptor {
4 | public:
5 | InMemoryDataDescriptor(ulong size) : _size(size) { }
6 | InMemoryDataDescriptor(const Schema& schema) : _schema(schema) {
7 | std::ifstream is(schema.path + "hcf/descriptor.hcf");
8 | boost::archive::text_iarchive archive(is);
9 |
10 | archive & (*this);
11 | }
12 |
13 | virtual ~InMemoryDataDescriptor() = default;
14 |
15 | inline const Schema& schema() const;
16 |
17 | inline token_t get(const std::string& key) const;
18 | inline void set(const tuple_t& tuple);
19 |
20 | void save(const std::string& fileName) const {
21 | std::ofstream os(fileName);
22 | boost::archive::text_oarchive archive(os);
23 |
24 | archive & (*this);
25 | }
26 |
27 | inline unsigned int size() const;
28 |
29 | template
30 | void serialize(Archive & ar, const unsigned int version);
31 |
32 |
33 | protected:
34 | unsigned int _size{ 0 };
35 | unsigned int _bitsPerHash{ 0 }; // legacy
36 | std::unordered_map _tokens;
37 |
38 | Schema _schema;
39 |
40 | private:
41 | friend class boost::serialization::access;
42 | };
43 |
44 | template
45 | void InMemoryDataDescriptor::serialize(Archive & ar, const unsigned int version) {
46 | ar & _size;
47 | ar & _bitsPerHash;
48 | ar & _tokens;
49 | }
50 |
51 | const Schema& InMemoryDataDescriptor::schema() const {
52 | return _schema;
53 | }
54 |
55 | token_t InMemoryDataDescriptor::get(const std::string& key) const {
56 | return _tokens.at(key);
57 | }
58 |
59 | void InMemoryDataDescriptor::set(const tuple_t& tuple) {
60 | _tokens.emplace(std::get<0>(tuple), token_t(std::get<1>(tuple), std::get<2>(tuple)));
61 | }
62 |
63 | unsigned int InMemoryDataDescriptor::size() const {
64 | return _size * _schema.fraction;
65 | }
--------------------------------------------------------------------------------
/src/InMemoryDataGenerator.cpp:
--------------------------------------------------------------------------------
1 | #include "stdafx.h"
2 | #include "InMemoryDataGenerator.h"
3 | #include "InMemoryDataDescriptor.h"
4 |
5 | InMemoryDataGenerator::InMemoryDataGenerator(const std::string& path, const std::vector tokens)
6 | : DataGenerator(path, tokens) {
7 |
8 | for (auto token : _tokens) {
9 | std::ofstream *s = new std::ofstream(_path + "hcf/" + std::get<1>(token), std::ios::out | std::ios::binary);
10 | _output.push_back(std::shared_ptr(s));
11 | }
12 | }
13 |
14 | void InMemoryDataGenerator::addInt(const std::string& key, ulong value) {
15 | _output[find_if(key)]->write(reinterpret_cast(&value), sizeof(ulong));
16 | }
17 |
18 | void InMemoryDataGenerator::addFloat(const std::string& key, float value) {
19 | _output[find_if(key)]->write(reinterpret_cast(&value), sizeof(float));
20 | }
21 |
22 | void InMemoryDataGenerator::execute() {
23 | _size++;
24 | }
25 |
26 | void InMemoryDataGenerator::commit() {
27 | for (auto& output : _output) {
28 | output->close();
29 | }
30 |
31 | InMemoryDataDescriptor descriptor(_size);
32 |
33 | for (auto token : _tokens) {
34 | descriptor.set(token);
35 | }
36 |
37 | descriptor.save(_path + "hcf/descriptor.hcf");
38 | }
39 |
--------------------------------------------------------------------------------
/src/InMemoryDataGenerator.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "DataGenerator.h"
4 | #include
5 |
6 | class InMemoryDataGenerator : public DataGenerator {
7 | public:
8 | InMemoryDataGenerator(const std::string& path, const std::vector tokens);
9 | virtual ~InMemoryDataGenerator() = default;
10 |
11 | virtual void addInt(const std::string& key, ulong value) override;
12 |
13 | virtual void addFloat(const std::string& key, float value) override;
14 |
15 | virtual void execute() override;
16 |
17 | virtual void commit() override;
18 |
19 | protected:
20 |
21 | ulong _size{ 0 };
22 | std::vector> _output;
23 |
24 | private:
25 | inline size_t find_if(const std::string& key) {
26 | auto it = std::find_if(_tokens.begin(), _tokens.end(), [key](tuple_t tuple) { return (key == std::get<0>(tuple)); });
27 |
28 | return it - _tokens.begin();
29 | }
30 |
31 | };
32 |
--------------------------------------------------------------------------------
/src/Mercator.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include "Types.h"
3 |
4 | namespace util {
5 |
6 | inline ulong lon2tilex(double lon, int z) {
7 | //lon = std::max(std::min(lon, 179.8), -179.8);
8 | int x = std::floor((lon + 180.0) / 360.0 * pow(2.0, z));
9 | return x & ((1 << z) - 1);
10 | }
11 |
12 | inline ulong lat2tiley(double lat, int z) {
13 | //lat = std::max(std::min(lat, 89.8), -89.8);
14 | int y = std::floor((1.0 - log(tan(lat * M_PI / 180.0) + 1.0 / cos(lat * M_PI / 180.0)) / M_PI) / 2.0 * pow(2.0, z));
15 | return y & ((1 << z) - 1);
16 | }
17 |
18 |
19 | inline double tilex2lon(double x, int z) {
20 | return x / pow(2.0, z) * 360.0 - 180;
21 | }
22 |
23 | inline double tiley2lat(double y, int z) {
24 | double n = M_PI - 2.0 * M_PI * y / pow(2.0, z);
25 | return 180.0 / M_PI * atan(0.5 * (exp(n) - exp(-n)));
26 | }
27 |
28 | inline bool intersectsTile(const tile_t& tile, const TileBounds& bounds) {
29 | return (bounds.lat1 <= tiley2lat(tile.y, tile.z)) && (bounds.lon1 >= tilex2lon(tile.x, tile.z))
30 | && (bounds.lat0 >= tiley2lat(tile.y + 1, tile.z)) && (bounds.lon0 <= tilex2lon(tile.x + 1, tile.z));
31 | }
32 |
33 | inline bool intersects(const tile_t& tile0, const Tile& tile1) {
34 | const float lat = tiley2lat(tile0.y, tile0.z);
35 | const float lon = tilex2lon(tile0.x, tile0.z);
36 | return (lon >= tile1.lon0 && lon <= tile1.lon1) && (lat <= tile1.lat0 && lat >= tile1.lat1);
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/MySQLSerializer.cpp:
--------------------------------------------------------------------------------
1 | #include "stdafx.h"
2 | #include "MySQLSerializer.h"
3 |
4 | MySQLSerializer& MySQLSerializer::getInstance() {
5 | static MySQLSerializer instance;
6 | return instance;
7 | }
8 |
9 | std::string MySQLSerializer::serialize(const Response& response, std::chrono::milliseconds& duration) {
10 | return "[]";
11 | }
12 |
13 | std::string MySQLSerializer::serialize(SQLData* data, Response& response, std::chrono::milliseconds& duration) {
14 | static const ulong max_count = 300;
15 | ulong count = 0;
16 |
17 | rapidjson::StringBuffer buffer;
18 | rapidjson::Writer writer(buffer);
19 |
20 | SQLite::Statement statement(*data->getDb(), "SELECT * FROM data WHERE ROWID==?");
21 |
22 | writer.StartArray();
23 |
24 | for (auto it = response.container().begin(); count < max_count && it != response.container().end(); ++it) {
25 | for (ulong id = (*it)->front(); count < max_count && id != (*it)->back(); ++id, ++count) {
26 | try {
27 | statement.reset();
28 | statement.bind(1, (int)data->getSQLIndex(id));
29 | if (statement.executeStep()) {
30 | writer.StartObject();
31 | for (int i = 0; i < statement.getColumnCount(); ++i) {
32 | writer.String(statement.getColumnName(i));
33 | switch (statement.getColumn(i).getType()) {
34 | case SQLITE_INTEGER:
35 | writer.Int(statement.getColumn(i).getInt());
36 | break;
37 | case SQLITE_FLOAT:
38 | writer.Double(statement.getColumn(i).getDouble());
39 | break;
40 | case SQLITE_TEXT:
41 | writer.String(statement.getColumn(i).getText());
42 | break;
43 | case SQLITE_BLOB:
44 | writer.String((char*)statement.getColumn(i).getBlob());
45 | break;
46 | case SQLITE_NULL:
47 | writer.String("null");
48 | break;
49 | }
50 | }
51 | writer.EndObject();
52 | }
53 | }
54 | catch (std::exception& e) {
55 | std::cout << "SQLite exception: " << e.what() << std::endl;
56 | return "[]";
57 | }
58 | }
59 | }
60 |
61 | writer.EndArray();
62 | return buffer.GetString();
63 | }
--------------------------------------------------------------------------------
/src/MySQLSerializer.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "Serializer.h"
4 | #include "Response.h"
5 |
6 | #include "SQLData.h"
7 |
8 | class MySQLSerializer {
9 | public:
10 | static MySQLSerializer& getInstance();
11 | std::string serialize(const Response& response, std::chrono::milliseconds& duration);
12 | std::string serialize(SQLData* data, Response& response, std::chrono::milliseconds& duration);
13 | protected:
14 |
15 | private:
16 | };
--------------------------------------------------------------------------------
/src/Pivot.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | class Pivot {
4 | public:
5 | Pivot() = default;
6 |
7 | Pivot(ulong size) : Pivot(0, size) { };
8 | Pivot(ulong first, ulong second) : _pivot({first, second}) { };
9 |
10 | Pivot(const Pivot&) = default;
11 |
12 | virtual ~Pivot() = default;
13 |
14 | inline bool empty() const;
15 | inline ulong size() const;
16 |
17 | inline ulong front() const;
18 | inline ulong back() const;
19 |
20 | inline bool operator< (const Pivot& other) const;
21 | inline bool operator> (const Pivot& other) const;
22 |
23 | // implicit conversion
24 | inline operator const Pivot*() const;
25 |
26 | inline bool endAfter(const Pivot& other) const;
27 | inline bool endAfter(const ulong other) const;
28 | inline bool endBefore(const Pivot& other) const;
29 |
30 | protected:
31 | std::array _pivot;
32 | };
33 |
34 | using pivot_container = std::vector;
35 | using pivot_iterator = pivot_container::const_iterator;
36 |
37 | using response_container = std::vector;
38 | using response_iterator = response_container::const_iterator;
39 |
40 |
41 | bool Pivot::empty() const {
42 | return (back() - front()) == 0;
43 | }
44 |
45 | ulong Pivot::size() const {
46 | return back() - front();
47 | }
48 |
49 | ulong Pivot::front() const {
50 | return _pivot[0];
51 | }
52 |
53 | ulong Pivot::back() const {
54 | return _pivot[1];
55 | }
56 |
57 | bool Pivot::operator<(const Pivot& other) const {
58 | return back() < other.front();
59 | }
60 |
61 | bool Pivot::operator>(const Pivot& other) const {
62 | return back() > other.front();
63 | }
64 |
65 | Pivot::operator const Pivot*() const {
66 | return this;
67 | }
68 |
69 | bool Pivot::endAfter(const ulong other) const {
70 | return back() > other;
71 | }
72 |
73 | bool Pivot::endAfter(const Pivot& other) const {
74 | return back() > other.front();
75 | }
76 |
77 | bool Pivot::endBefore(const Pivot& other) const {
78 | return back() <= other.front();
79 | }
--------------------------------------------------------------------------------
/src/Query.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include "TemporalInterval.h"
3 |
4 | class HashedCube;
5 |
6 | class Query {
7 | public:
8 | enum QueryType { TILE, GROUP, TSERIES, SCATTER, MYSQL, REGION };
9 |
10 | QueryType type;
11 | std::string instance{ "brightkite" };
12 | std::shared_ptr cube;
13 |
14 | ulong zoom;
15 | ulong resolution;
16 |
17 | std::unordered_map tseries;
18 | std::unordered_set group;
19 |
20 | Query(const std::string& url);
21 | Query(const std::vector& tokens);
22 | Query(const std::string& instance, const std::string& type);
23 |
24 | friend std::ostream& operator<< (std::ostream& stream, const Query& query);
25 |
26 | inline const TemporalInterval& getTseries(const std::string& key) const {
27 | return tseries.at(key);
28 | }
29 | inline const std::vector& getWhere(const std::string& key) const {
30 | return _where.at(key);
31 | }
32 |
33 |
34 | inline bool evalTseries(const std::string& key) const {
35 | return tseries.find(key) != tseries.end();
36 | }
37 | inline bool evalGroup(const std::string& key) const {
38 | return group.find(key) != group.end();
39 | }
40 |
41 |
42 | // tile
43 | inline void emplaceTile(ulong key, const Tile& tile) {
44 | if (key < _tile.size()) {
45 | _tile[key] = tile;
46 | }
47 | }
48 | inline bool evalTile(ulong key) const {
49 | if (key < _tile.size()) {
50 | return _tile[key].isValid();
51 | } else return false;
52 | }
53 | inline bool evalAnyTile(const std::vector& key) const {
54 | for (auto& k : key) {
55 | if (evalTile(k)) return true;
56 | }
57 | return false;
58 | }
59 | inline const Tile& getTile(ulong key) const {
60 | return _tile[key];
61 | }
62 |
63 | // region
64 | inline ulong getLastValidRegion(void) const {
65 | return _last_valid_region;
66 | }
67 | inline void emplaceRegion(ulong key, const TileBounds& region) {
68 | if (key < _region.size()) {
69 | _region[key] = region;
70 | _last_valid_region = key;
71 | }
72 | }
73 | inline bool evalRegion(ulong key) const {
74 | if (key < _region.size()) {
75 | return _region[key].isValid();
76 | }
77 | else return false;
78 | }
79 | inline bool evalAnyRegion(const std::vector& key) const {
80 | for (auto& k : key) {
81 | if (evalRegion(k)) return true;
82 | }
83 | return false;
84 | }
85 | inline const TileBounds& getRegion(ulong key) const {
86 | return _region.at(key);
87 | }
88 |
89 | //where
90 | void emplaceWhere(const std::string& key, const std::vector& values);
91 |
92 | inline bool evalWhere(const std::string& key) const {
93 | return _where.find(key) != _where.end();
94 | }
95 |
96 | protected:
97 | // tile
98 | std::vector _tile;
99 |
100 | // region
101 | ulong _last_valid_region = 0;
102 | std::vector _region;
103 |
104 | // where
105 | std::unordered_map> _where;
106 |
107 | inline std::string nextToken(std::vector::const_iterator& it) { return *(++it); }
108 | };
--------------------------------------------------------------------------------
/src/ResidentSetSize.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Author: David Robert Nadeau
3 | * Site: http://NadeauSoftware.com/
4 | * License: Creative Commons Attribution 3.0 Unported License
5 | * http://creativecommons.org/licenses/by/3.0/deed.en_US
6 | */
7 |
8 | #if defined(_WIN32)
9 | #include
10 | #include
11 |
12 | #elif defined(__unix__) || defined(__unix) || defined(unix) || (defined(__APPLE__) && defined(__MACH__))
13 | #include
14 | #include
15 |
16 | #if defined(__APPLE__) && defined(__MACH__)
17 | #include
18 |
19 | #elif (defined(_AIX) || defined(__TOS__AIX__)) || (defined(__sun__) || defined(__sun) || defined(sun) && (defined(__SVR4) || defined(__svr4__)))
20 | #include
21 | #include
22 |
23 | #elif defined(__linux__) || defined(__linux) || defined(linux) || defined(__gnu_linux__)
24 | #include
25 |
26 | #endif
27 |
28 | #else
29 | #error "Cannot define getPeakRSS( ) or getCurrentRSS( ) for an unknown OS."
30 | #endif
31 |
32 |
33 |
34 |
35 |
36 | /**
37 | * Returns the peak (maximum so far) resident set size (physical
38 | * memory use) measured in bytes, or zero if the value cannot be
39 | * determined on this OS.
40 | */
41 | inline size_t getPeakRSS()
42 | {
43 | #if defined(_WIN32)
44 | /* Windows -------------------------------------------------- */
45 | PROCESS_MEMORY_COUNTERS info;
46 | GetProcessMemoryInfo(GetCurrentProcess(), &info, sizeof(info));
47 | return (size_t)info.PeakWorkingSetSize;
48 |
49 | #elif (defined(_AIX) || defined(__TOS__AIX__)) || (defined(__sun__) || defined(__sun) || defined(sun) && (defined(__SVR4) || defined(__svr4__)))
50 | /* AIX and Solaris ------------------------------------------ */
51 | struct psinfo psinfo;
52 | int fd = -1;
53 | if ((fd = open("/proc/self/psinfo", O_RDONLY)) == -1)
54 | return (size_t)0L; /* Can't open? */
55 | if (read(fd, &psinfo, sizeof(psinfo)) != sizeof(psinfo))
56 | {
57 | close(fd);
58 | return (size_t)0L; /* Can't read? */
59 | }
60 | close(fd);
61 | return (size_t)(psinfo.pr_rssize * 1024L);
62 |
63 | #elif defined(__unix__) || defined(__unix) || defined(unix) || (defined(__APPLE__) && defined(__MACH__))
64 | /* BSD, Linux, and OSX -------------------------------------- */
65 | struct rusage rusage;
66 | getrusage(RUSAGE_SELF, &rusage);
67 | #if defined(__APPLE__) && defined(__MACH__)
68 | return (size_t)rusage.ru_maxrss;
69 | #else
70 | return (size_t)(rusage.ru_maxrss * 1024L);
71 | #endif
72 |
73 | #else
74 | /* Unknown OS ----------------------------------------------- */
75 | return (size_t)0L; /* Unsupported. */
76 | #endif
77 | }
78 |
79 |
80 |
81 |
82 |
83 | /**
84 | * Returns the current resident set size (physical memory use) measured
85 | * in bytes, or zero if the value cannot be determined on this OS.
86 | */
87 | inline size_t getCurrentRSS()
88 | {
89 | #if defined(_WIN32)
90 | /* Windows -------------------------------------------------- */
91 | PROCESS_MEMORY_COUNTERS info;
92 | GetProcessMemoryInfo(GetCurrentProcess(), &info, sizeof(info));
93 | return (size_t)info.WorkingSetSize;
94 |
95 | #elif defined(__APPLE__) && defined(__MACH__)
96 | /* OSX ------------------------------------------------------ */
97 | struct mach_task_basic_info info;
98 | mach_msg_type_number_t infoCount = MACH_TASK_BASIC_INFO_COUNT;
99 | if (task_info(mach_task_self(), MACH_TASK_BASIC_INFO,
100 | (task_info_t)&info, &infoCount) != KERN_SUCCESS)
101 | return (size_t)0L; /* Can't access? */
102 | return (size_t)info.resident_size;
103 |
104 | #elif defined(__linux__) || defined(__linux) || defined(linux) || defined(__gnu_linux__)
105 | /* Linux ---------------------------------------------------- */
106 | long rss = 0L;
107 | FILE* fp = NULL;
108 | if ((fp = fopen("/proc/self/statm", "r")) == NULL)
109 | return (size_t)0L; /* Can't open? */
110 | if (fscanf(fp, "%*s%ld", &rss) != 1)
111 | {
112 | fclose(fp);
113 | return (size_t)0L; /* Can't read? */
114 | }
115 | fclose(fp);
116 | return (size_t)rss * (size_t)sysconf(_SC_PAGESIZE);
117 |
118 | #else
119 | /* AIX, BSD, Solaris, and Unknown OS ------------------------ */
120 | return (size_t)0L; /* Unsupported. */
121 | #endif
122 | }
--------------------------------------------------------------------------------
/src/Response.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "stdafx.h"
4 | #include "Pivot.h"
5 |
6 | class Response {
7 | public:
8 | Response() = default;
9 | Response(const response_container& container) : _container(container) {};
10 |
11 | ~Response() = default;
12 |
13 | inline const response_container& container() const;
14 |
15 | inline void addElement(const Pivot* const pivot);
16 |
17 | template
18 | inline void insert(_Iter begin, _Iter last);
19 |
20 | inline size_t size() const;
21 |
22 | inline response_iterator begin() const;
23 | inline response_iterator end() const;
24 |
25 | inline void swap(Response& right);
26 |
27 | protected:
28 | response_container _container;
29 | };
30 |
31 | response_iterator Response::begin() const {
32 | return _container.begin();
33 | }
34 |
35 | response_iterator Response::end() const {
36 | return _container.end();
37 | }
38 |
39 | void Response::swap(Response& right) {
40 | _container.swap(right._container);
41 | right._container.clear();
42 | }
43 |
44 | const response_container& Response::container() const {
45 | return _container;
46 | }
47 |
48 | void Response::addElement(const Pivot* const pivot) {
49 | _container.emplace_back(pivot);
50 | }
51 |
52 | template
53 | void Response::insert(_Iter begin, _Iter last) {
54 | _container.insert(_container.end(), begin, last);
55 | }
56 |
57 | size_t Response::size() const {
58 | return _container.size();
59 | }
60 |
61 |
--------------------------------------------------------------------------------
/src/SQLData.cpp:
--------------------------------------------------------------------------------
1 | #include "stdafx.h"
2 | #include "SQLData.h"
3 |
4 | SQLData::SQLData(const Schema& schema, const InMemoryDataDescriptor& descriptor) : InMemoryData(descriptor) {
5 | try {
6 | _db = std::make_unique(schema.path + "db3/log.db3", SQLITE_OPEN_READONLY);
7 | std::cout << "SQLite database file '" << _db->getFilename().c_str() << "' opened successfully\n";
8 | } catch (std::exception& e) {
9 | std::cout << "SQLite exception: " << e.what() << std::endl;
10 | return;
11 | }
12 | }
13 |
14 | void SQLData::dispose() {
15 | InMemoryData::dispose();
16 | Data::_hash.clear();
17 | }
18 |
--------------------------------------------------------------------------------
/src/SQLData.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "Data.h"
4 | #include"Types.h"
5 |
6 | #include "InMemoryData.h"
7 |
8 | class SQLData : public InMemoryData {
9 | public:
10 | SQLData(const Schema& schema, const InMemoryDataDescriptor& descriptor);
11 | virtual ~SQLData() = default;
12 |
13 | virtual void dispose() override;
14 |
15 | SQLData(const SQLData&) = default;
16 | SQLData& operator=(const SQLData&) = default;
17 |
18 | inline SQLite::Database* getDb() const;
19 | inline ulong getSQLIndex(ulong id) const;
20 |
21 | protected:
22 | std::unique_ptr _db;
23 | };
24 |
25 | SQLite::Database* SQLData::getDb() const {
26 | return _db.get();
27 | }
28 |
29 | ulong SQLData::getSQLIndex(ulong id) const {
30 | return _index[id];
31 | }
32 |
33 |
--------------------------------------------------------------------------------
/src/ScatterSerializer.cpp:
--------------------------------------------------------------------------------
1 | #include "stdafx.h"
2 | #include "ScatterSerializer.h"
3 |
4 | #include "CategoricalDimension.h"
5 |
6 | ScatterSerializer& ScatterSerializer::getInstance() {
7 | static ScatterSerializer instance;
8 | return instance;
9 | }
10 |
11 | std::string ScatterSerializer::serialize(const CategoricalDimension* hashing, const Response& response, std::chrono::milliseconds& duration) { return "[]"; }
12 |
13 | std::string ScatterSerializer::serialize(const CategoricalDimension* hashing, const std::pair& tuple, std::chrono::milliseconds& duration) { return "[]"; }
14 |
15 | std::string ScatterSerializer::serialize(const std::vector>& tuples, std::chrono::milliseconds& duration) {
16 | if (tuples.size() != 2) return "[]";
17 |
18 | std::chrono::time_point start, end;
19 | start = std::chrono::high_resolution_clock::now();
20 |
21 | size_t size = (tuples[0].first)->numberOfValues() * (tuples[1].first)->numberOfValues();
22 |
23 | std::vector aggregate(size, 0);
24 |
25 | rapidjson::StringBuffer buffer;
26 | rapidjson::Writer writer(buffer);
27 |
28 | auto it = tuples[1].second.begin();
29 | for (const auto& pivot : tuples[0].second.container()) {
30 | int size = 0;
31 |
32 | while (it != tuples[1].second.end() && (*pivot) > (**it)) {
33 | aggregate[((CategoricalPivot*)pivot)->value() * (tuples[1].first)->numberOfValues() + ((CategoricalPivot*)*it)->value()] += ((CategoricalPivot*)*it)->size();
34 | it++;
35 | }
36 | }
37 |
38 | end = std::chrono::high_resolution_clock::now();
39 | duration = std::chrono::duration_cast(end - start);
40 |
41 | writer.StartArray();
42 | for (ulong i = 0; i < aggregate.size(); ++i) {
43 | if (aggregate[i] == 0) continue;
44 |
45 | writer.StartArray();
46 | writer.Uint(i - ((i / ((tuples[1].first)->numberOfValues()) * ((tuples[1].first)->numberOfValues()))));
47 | writer.Uint(i / (tuples[1].first)->numberOfValues());
48 | writer.Uint(aggregate[i]);
49 | writer.EndArray();
50 | }
51 | writer.EndArray();
52 | return buffer.GetString();
53 | }
54 |
--------------------------------------------------------------------------------
/src/ScatterSerializer.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "Serializer.h"
4 | #include "Response.h"
5 |
6 | class CategoricalDimension;
7 |
8 | class ScatterSerializer : public Serializer {
9 | public:
10 |
11 | static ScatterSerializer& getInstance();
12 |
13 | std::string serialize(const CategoricalDimension* hashing, const Response& response, std::chrono::milliseconds& duration) override;
14 | std::string serialize(const CategoricalDimension* hashing, const std::pair& tuple, std::chrono::milliseconds& duration) override;
15 |
16 | std::string serialize(const std::vector>& tuples, std::chrono::milliseconds& duration);
17 | };
--------------------------------------------------------------------------------
/src/Serializer.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "Response.h"
4 |
5 | template
6 | class Serializer {
7 | public:
8 | virtual std::string serialize(const T* hashing, const Response& response, std::chrono::milliseconds& duration) = 0;
9 | virtual std::string serialize(const T* hashing, const std::pair& tuple, std::chrono::milliseconds& duration) = 0;
10 | protected:
11 | private:
12 | };
13 |
--------------------------------------------------------------------------------
/src/Server.cpp:
--------------------------------------------------------------------------------
1 | #include "stdafx.h"
2 | #include "Server.h"
3 | #include "Query.h"
4 |
5 | #include "HashedCubeInstances.h"
6 |
7 |
8 | Server& Server::getInstance() {
9 | // c++11 static local variable initilization is thread-safe
10 | static Server instance;
11 | return instance;
12 | }
13 |
14 | void Server::run(bool disable_multithreading, ulong port) {
15 | mg_mgr_init(&Server::getInstance().mgr, NULL);
16 | Server::getInstance().nc = mg_bind(&Server::getInstance().mgr, std::to_string(port).c_str(), handler);
17 |
18 | mg_set_protocol_http_websocket(Server::getInstance().nc);
19 |
20 | Server::getInstance().http_server_opts.document_root = "WebContent";
21 |
22 | if (!disable_multithreading) {
23 | mg_enable_multithreading(Server::getInstance().nc);
24 | }
25 |
26 | std::cout << "\nServer running..." << std::endl;
27 |
28 | while (Server::getInstance().running) {
29 | mg_mgr_poll(&Server::getInstance().mgr, 1);
30 | }
31 | mg_mgr_free(&Server::getInstance().mgr);
32 | }
33 |
34 | void Server::stop() {
35 | running = false;
36 | }
37 |
38 | void Server::handler(struct mg_connection* conn, int ev, void *p) {
39 | if (ev != MG_EV_HTTP_REQUEST) return;
40 |
41 | struct http_message *hm = (struct http_message *) p;
42 | std::string uri(hm->uri.p, hm->uri.len);
43 |
44 | try {
45 | std::vector tokens = util::split(uri, "[/]+");
46 |
47 | if (tokens.size() <= 1) {
48 | mg_serve_http(conn, hm, Server::getInstance().http_server_opts);
49 |
50 | }
51 | else if (tokens[1] == "rest") {
52 | if (!HashedCubeInstances::getInstance().ready()) {
53 | printJson(conn, "[]", 200);
54 |
55 | }
56 | else if (tokens.size() >= 4) {
57 | if (tokens[2] == "schema") {
58 | printJson(conn, HashedCubeInstances::getInstance().schema(tokens[3]), 200);
59 | }
60 | else if (tokens.size() >= 5 && tokens[2] == "query") {
61 | printJson(conn, HashedCubeInstances::getInstance().query(Query(tokens)), 200);
62 | return;
63 | }
64 | else {
65 | printJson(conn, "[]", 200);
66 | }
67 | }
68 | }
69 | else {
70 | mg_serve_http(conn, hm, Server::getInstance().http_server_opts);
71 | }
72 | } catch (...) {
73 | std::cout << uri << std::endl;
74 | printJson(conn, "[]", 200);
75 | }
76 | }
77 |
78 | void Server::printText(struct mg_connection* conn, const std::string& content, int code) {
79 | const std::string sep = "\r\n";
80 |
81 | std::stringstream ss;
82 | ss << "HTTP/1.1 " << code << " OK" << sep
83 | << "Content-Type: text/plain" << sep
84 | << "Access-Control-Allow-Origin: " << "*" << sep
85 | << "Connection: keep-alive" << sep
86 | << "Cache-Control: public, max-age=" << "86400" << sep
87 | << "Content-Length: %d" << sep << sep
88 | << "%s";
89 |
90 | mg_printf(conn, ss.str().c_str(), (int)content.size(), content.c_str());
91 | }
92 |
93 | void Server::printJson(struct mg_connection* conn, const std::string& content, int code) {
94 | const std::string sep = "\r\n";
95 |
96 | bool cache = true;
97 | if (content == "[null]") cache = false;
98 |
99 | std::stringstream ss;
100 | ss << "HTTP/1.1 " << code << " OK" << sep
101 | << "Content-Type: application/json" << sep
102 | << "Access-Control-Allow-Origin: " << "*" << sep
103 | << "Connection: keep-alive" << sep;
104 | if (cache) ss << "Cache-Control: public, max-age=" << "86400" << sep;
105 | ss << "Content-Length: %d" << sep << sep
106 | << "%s";
107 |
108 | mg_printf(conn, ss.str().c_str(), (int)content.size(), content.c_str());
109 | }
110 |
--------------------------------------------------------------------------------
/src/Server.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | class Server {
4 | public:
5 | static Server& getInstance();
6 |
7 |
8 | static void run(bool disable_multithreading, ulong port);
9 |
10 | void stop();
11 |
12 | static void handler(struct mg_connection* conn, int ev, void *p);
13 |
14 | static void printText(struct mg_connection* conn, const std::string& content, int code);
15 | static void printJson(struct mg_connection* conn, const std::string& content, int code);
16 |
17 | struct mg_mgr mgr;
18 | struct mg_connection *nc;
19 |
20 | bool running{ true };
21 |
22 | protected:
23 | struct mg_serve_http_opts http_server_opts;
24 |
25 | private:
26 | Server() = default;
27 | ~Server() = default;
28 | };
29 |
--------------------------------------------------------------------------------
/src/SnapLoader.cpp:
--------------------------------------------------------------------------------
1 | #include "stdafx.h"
2 | #include "SnapLoader.h"
3 |
4 | SnapLoader& SnapLoader::getInstance() {
5 | static SnapLoader instance;
6 | return instance;
7 | }
8 |
9 | void SnapLoader::write(const std::string& path) {
10 |
11 | auto generator = getInMemoryGenerator(path);
12 |
13 | boost::filesystem::path boost_path(generator.path());
14 |
15 | if (!exists(boost_path) || !is_directory(boost_path)) {
16 | std::cout << boost_path << " is a invalid path." << std::endl;
17 | return;
18 | }
19 |
20 | for (auto& x : boost::filesystem::directory_iterator(boost_path)) {
21 |
22 | if (is_directory(x)) continue;
23 |
24 | std::ifstream infile(x.path().string());
25 |
26 | infile.unsetf(std::ios_base::skipws);
27 |
28 | size_t line_count = std::count(std::istreambuf_iterator(infile), std::istreambuf_iterator(), '\n') + 1;
29 | infile.seekg(0, infile.beg);
30 |
31 | #pragma omp parallel for
32 | for (int l = 0; l < (int)line_count; ++l) {
33 | std::string line;
34 |
35 | #pragma omp critical (read_snap)
36 | {
37 | std::getline(infile, line);
38 | }
39 |
40 | if (line == "") continue;
41 |
42 | auto record = util::split(line, "[\t]+");
43 |
44 | if (record.size() != 5) continue;
45 |
46 | float lat = std::stof(record[2]);
47 | float lon = std::stof(record[3]);
48 |
49 | if (lat < -90.f || lat > 90.f) continue;
50 | if (lon < -180.f || lat > 180.f) continue;
51 |
52 | if (lat == 0.f && lon == 0.f) continue;
53 |
54 | auto datetime = util::split(record[1], "T");
55 |
56 | if (datetime.size() != 2) continue;
57 |
58 | auto date = util::split(datetime[0], "-");
59 | auto hour = util::split(datetime[1], ":");
60 |
61 | if (date.size() != 3) continue;
62 |
63 | int days = util::days_from_civil(std::stoi(date[0]), std::stoi(date[1]), std::stoi(date[2]));
64 |
65 | std::tm time = { 0 };
66 | time.tm_sec = std::stoi(hour[2]);
67 | time.tm_min = std::stoi(hour[1]);
68 | time.tm_hour = std::stoi(hour[0]);
69 |
70 | time.tm_mday = std::stoi(date[2]);
71 | time.tm_mon = std::stoi(date[1]) - 1;
72 | time.tm_year = std::stoi(date[0]) - 1900;
73 |
74 | #pragma omp critical (write_snap)
75 | {
76 | generator.addFloat("lat0", lat);
77 | generator.addFloat("lon0", lon);
78 |
79 | generator.addInt("hour_of_day", std::stoi(hour[0]));
80 | generator.addInt("day_of_week", (util::weekday_from_days(days) + 6) % 7);
81 | generator.addInt("month_of_year", std::stoi(date[1]) - 1);
82 | generator.addInt("day_of_month", std::stoi(date[2]) - 1);
83 |
84 | generator.addInt("tseries", util::mkgmtime(&time));
85 |
86 | generator.execute();
87 | }
88 | }
89 |
90 | infile.close();
91 | }
92 |
93 | generator.commit();
94 | }
95 |
96 | InMemoryDataGenerator SnapLoader::getInMemoryGenerator(const std::string& path) {
97 | std::vector tokens;
98 |
99 | tokens.emplace_back("lat0", "lat0", Spatial);
100 | tokens.emplace_back("lon0", "lon0", Spatial);
101 |
102 |
103 | tokens.emplace_back("hour_of_day", "cat0", Categorical);
104 | tokens.emplace_back("day_of_week", "cat1", Categorical);
105 |
106 | tokens.emplace_back("month_of_year", "cat2", Categorical);
107 | tokens.emplace_back("day_of_month", "cat3", Categorical);
108 |
109 | tokens.emplace_back("tseries", "tseries", Temporal);
110 |
111 | return InMemoryDataGenerator(path, tokens);
112 | }
113 |
--------------------------------------------------------------------------------
/src/SnapLoader.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "DataLoader.h"
4 | #include "InMemoryDataGenerator.h"
5 |
6 | class SnapLoader : public DataLoader {
7 | public:
8 | static SnapLoader& getInstance();
9 | virtual void write(const std::string& path) override;
10 |
11 | protected:
12 | virtual InMemoryDataGenerator getInMemoryGenerator(const std::string& path) override;
13 |
14 | private:
15 | SnapLoader() = default;
16 | ~SnapLoader() = default;
17 | };
18 |
--------------------------------------------------------------------------------
/src/SpatialDimension.cpp:
--------------------------------------------------------------------------------
1 | #include "stdafx.h"
2 | #include "SpatialDimension.h"
3 |
4 | #include "TileNode.h"
5 |
6 | SpatialDimension::SpatialDimension(const std::vector& key, ulong leaf) : Hashing(key) {
7 | _max_zoom = 20 * (ulong)key.size();
8 | _min_per_node = leaf;
9 | }
10 |
11 | bool SpatialDimension::query(const Query& query, const Response& range, Response& response) const {
12 | if (!query.evalAnyRegion(_key) && !query.evalAnyTile(_key)) return false;
13 |
14 | auto node_it = _nodes.begin();
15 | for (auto range_it = range.begin(); range_it != range.end(); ++range_it) {
16 |
17 | nextNode(*range_it, node_it);
18 |
19 | while ((**range_it).endAfter((*node_it)->front())) {
20 |
21 | if (query.type == Query::TILE) {
22 | (*node_it)->queryTile(this, query, response, 0);
23 | } else {
24 | (*node_it)->queryRegion(this, query, response, 0);
25 | }
26 |
27 | if (++node_it == _nodes.end()) return true;
28 | }
29 | }
30 |
31 | return true;
32 | }
33 |
34 | size_t SpatialDimension::hash(const response_container& container, response_container& response, Data& data) {
35 | std::cout << "\tHashing " + std::to_string(key().size()) + " SpatialDimension(s)...";
36 |
37 | data.prepareKey("lat", key());
38 | data.prepareKey("lon", key());
39 |
40 | size_t pivots_count = 0;
41 |
42 | for (const auto& ptr : container) {
43 | if (ptr == nullptr || (*ptr).empty()) continue;
44 |
45 | _nodes.emplace_back(std::make_unique(*ptr, tile_t()));
46 |
47 | pivots_count += _nodes.back()->hash(this, response, data);
48 | }
49 | _nodes.shrink_to_fit();
50 |
51 | std::cout << "Done." << std::endl;
52 | data.dispose();
53 |
54 | return pivots_count;
55 | }
56 |
57 | ulong SpatialDimension::maxZoom() const {
58 | return _max_zoom;
59 | }
60 |
61 |
62 | ulong SpatialDimension::min_per_node() const {
63 | return _min_per_node;
64 | }
65 |
66 |
67 |
--------------------------------------------------------------------------------
/src/SpatialDimension.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "Hashing.h"
4 | #include "TileNode.h"
5 |
6 | class SpatialDimension : public Hashing> {
7 | public:
8 | SpatialDimension(const std::vector& key, ulong leaf);
9 | SpatialDimension(SpatialDimension&&) = default;
10 | SpatialDimension(const SpatialDimension&) = delete;
11 |
12 | ~SpatialDimension() = default;
13 |
14 | SpatialDimension& operator=(SpatialDimension&&) = default;
15 | SpatialDimension& operator=(const SpatialDimension&) = delete;
16 |
17 | bool query(const Query& query, const Response& range, Response& response) const override;
18 | size_t hash(const response_container& container, response_container& response, Data& data) override;
19 |
20 | ulong maxZoom() const;
21 | ulong min_per_node() const;
22 |
23 | protected:
24 |
25 | ulong _max_zoom;
26 | ulong _min_per_node;
27 | };
28 |
--------------------------------------------------------------------------------
/src/SpatialSerializer.cpp:
--------------------------------------------------------------------------------
1 | #include "stdafx.h"
2 | #include "SpatialSerializer.h"
3 |
4 | #include "TilePivot.h"
5 |
6 | SpatialSerializer& SpatialSerializer::getInstance() {
7 | static SpatialSerializer instance;
8 | return instance;
9 | }
10 |
11 | std::string SpatialSerializer::serialize(const SpatialDimension* hashing, const Response& response, std::chrono::milliseconds& duration) {
12 |
13 | std::chrono::time_point start, end;
14 | start = std::chrono::high_resolution_clock::now();
15 |
16 | std::unordered_map aggregate;
17 |
18 | for (const auto& pivot : response.container()) {
19 | aggregate[((TilePivot*)pivot)->value()] += pivot->size();
20 | }
21 |
22 | end = std::chrono::high_resolution_clock::now();
23 | duration = std::chrono::duration_cast(end - start);
24 |
25 | rapidjson::StringBuffer buffer;
26 | rapidjson::Writer writer(buffer);
27 |
28 | writer.StartArray();
29 | for (const auto& pair : aggregate) {
30 | writer.StartArray();
31 | writer.Uint(pair.first.x);
32 | writer.Uint(pair.first.y);
33 | writer.Uint(pair.first.z);
34 | writer.Uint(pair.second);
35 | writer.EndArray();
36 | }
37 | writer.EndArray();
38 | return buffer.GetString();
39 | }
40 |
41 | std::string SpatialSerializer::serialize(const SpatialDimension* hashing, const std::pair& tuple, std::chrono::milliseconds& duration) {
42 |
43 | std::chrono::time_point start, end;
44 | start = std::chrono::high_resolution_clock::now();
45 |
46 | std::unordered_map aggregate;
47 |
48 | auto it = tuple.second.begin();
49 | for (const auto& pivot : tuple.first.container()) {
50 | ulong size = 0;
51 |
52 | while (it != tuple.second.end() && (*pivot) > (**it)) {
53 | size += (**it).size();
54 | it++;
55 | }
56 |
57 | aggregate[((TilePivot*)pivot)->value()] += size;
58 | }
59 |
60 | end = std::chrono::high_resolution_clock::now();
61 | duration = std::chrono::duration_cast(end - start);
62 |
63 | rapidjson::StringBuffer buffer;
64 | rapidjson::Writer writer(buffer);
65 |
66 | writer.StartArray();
67 | for (const auto& pair : aggregate) {
68 | if (pair.second == 0) continue;
69 | writer.StartArray();
70 | writer.Uint(pair.first.x);
71 | writer.Uint(pair.first.y);
72 | writer.Uint(pair.first.z);
73 | writer.Uint(pair.second);
74 | writer.EndArray();
75 | }
76 | writer.EndArray();
77 | return buffer.GetString();
78 | }
79 |
--------------------------------------------------------------------------------
/src/SpatialSerializer.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "Serializer.h"
4 | #include "Response.h"
5 |
6 | class SpatialDimension;
7 |
8 | class SpatialSerializer : public Serializer {
9 | public:
10 |
11 | static SpatialSerializer& getInstance();
12 |
13 | std::string serialize(const SpatialDimension* hashing, const Response& response, std::chrono::milliseconds& duration) override;
14 | std::string serialize(const SpatialDimension* hashing, const std::pair& tuple, std::chrono::milliseconds& duration) override;
15 |
16 | protected:
17 |
18 | private:
19 | };
20 |
--------------------------------------------------------------------------------
/src/SplomLoader.cpp:
--------------------------------------------------------------------------------
1 | #include "stdafx.h"
2 | #include "SplomLoader.h"
3 |
4 | SplomLoader& SplomLoader::getInstance() {
5 | static SplomLoader instance;
6 | return instance;
7 | }
8 |
9 | void SplomLoader::write(const std::string& path) {
10 |
11 | auto generator = getInMemoryGenerator(path);
12 |
13 | for (int l = 0; l < 1000000000; ++l) {
14 |
15 | float d0, d1, d2, d3, d4;
16 |
17 | d0 = randNormal(10, 10);
18 | d1 = randNormal(10, 10);
19 | d2 = randNormal(d0, 10);
20 | d3 = (log(fabs(d0) + 1) + randUniform(3, 1));
21 | d4 = randNormal(10, 10);
22 |
23 | generator.addInt("dim0_10", util::linearScale(-40.f, 60.f, 0, 10, d0));
24 | generator.addInt("dim1_10", util::linearScale(-40.f, 60.f, 0, 10, d1));
25 | generator.addInt("dim2_10", util::linearScale(-70.f, 80.f, 0, 10, d2));
26 | generator.addInt("dim3_10", util::linearScale(1.f, 7.f, 0, 10, d3));
27 | generator.addInt("dim4_10", util::linearScale(-40.f, 60.f, 0, 10, d4));
28 |
29 | generator.addInt("dim0_20", util::linearScale(-40.f, 60.f, 0, 20, d0));
30 | generator.addInt("dim1_20", util::linearScale(-40.f, 60.f, 0, 20, d1));
31 | generator.addInt("dim2_20", util::linearScale(-70.f, 80.f, 0, 20, d2));
32 | generator.addInt("dim3_20", util::linearScale(1.f, 7.f, 0, 20, d3));
33 | generator.addInt("dim4_20", util::linearScale(-40.f, 60.f, 0, 20, d4));
34 |
35 | generator.addInt("dim0_30", util::linearScale(-40.f, 60.f, 0, 30, d0));
36 | generator.addInt("dim1_30", util::linearScale(-40.f, 60.f, 0, 30, d1));
37 | generator.addInt("dim2_30", util::linearScale(-70.f, 80.f, 0, 30, d2));
38 | generator.addInt("dim3_30", util::linearScale(1.f, 7.f, 0, 30, d3));
39 | generator.addInt("dim4_30", util::linearScale(-40.f, 60.f, 0, 30, d4));
40 |
41 | generator.addInt("dim0_40", util::linearScale(-40.f, 60.f, 0, 40, d0));
42 | generator.addInt("dim1_40", util::linearScale(-40.f, 60.f, 0, 40, d1));
43 | generator.addInt("dim2_40", util::linearScale(-70.f, 80.f, 0, 40, d2));
44 | generator.addInt("dim3_40", util::linearScale(1.f, 7.f, 0, 40, d3));
45 | generator.addInt("dim4_40", util::linearScale(-40.f, 60.f, 0, 40, d4));
46 |
47 | generator.addInt("dim0_50", util::linearScale(-40.f, 60.f, 0, 50, d0));
48 | generator.addInt("dim1_50", util::linearScale(-40.f, 60.f, 0, 50, d1));
49 | generator.addInt("dim2_50", util::linearScale(-70.f, 80.f, 0, 50, d2));
50 | generator.addInt("dim3_50", util::linearScale(1.f, 7.f, 0, 50, d3));
51 | generator.addInt("dim4_50", util::linearScale(-40.f, 60.f, 0, 50, d4));
52 |
53 | generator.execute();
54 | }
55 |
56 | generator.commit();
57 | }
58 |
59 | InMemoryDataGenerator SplomLoader::getInMemoryGenerator(const std::string& path) {
60 | std::vector tokens;
61 |
62 | tokens.emplace_back("dim0_10", "dim0_10", Categorical);
63 | tokens.emplace_back("dim1_10", "dim1_10", Categorical);
64 | tokens.emplace_back("dim2_10", "dim2_10", Categorical);
65 | tokens.emplace_back("dim3_10", "dim3_10", Categorical);
66 | tokens.emplace_back("dim4_10", "dim4_10", Categorical);
67 |
68 | tokens.emplace_back("dim0_20", "dim0_20", Categorical);
69 | tokens.emplace_back("dim1_20", "dim1_20", Categorical);
70 | tokens.emplace_back("dim2_20", "dim2_20", Categorical);
71 | tokens.emplace_back("dim3_20", "dim3_20", Categorical);
72 | tokens.emplace_back("dim4_20", "dim4_20", Categorical);
73 |
74 | tokens.emplace_back("dim0_30", "dim0_30", Categorical);
75 | tokens.emplace_back("dim1_30", "dim1_30", Categorical);
76 | tokens.emplace_back("dim2_30", "dim2_30", Categorical);
77 | tokens.emplace_back("dim3_30", "dim3_30", Categorical);
78 | tokens.emplace_back("dim4_30", "dim4_30", Categorical);
79 |
80 | tokens.emplace_back("dim0_40", "dim0_40", Categorical);
81 | tokens.emplace_back("dim1_40", "dim1_40", Categorical);
82 | tokens.emplace_back("dim2_40", "dim2_40", Categorical);
83 | tokens.emplace_back("dim3_40", "dim3_40", Categorical);
84 | tokens.emplace_back("dim4_40", "dim4_40", Categorical);
85 |
86 | tokens.emplace_back("dim0_50", "dim0_50", Categorical);
87 | tokens.emplace_back("dim1_50", "dim1_50", Categorical);
88 | tokens.emplace_back("dim2_50", "dim2_50", Categorical);
89 | tokens.emplace_back("dim3_50", "dim3_50", Categorical);
90 | tokens.emplace_back("dim4_50", "dim4_50", Categorical);
91 |
92 | return InMemoryDataGenerator(path, tokens);
93 | }
94 |
95 |
--------------------------------------------------------------------------------
/src/SplomLoader.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "Trunc.h"
4 | #include "DataLoader.h"
5 | #include "InMemoryDataGenerator.h"
6 |
7 | class SplomLoader : public DataLoader {
8 | public:
9 | static SplomLoader& getInstance();
10 | virtual void write(const std::string& path) override;
11 |
12 | protected:
13 | virtual InMemoryDataGenerator getInMemoryGenerator(const std::string& path) override;
14 |
15 | private:
16 | inline float randUniform(int min, int max);
17 | inline float randNormal(float mean, float stdev);
18 |
19 | SplomLoader() = default;
20 | ~SplomLoader() = default;
21 |
22 | std::default_random_engine _random_engine;
23 | std::uniform_real_distribution _uniform_dist {0.0, 1.0};
24 | };
25 |
26 | float SplomLoader::randUniform(int min, int max) {
27 | float delta = max - min;
28 | return (float)(min + delta * _uniform_dist(_random_engine));
29 | }
30 |
31 | float SplomLoader::randNormal(float mean, float stdev) {
32 | float x = 0, y = 0, rds, c;
33 | do {
34 | x = (float)(_uniform_dist(_random_engine) * 2 - 1);
35 | y = (float)(_uniform_dist(_random_engine) * 2 - 1);
36 | rds = x * x + y * y;
37 | } while (rds == 0 || rds > 1);
38 | c = (float)sqrt(-2 * log(rds) / rds);
39 | return mean + x * c * stdev;
40 | }
41 |
--------------------------------------------------------------------------------
/src/StringUtil.cpp:
--------------------------------------------------------------------------------
1 | #include "stdafx.h"
2 | #include "StringUtil.h"
3 |
4 | std::vector util::split(const std::string& input, const std::regex& regex) {
5 | static const std::sregex_token_iterator last;
6 | return std::vector{ std::sregex_token_iterator{ input.begin(), input.end(), regex, -1 }, last };
7 | }
8 |
9 | std::vector util::split(const std::string& input, const std::string& str_regex) {
10 | static const std::sregex_token_iterator last;
11 | std::regex regex(str_regex);
12 | return std::vector{ std::sregex_token_iterator{ input.begin(), input.end(), regex, -1 }, last };
13 | }
14 |
15 |
--------------------------------------------------------------------------------
/src/StringUtil.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | namespace util {
4 | std::vector split(const std::string& input, const std::regex& regex);
5 | std::vector split(const std::string& input, const std::string& str_regex);
6 | }
7 |
--------------------------------------------------------------------------------
/src/TemporalDimension.cpp:
--------------------------------------------------------------------------------
1 | #include "stdafx.h"
2 | #include "TemporalDimension.h"
3 | #include "TemporalNode.h"
4 | #include "TemporalPivot.h"
5 |
6 | TemporalDimension::TemporalDimension(const std::string& key, size_t bucketSize)
7 | : Hashing(key), _bucketSize(static_cast(bucketSize)) { }
8 |
9 | bool TemporalDimension::query(const Query& query, const Response& range, Response& response) const {
10 |
11 | if (query.evalTseries(_key)) {
12 | if (query.type == Query::TSERIES) {
13 |
14 | auto& interval = query.getTseries(_key);
15 |
16 | auto node_it = _nodes.begin();
17 | for (auto range_it = range.begin(); range_it != range.end(); ++range_it) {
18 |
19 | nextNode(*range_it, node_it);
20 |
21 | while ((**range_it).endAfter((*node_it)->front())) {
22 |
23 | (*node_it)->queryTseries(interval, response);
24 |
25 | if (++node_it == _nodes.end()) return true;
26 | }
27 | }
28 |
29 | } else if (!query.getTseries(_key).contains(_interval.lower(), _interval.upper())) {
30 |
31 | auto& interval = query.getTseries(_key);
32 |
33 | auto node_it = _nodes.begin();
34 | for (auto range_it = range.begin(); range_it != range.end(); ++range_it) {
35 |
36 | nextNode(*range_it, node_it);
37 |
38 | while ((**range_it).endAfter((*node_it)->front())) {
39 |
40 | (*node_it)->query(interval, response);
41 |
42 | if (++node_it == _nodes.end()) return true;
43 | }
44 | }
45 | } else {
46 | return false;
47 | }
48 | return true;
49 |
50 | } else {
51 | return false;
52 | }
53 | }
54 |
55 | size_t TemporalDimension::hash(const response_container& container, response_container& response, Data& data) {
56 | std::cout << "\tHashing Temporal Dimension: " + _key + "... ";
57 |
58 | data.prepareKey(_key);
59 |
60 | size_t pivots_count = 0;
61 |
62 | for (const auto& ptr : container) {
63 |
64 | if (ptr == nullptr || (*ptr).empty()) continue;
65 |
66 | _nodes.emplace_back(std::make_unique(*ptr));
67 |
68 | pivots_count += _nodes.back()->hash(this, response, data, *ptr);
69 | }
70 | _nodes.shrink_to_fit();
71 |
72 | std::cout << "Done." << std::endl;
73 | data.dispose();
74 |
75 | return pivots_count;
76 | }
77 |
78 | float TemporalDimension::bucketSize() const {
79 | return _bucketSize;
80 | }
81 |
82 | TemporalInterval& TemporalDimension::interval() {
83 | return _interval;
84 | }
85 |
86 | const TemporalInterval& TemporalDimension::interval() const {
87 | return _interval;
88 | }
89 |
90 | unsigned int TemporalDimension::intervalSize() const {
91 | return _interval.days();
92 | }
93 |
94 |
95 |
--------------------------------------------------------------------------------
/src/TemporalDimension.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "Hashing.h"
4 | #include "TemporalNode.h"
5 |
6 | class TemporalDimension : public Hashing {
7 | public:
8 | TemporalDimension(const std::string& key, size_t bucketSize);
9 | TemporalDimension(TemporalDimension&&) = default;
10 | TemporalDimension(const TemporalDimension&) = delete;
11 |
12 | ~TemporalDimension() = default;
13 |
14 | TemporalDimension& operator=(TemporalDimension&&) = default;
15 | TemporalDimension& operator=(const TemporalDimension&) = delete;
16 |
17 | bool query(const Query& query, const Response& range, Response& response) const override;
18 | size_t hash(const response_container& container, response_container& response, Data& data) override;
19 |
20 | float bucketSize() const;
21 | TemporalInterval& interval();
22 | const TemporalInterval& interval() const;
23 |
24 | unsigned int intervalSize() const;
25 |
26 | protected:
27 |
28 | const float _bucketSize;
29 | TemporalInterval _interval;
30 | private:
31 | };
32 |
33 |
--------------------------------------------------------------------------------
/src/TemporalInterval.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | class TemporalInterval {
4 | public:
5 | TemporalInterval() : TemporalInterval(std::numeric_limits::max(), std::numeric_limits::min()) {};
6 | TemporalInterval(temporal_t lower, temporal_t upper) : _bound{lower, upper} {};
7 | virtual ~TemporalInterval() = default;
8 |
9 | inline temporal_t lower() const {
10 | return _bound[0];
11 | }
12 | inline temporal_t upper() const {
13 | return _bound[1];
14 | }
15 |
16 | inline void setLower(temporal_t value) {
17 | _bound[0] = value;
18 | }
19 | inline void setUpper(temporal_t value) {
20 | _bound[1] = value;
21 | }
22 |
23 | inline temporal_t days() const {
24 | return _bound[1] - _bound[0] + 1;
25 | }
26 |
27 | inline bool intersects(size_t lower, size_t upper) const {
28 | return (_bound[0] <= upper) && (_bound[1] >= lower);
29 | }
30 |
31 | inline bool contains(size_t lower, size_t upper) const {
32 | return (_bound[0] <= lower) && (_bound[1] >= upper);
33 | }
34 |
35 | friend std::ostream& operator<< (std::ostream& stream, const TemporalInterval& interval) {
36 | stream << interval.lower() << "/" << interval.upper();
37 | return stream;
38 | }
39 |
40 | protected:
41 | std::array_bound{};
42 | };
43 |
--------------------------------------------------------------------------------
/src/TemporalNode.cpp:
--------------------------------------------------------------------------------
1 | #include "stdafx.h"
2 | #include "TemporalNode.h"
3 |
4 | #include "TemporalDimension.h"
5 |
6 | TemporalNode::TemporalNode(const Pivot& pivot) : _pivot(pivot) { }
7 |
8 | void TemporalNode::query(const TemporalInterval& interval, Response& response) const {
9 | if (interval.contains(lower(), upper())) {
10 | response.addElement(&_pivot);
11 | } else {
12 | queryInterval(interval, response);
13 | }
14 | }
15 |
16 | void TemporalNode::queryTseries(const TemporalInterval& interval, Response& response) const {
17 | if (interval.contains(lower(), upper())) {
18 | response.insert(_container.begin(), _container.end());
19 | } else {
20 | queryInterval(interval, response);
21 | }
22 | }
23 |
24 | void TemporalNode::queryInterval(const TemporalInterval& interval, Response& response) const {
25 | if (!interval.intersects(lower(), upper())) return;
26 |
27 | auto lower = std::lower_bound(_container.begin(), _container.end(), interval.lower(),
28 | [](const TemporalPivot& o1, const temporal_t& o2) { return o2 > o1.value(); }
29 | );
30 |
31 | auto upper = std::lower_bound(lower, _container.end(), interval.upper(),
32 | [](const TemporalPivot& o1, const temporal_t& o2) { return o2 > o1.value(); }
33 | );
34 |
35 | response.insert(lower, upper);
36 | }
37 |
38 | size_t TemporalNode::hash(const TemporalDimension* hashing, response_container& response, Data& data, const Pivot& pivot) {
39 |
40 | std::map map{};
41 |
42 | const float bucketSize = ((TemporalDimension*)hashing)->bucketSize();
43 |
44 | for (auto i = pivot.front(); i < pivot.back(); ++i) {
45 |
46 | ulong value = std::floor(data.getIntProperty(i) / bucketSize) * bucketSize;
47 |
48 | // update TemporalInterval
49 | auto& interval = ((TemporalDimension*)hashing)->interval();
50 | if (value > interval.upper()) interval.setUpper(value);
51 | if (value < interval.lower()) interval.setLower(value);
52 |
53 | map[value]++;
54 |
55 | data.setHash(i, value);
56 | }
57 |
58 | int accum = pivot.front();
59 | for (auto entry : map) {
60 |
61 | int first = accum;
62 | accum += entry.second;
63 | int second = accum;
64 |
65 | _container.emplace_back(first, second, entry.first);
66 | }
67 | _container.shrink_to_fit();
68 |
69 | for (auto& ptr : _container) {
70 | response.emplace_back(&ptr);
71 | }
72 |
73 | data.sortHash(pivot.front(), pivot.back());
74 |
75 | return _container.size();
76 | }
77 |
78 |
79 |
80 |
81 |
--------------------------------------------------------------------------------
/src/TemporalNode.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "TemporalPivot.h"
4 |
5 | #include "Data.h"
6 | #include "Query.h"
7 | #include "Response.h"
8 |
9 | class TemporalDimension;
10 |
11 | class TemporalNode {
12 | public:
13 | TemporalNode(const Pivot& pivot);
14 | TemporalNode(TemporalNode&&) = default;
15 | TemporalNode(const TemporalNode&) = delete;
16 |
17 | ~TemporalNode() = default;
18 |
19 | TemporalNode& operator=(TemporalNode&&) = default;
20 | TemporalNode& operator=(const TemporalNode&) = delete;
21 |
22 | void query(const TemporalInterval& interval, Response& response) const;
23 | void queryTseries(const TemporalInterval& interval, Response& response) const;
24 |
25 | size_t hash(const TemporalDimension* hashing, response_container& response, Data& data, const Pivot& pivot);
26 |
27 | inline ulong lower() const;
28 | inline ulong upper() const;
29 |
30 | inline const ulong front() const;
31 | inline const ulong back() const;
32 |
33 | protected:
34 | void queryInterval(const TemporalInterval& interval, Response& response) const;
35 |
36 | Pivot _pivot;
37 | std::vector _container;
38 | };
39 |
40 | const ulong TemporalNode::front() const {
41 | return _pivot.front();
42 | }
43 |
44 | const ulong TemporalNode::back() const {
45 | return _pivot.back();
46 | }
47 |
48 | ulong TemporalNode::lower() const {
49 | return _container.front().value();
50 | }
51 |
52 | ulong TemporalNode::upper() const {
53 | return _container.back().value();
54 | }
55 |
--------------------------------------------------------------------------------
/src/TemporalPivot.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "Pivot.h"
4 | #include "TemporalInterval.h"
5 |
6 | class TemporalPivot : public Pivot {
7 | public:
8 | TemporalPivot(ulong first, ulong second, const temporal_t& value) : Pivot(first, second), _value(value) { }
9 | TemporalPivot(const Pivot& pivot, const temporal_t& value) : Pivot(pivot), _value(value) { }
10 | ~TemporalPivot() = default;
11 |
12 | inline const temporal_t& value() const;
13 |
14 | protected:
15 | temporal_t _value;
16 | };
17 |
18 | const temporal_t& TemporalPivot::value() const {
19 | return _value;
20 | }
21 |
--------------------------------------------------------------------------------
/src/TemporalSerializer.cpp:
--------------------------------------------------------------------------------
1 | #include "stdafx.h"
2 | #include "TemporalSerializer.h"
3 | #include "TemporalPivot.h"
4 | #include "TemporalDimension.h"
5 |
6 | TemporalSerializer& TemporalSerializer::getInstance() {
7 | static TemporalSerializer instance;
8 | return instance;
9 | }
10 |
11 | std::string TemporalSerializer::serialize(const TemporalDimension* hashing, const Response& response, std::chrono::milliseconds& duration) {
12 |
13 | std::chrono::time_point start, end;
14 | start = std::chrono::high_resolution_clock::now();
15 |
16 | std::vector aggregate(bins, 0);
17 |
18 | rapidjson::StringBuffer buffer;
19 | rapidjson::Writer writer(buffer);
20 |
21 | for (const auto& pivot : response.container()) {
22 | size_t index = util::linearScale(hashing->interval().lower(), hashing->interval().upper(), 0, bins - 1, ((TemporalPivot*)pivot)->value());
23 | aggregate[index] += pivot->size();
24 | }
25 |
26 | end = std::chrono::high_resolution_clock::now();
27 | duration = std::chrono::duration_cast(end - start);
28 |
29 | writer.StartArray();
30 | for (ulong i = 0; i < aggregate.size(); ++i) {
31 | if (aggregate[i] == 0) continue;
32 | writer.StartArray();
33 | writer.Uint((i * (hashing->interval().days() / bins)) + hashing->interval().lower());
34 | writer.Uint(aggregate[i]);
35 | writer.EndArray();
36 | }
37 | writer.EndArray();
38 | return buffer.GetString();
39 | }
40 |
41 | std::string TemporalSerializer::serialize(const TemporalDimension* hashing, const std::pair& tuple, std::chrono::milliseconds& duration) {
42 |
43 | std::chrono::time_point start, end;
44 | start = std::chrono::high_resolution_clock::now();
45 |
46 | std::vector aggregate(bins, 0);
47 |
48 | rapidjson::StringBuffer buffer;
49 | rapidjson::Writer writer(buffer);
50 |
51 | auto it = tuple.second.begin();
52 | for (const auto& pivot : tuple.first.container()) {
53 | int size = 0;
54 |
55 | while (it != tuple.second.end() && (*pivot) > (**it)) {
56 | size += (**it).size();
57 | it++;
58 | }
59 |
60 | size_t index = util::linearScale(hashing->interval().lower(), hashing->interval().upper(), 0, bins - 1, ((TemporalPivot*)pivot)->value());
61 | aggregate[index] += size;
62 | }
63 |
64 | end = std::chrono::high_resolution_clock::now();
65 | duration = std::chrono::duration_cast(end - start);
66 |
67 | writer.StartArray();
68 | for (ulong i = 0; i < aggregate.size(); ++i) {
69 | if (aggregate[i] == 0) continue;
70 | writer.StartArray();
71 | writer.Uint((i * (hashing->interval().days() / bins)) + hashing->interval().lower());
72 | writer.Uint(aggregate[i]);
73 | writer.EndArray();
74 | }
75 | writer.EndArray();
76 | return buffer.GetString();
77 | }
78 |
--------------------------------------------------------------------------------
/src/TemporalSerializer.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "Serializer.h"
4 | #include "Response.h"
5 |
6 | class TemporalDimension;
7 |
8 | class TemporalSerializer : public Serializer {
9 | public:
10 |
11 | static TemporalSerializer& getInstance();
12 |
13 | std::string serialize(const TemporalDimension* hashing, const Response& response, std::chrono::milliseconds& duration) override;
14 | std::string serialize(const TemporalDimension* hashing, const std::pair& tuple, std::chrono::milliseconds& duration) override;
15 |
16 | static const ulong bins { 256 };
17 | };
18 |
--------------------------------------------------------------------------------
/src/TileNode.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "Types.h"
4 | #include "TilePivot.h"
5 |
6 | #include "Data.h"
7 | #include "Query.h"
8 | #include "Response.h"
9 |
10 | class SpatialDimension;
11 |
12 | class TileNode {
13 | public:
14 | TileNode(const TilePivot& pivot);
15 | TileNode(const Pivot& pivot, const tile_t& value);
16 |
17 | TileNode(TileNode&&) = default;
18 | TileNode(const TileNode&) = delete;
19 |
20 | ~TileNode() = default;
21 |
22 | TileNode& operator=(TileNode&&) = default;
23 | TileNode& operator=(const TileNode&) = delete;
24 |
25 | void queryTile(const SpatialDimension* hashing, const Query& query, Response& response, ulong level) const;
26 | void queryRegion(const SpatialDimension* hashing, const Query& query, Response& response, ulong level) const;
27 |
28 | size_t hash(const SpatialDimension* hashing, response_container& response, Data& data);
29 |
30 | inline const ulong front() const;
31 | inline const ulong back() const;
32 |
33 | private:
34 | struct zoom_level {
35 | zoom_level() : first(0), second(0), z(0) {}
36 | ulong first, second, z;
37 | };
38 |
39 | void aggregateTile(const SpatialDimension* hashing, const Query& query, Response& response, ulong level) const;
40 |
41 | inline ulong getIndex(ulong x, ulong y) const;
42 |
43 | inline bool last() const;
44 | inline void setLast();
45 |
46 | size_t hashSingle(const SpatialDimension* hashing, Data& data, response_container& response, ulong zoom);
47 | size_t hashMultiple(const SpatialDimension* hashing, Data& data, response_container& response, std::vector zoom, ulong level);
48 |
49 | TilePivot _pivot;
50 | std::array, 4> _container{};
51 | };
52 |
53 | ulong TileNode::getIndex(ulong x, ulong y) const {
54 | if (x % 2 == 0) {
55 | if (y % 2 == 0) return 0;
56 | else return 1;
57 | } else {
58 | if (y % 2 == 0) return 2;
59 | else return 3;
60 | }
61 | }
62 |
63 | bool TileNode::last() const {
64 | return _pivot.last();
65 | }
66 |
67 | void TileNode::setLast() {
68 | _pivot.setLast();
69 | }
70 |
71 | const ulong TileNode::front() const {
72 | return _pivot.front();
73 | }
74 |
75 | const ulong TileNode::back() const {
76 | return _pivot.back();
77 | }
--------------------------------------------------------------------------------
/src/TilePivot.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "Types.h"
4 | #include "Pivot.h"
5 |
6 | class TilePivot : public Pivot {
7 | public:
8 | TilePivot() = default;
9 |
10 | TilePivot(ulong first, ulong second, const tile_t& value) : Pivot(first, second), _value(value) { }
11 | TilePivot(const Pivot& pivot, const tile_t& value) : Pivot(pivot), _value(value) { }
12 | ~TilePivot() = default;
13 |
14 | inline const tile_t& value() const;
15 |
16 | inline bool last() const;
17 | inline void setLast();
18 |
19 | protected:
20 |
21 | tile_t _value;
22 | };
23 |
24 | const tile_t& TilePivot::value() const {
25 | return _value;
26 | }
27 |
28 | bool TilePivot::last() const {
29 | return _value.l == 1;
30 | }
31 |
32 | void TilePivot::setLast() {
33 | _value.l = 1;
34 | }
35 |
--------------------------------------------------------------------------------
/src/TripLoader.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "DataLoader.h"
4 | #include "InMemoryDataGenerator.h"
5 |
6 | class TripLoader : public DataLoader {
7 | public:
8 | static TripLoader& getInstance();
9 | virtual void write(const std::string& path) override;
10 |
11 | protected:
12 | virtual InMemoryDataGenerator getInMemoryGenerator(const std::string& path) override;
13 |
14 | private:
15 | TripLoader() = default;
16 | ~TripLoader() = default;
17 | };
18 |
--------------------------------------------------------------------------------
/src/Trunc.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | namespace util {
4 | inline double trunc(double d) {
5 | return std::trunc(d * 100000.0) / 100000.0;
6 | }
7 |
8 | inline int linearScale(float min, float max, float a, float b, float x) {
9 | return std::floor((((b - a) * (x - min)) / (max - min)) + a);
10 | //return value >= b ? (b - 1) : (value < a ? a : value);
11 | }
12 | } // namespace util
--------------------------------------------------------------------------------
/src/Types.cpp:
--------------------------------------------------------------------------------
1 | #include "stdafx.h"
2 | #include "Types.h"
3 | #include "Mercator.h"
4 |
5 | Tile::Tile(int _x, int _y, ulong _z) : Tile::Tile((ulong)_x, (ulong)_y, _z) {}
6 |
7 | Tile::Tile(ulong _x, ulong _y, ulong _z) : x(_x), y(_y), z(_z) {
8 | lat0 = util::tiley2lat(y, z);
9 | lon0 = util::tilex2lon(x, z);
10 |
11 | lat1 = util::tiley2lat(y + 1, z);
12 | lon1 = util::tilex2lon(x + 1, z);
13 | }
14 |
15 | TileBounds::TileBounds(ulong _x0, ulong _y0, ulong _x1, ulong _y1, ulong _z)
16 | : x0(_x0), y0(_y0), x1(_x1), y1(_y1), z(_z) {
17 |
18 | lat0 = util::tiley2lat(y0, z);
19 | lon0 = util::tilex2lon(x0, z);
20 |
21 | lat1 = util::tiley2lat(y1 + 1, z);
22 | lon1 = util::tilex2lon(x1 + 1, z);
23 | }
24 |
--------------------------------------------------------------------------------
/src/Types.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | template
4 | struct data_container {
5 | typedef std::vector result;
6 | };
7 |
8 | typedef unsigned long ulong;
9 |
10 | typedef unsigned char categorical_t;
11 |
12 | typedef unsigned long temporal_t;
13 |
14 | enum DimensionType {
15 | Spatial,
16 | Categorical,
17 | Temporal
18 | };
19 |
20 | struct tile_t {
21 | tile_t() : x(0), y(0), z(0), l(0) {}
22 | tile_t(uint32_t _x, uint32_t _y, uint8_t _z, uint8_t _l = 0) : x(_x), y(_y), z(_z), l(_l) {}
23 |
24 | inline bool operator ==(const tile_t &other) const {
25 | return (z == other.z && x == other.x && y == other.y);
26 | }
27 |
28 | uint64_t x : 29;
29 | uint64_t y : 29;
30 | uint64_t z : 5;
31 | uint64_t l : 1;
32 |
33 | friend std::ostream& operator<< (std::ostream& stream, const tile_t& tile) {
34 | stream << tile.x << "/" << tile.y << "/" << tile.z;
35 | return stream;
36 | }
37 | };
38 |
39 | namespace std {
40 | template <> struct hash {
41 | std::size_t operator()(const tile_t k) const {
42 | return (k.x * ((2 << k.z) - 1)) + k.y;
43 | }
44 | };
45 | }
46 |
47 | struct Tile {
48 | Tile() = default;
49 | Tile(int _x, int _y, ulong _z);
50 | Tile(ulong _x, ulong _y, ulong _z);
51 |
52 | int z { -1};
53 | ulong x, y;
54 | float lat0, lon0, lat1, lon1;
55 |
56 | inline bool isValid() const {
57 | return z != -1;
58 | }
59 |
60 | inline bool operator ==(const tile_t &tile) const {
61 | return z == tile.z && x == tile.x && y == tile.y;
62 | }
63 |
64 | friend std::ostream& operator<< (std::ostream& stream, const Tile& tile) {
65 | stream << tile.x << "/" << tile.y << "/" << tile.z;
66 | return stream;
67 | }
68 | };
69 |
70 | struct TileBounds {
71 | TileBounds() = default;
72 | TileBounds(ulong _x0, ulong _y0, ulong _x1, ulong _y1, ulong _z);
73 |
74 | int z{ -1 };
75 | ulong x0, y0, x1, y1;
76 | float lat0, lon0, lat1, lon1;
77 |
78 | inline bool isValid() const {
79 | return z != -1;
80 | }
81 |
82 | friend std::ostream& operator<< (std::ostream& stream, const TileBounds& tile) {
83 | stream << tile.x0 << "/" << tile.y0 << "/" << tile.x1 << "/" << tile.y1;
84 | return stream;
85 | }
86 | };
87 |
88 | struct LatLon {
89 | LatLon(double _lat, double _lon) : lat(_lat), lon(_lon) {}
90 | double lat, lon;
91 | };
92 |
93 | struct LatLngBounds {
94 | LatLngBounds(LatLon _latlon0, LatLon _latlon1) : latlon0(_latlon0), latlon1(_latlon1) {}
95 | LatLon latlon0, latlon1;
96 | };
97 |
98 | struct Schema {
99 | std::string name, path, loader;
100 |
101 | float fraction { 1.f };
102 | ulong leaf { 32 };
103 | ulong sql_threshold { 250 };
104 |
105 | std::vector spatial;
106 | std::vector> categorical;
107 | std::vector> temporal;
108 | };
109 |
110 |
111 |
112 |
--------------------------------------------------------------------------------
/src/stdafx.cpp:
--------------------------------------------------------------------------------
1 | // stdafx.cpp : source file that includes just the standard includes
2 | // cpp-hashedcubes.pch will be the pre-compiled header
3 | // stdafx.obj will contain the pre-compiled type information
4 |
5 | #include "stdafx.h"
6 |
7 | // TODO: reference any additional headers you need in STDAFX.H
8 | // and not in this file
9 |
--------------------------------------------------------------------------------
/src/stdafx.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #define NOMINMAX
4 | #define _CRT_SECURE_NO_WARNINGS
5 |
6 | #pragma warning( disable : 4250)
7 | #define _SILENCE_STDEXT_HASH_DEPRECATION_WARNINGS
8 |
9 | // stl
10 | #include
11 | #include
12 | #include
13 |
14 | #include
15 | #include
16 | #include
17 | #include