-- ----------------------------------------------------------------
-- Regression tests for explicit threshold control.
-- ----------------------------------------------------------------

SELECT hll_set_output_version(1);

-- Should become explicit.
SELECT hll_add(E'\\x118c49'::hll, hll_hash_integer(1,0));

-- Also explicit.
SELECT hll_add(hll_empty(12,5,256,1), hll_hash_integer(1,0));

-- ----------------

-- Should go straight to sparse.
SELECT hll_add(hll_empty(12,5,0,1),
           hll_hash_integer(1,0));

-- Should stay sparse.
SELECT hll_add(
       hll_add(hll_empty(12,5,0,1),
           hll_hash_integer(1,0)),
           hll_hash_integer(2,0));

-- ----------------

-- Should stay explicit for one add.
SELECT hll_add(hll_empty(12,5,1,1),
           hll_hash_integer(1,0));

-- But not on the second add.
SELECT hll_add(
       hll_add(hll_empty(12,5,1,1),
           hll_hash_integer(1,0)),
           hll_hash_integer(2,0));

-- Nor the third.
SELECT hll_add(
       hll_add(
       hll_add(hll_empty(12,5,1,1),
           hll_hash_integer(1,0)),
           hll_hash_integer(2,0)),
           hll_hash_integer(3,0));

-- ----------------

-- Should stay explicit for two adds.
SELECT hll_add(hll_empty(12,5,2,1),
           hll_hash_integer(1,0));

SELECT hll_add(
       hll_add(hll_empty(12,5,2,1),
           hll_hash_integer(1,0)),
           hll_hash_integer(2,0));

-- Not explicit anymore.
SELECT hll_add(
       hll_add(
       hll_add(hll_empty(12,5,2,1),
           hll_hash_integer(1,0)),
           hll_hash_integer(2,0)),
           hll_hash_integer(3,0));

-- ----------------

-- Should stay explicit for four adds.
SELECT hll_add(hll_empty(12,5,4,1),
           hll_hash_integer(1,0));

SELECT hll_add(
       hll_add(hll_empty(12,5,4,1),
           hll_hash_integer(1,0)),
           hll_hash_integer(2,0));

SELECT hll_add(
       hll_add(
       hll_add(hll_empty(12,5,4,1),
           hll_hash_integer(1,0)),
           hll_hash_integer(2,0)),
           hll_hash_integer(3,0));

SELECT hll_add(
       hll_add(
       hll_add(
       hll_add(hll_empty(12,5,4,1),
           hll_hash_integer(1,0)),
           hll_hash_integer(2,0)),
           hll_hash_integer(3,0)),
           hll_hash_integer(4,0));

-- Not anymore.
SELECT hll_add(
       hll_add(
       hll_add(
       hll_add(
       hll_add(hll_empty(12,5,4,1),
           hll_hash_integer(1,0)),
           hll_hash_integer(2,0)),
           hll_hash_integer(3,0)),
           hll_hash_integer(4,0)),
           hll_hash_integer(5,0));

-- ----------------------------------------------------------------

-- Should stay explicit.
SELECT E'\\x128C09810F076F2EFC7D5781A8E923DD4D727381F60023440AC8F3826E20FD0E1C755783418A43C9E2536983D2657BAECEC77085B2C833BF06C38B85EC2FB805FEB9C08A577647206737E98B67F1909C4FBA238C8826ECCD18A1328CB8A65A27F9A2E58E332D3E1C1E8B018E53D45009306837913A1E408B1D83BE927DA34AE676FD6893BCD79BF47657EB957033B0E2A1F9EF96191BCB8D84D1D4967B18FF84CF372697034327A4CA49DE97688D9A869A43E097A62AAE1CE1D2D59839BEC0D573CC36993FFAAC3DD9DCAE9A1713EF73725EDB9A9EACDD27AC70F69B2F47DFF8D609AE9B7A4FEC37666D559BF0AB70FDA186F89DF0868CB5304B979DFD45C697433E799F94C56130B117AFA161FD0F8E175DABA16236AF4726E653A195A90A5F74A02AA3330817521EEDFBA3507CEC7C8EFFEEA4DDFD7A022356FAA708B69996145FD2A7B975333A92C45DA7F504C22BBD8883A8AD40BD99DD3136A8EEBA810AD4107CA97A88A733A3635EAAC55193F00B6ABEAB770C1E27FE3A96AD16681AD304ED0FAE103F67A4732B8FAE78848FA95BB4F0AFB9EA12A8A60235B0F42EFD18F185B4B10788ABF2A627C5B1E81C4F73418369B2347427BE5DBA99B2F219105C2C8EF9B4F4AAD6DAA3018BB500D980CEE8DEBEB52629581B1E9F38B54991A7EE2ADA3DB5E83A5EF27FA458B676ED1B4AD57B1BB72FC20093D243C3B7A270C97E9F60B1B81558085FA73AF4B92EE2526D66F7A9B947C25F6AA0B1C3BAD5BD98CA753A7CBB1AD57319B89CD8BE4D78B4EA777902BE67281D8C16DFB3BE75C448B47B885BBE8724958A2DD547C1307F3E3DC82B19C31B272386EBD3D5C38570F6A6B16AAFC389BD7042E65615C541D6E99556AD8DC64C7451D5E4A410C6E8E17A0B8565C1C72586EF2CA395AFC727BFDF07262E4FC806DD068E0D83DFC95F393EE574D488CA08660086D78399CDB9F2FDBD2C68A3CE23684A013E0402CE9C8E990D340AD0CF54F0AA63651486D0D651B83055D98FD1D6B47BFAE04129D2F0690082673069D466A4F678408E51D618BCBB1713D866D9820F495DE4B9B2DB6CAD89234C26B9DCC981DD4C9389A1E05E8BB7D36479F5E15F18764DE26865E16EEA095E95B9D6E301AEBCD7FB18E9E3D10F4B6322D8EBE6E47D0415918BC6E843946AFF559A84E8DA7FF35746346DEB978C5E6478F1EFEDCBFA7EE0C17F12EDD9AB37B9A86FDBEFE49DA97CB1C23BF022C44555C715F6F09B04B38DD7AEE4F22C88BD8D437311F27B5DB0E9340CFCF57471D55DBD1460F660CDAB03F03B06F6B55BBA28DA1B7EF75C6B35F73E591BF7BED9D4B5F30868F816C1F65ECBE466F94D2F8F21555B84FBACA654EDD11944FBFC9419F653B5F3FCB2B9C023BDBB04FF1C2921C7C365D1FFBD34EDA309EBA8FFCA7C3CF7CD7EFA0149546ADA2D4A210190E5722719B812023E1F61A788768802BC36ABAEFB97D8060A8F1F743E41B70643CE33D5392E620732E58C48B4D31207960AD1274EEC3C07A0D2BAFBC4365507B297476AEA276C0823D06F731E8CEC0849965B6A8A6D0B09CFCA9645744B6F0ACC38CA90A4D6950B30199E6FBA2E590D64E5396A4AC48C0D978892127108BD0FD8CBD2A1668FF10FFF3E568ECFA66110BDDBC4CC046AEB12B1D54A424D4E8612F4CE0A47E70565130958F67D24CBFF15B0439A464B33C71849E2AEE12079F019893C0C103E358E1C3AE416CC2D17901C490FFF8BDF2A0D1DA44FA4DBE9B4E31DB004FA8A0CEBCC1EADC56CFDEBFC791FA8EADDA7813B5D21328CC6AD76D9B12156396BA820C494219447B20A81CDAB23C77CB6E11760A5245B99B846685CFB273B251498B9637A27D40052777179E828209046C2FD1CE6285A7ADF6C9BDC52293A22A87C7B822429C1271B6FFAEEE02AE7D5475682E8792C32B6A13E130F7E2CFACDAD91AF54BC2D5FC77A0AC38F852D9500937CCDC8C02DBCD0FAFAC582322F48F6FC00551A97325A3CBC4186C4B53462FEEF714A0E44347536F04629644834ECBFF843E13794352CCCFC0946B8F0353E0B46E91ADDFC35A150F45BE711D637B4C5D368130F6A397DAC5A505F4A38399B1127B3186EEF3A6716B6650B37A43AAAF949857A41BB3BB019028551C8493C067E67A65FE8523D36145A51288B1B3E05CF2AB6FF496C3ED4466534CE7F0E3F19AE90B58263303F9CF5B2E040E3CD40136A78605D79B84141BECDB31896FD43E73111AE07DA894433E27F945114A945737AA1DCFE7648471C7A3075A27BFF47AE2F865A746FF549C0F7D5C58DAD7D4AC6A258049BD6E64B4752645E76F39E4DA9780D75AF0A6B4DD1665B6856D4F84E75A7D7BECC1DF94EDF2D538BCC83F950B87C338B76F32F50BF8C06E0FE08FE50DFF83F87E1D33B510EC2A8DC498C4551D864D5E42B8A76529A72B2DBDE8F4B552CF1E4A8AB85DD55677ABC4A6D6CC05674E0EAC7181CFD58F6F13D28CA7A365956D8037CB505725958C47B349399765998A979DF2DDFB85A9429AB90400CD25D84AD4C134DE91E5E7F961E93A35FF45EA819B7306D3C885F377E4255EDABB25FE907945CE6C0A16034F743F87AA74260D1D9429FBCAA0860ED6DD80CC3E3CB6383C322196D1EC464FF526FD87CE3E765AD3780E9F97898668AEA231012C91268FB0E6F684DF9926C58FAFCA44F68D16D2B5F0F78EB98D66D7DC0B998C0780F6DC4CCC1230752666E98008FF328B47571765F290D2BB87E71C7E89C4494F41271D144CC0032659B71DE0513743DE1B971F76602BFC11BCF73754B1443CE1E1E74124CCF336150F8752BD6E456B21CC7769E177BE0E0B66F76BE1268218DAE37784EE11732089EF97A8A8099020BE0747B528BF8134C9D4F7B5B54D144123AEB7DCFBF351DDE1AE2'::hll(12,5,256,0);

-- Should become sparse
SELECT hll_add(E'\\x128C49810F076F2EFC7D5781A8E923DD4D727381F60023440AC8F3826E20FD0E1C755783418A43C9E2536983D2657BAECEC77085B2C833BF06C38B85EC2FB805FEB9C08A577647206737E98B67F1909C4FBA238C8826ECCD18A1328CB8A65A27F9A2E58E332D3E1C1E8B018E53D45009306837913A1E408B1D83BE927DA34AE676FD6893BCD79BF47657EB957033B0E2A1F9EF96191BCB8D84D1D4967B18FF84CF372697034327A4CA49DE97688D9A869A43E097A62AAE1CE1D2D59839BEC0D573CC36993FFAAC3DD9DCAE9A1713EF73725EDB9A9EACDD27AC70F69B2F47DFF8D609AE9B7A4FEC37666D559BF0AB70FDA186F89DF0868CB5304B979DFD45C697433E799F94C56130B117AFA161FD0F8E175DABA16236AF4726E653A195A90A5F74A02AA3330817521EEDFBA3507CEC7C8EFFEEA4DDFD7A022356FAA708B69996145FD2A7B975333A92C45DA7F504C22BBD8883A8AD40BD99DD3136A8EEBA810AD4107CA97A88A733A3635EAAC55193F00B6ABEAB770C1E27FE3A96AD16681AD304ED0FAE103F67A4732B8FAE78848FA95BB4F0AFB9EA12A8A60235B0F42EFD18F185B4B10788ABF2A627C5B1E81C4F73418369B2347427BE5DBA99B2F219105C2C8EF9B4F4AAD6DAA3018BB500D980CEE8DEBEB52629581B1E9F38B54991A7EE2ADA3DB5E83A5EF27FA458B676ED1B4AD57B1BB72FC20093D243C3B7A270C97E9F60B1B81558085FA73AF4B92EE2526D66F7A9B947C25F6AA0B1C3BAD5BD98CA753A7CBB1AD57319B89CD8BE4D78B4EA777902BE67281D8C16DFB3BE75C448B47B885BBE8724958A2DD547C1307F3E3DC82B19C31B272386EBD3D5C38570F6A6B16AAFC389BD7042E65615C541D6E99556AD8DC64C7451D5E4A410C6E8E17A0B8565C1C72586EF2CA395AFC727BFDF07262E4FC806DD068E0D83DFC95F393EE574D488CA08660086D78399CDB9F2FDBD2C68A3CE23684A013E0402CE9C8E990D340AD0CF54F0AA63651486D0D651B83055D98FD1D6B47BFAE04129D2F0690082673069D466A4F678408E51D618BCBB1713D866D9820F495DE4B9B2DB6CAD89234C26B9DCC981DD4C9389A1E05E8BB7D36479F5E15F18764DE26865E16EEA095E95B9D6E301AEBCD7FB18E9E3D10F4B6322D8EBE6E47D0415918BC6E843946AFF559A84E8DA7FF35746346DEB978C5E6478F1EFEDCBFA7EE0C17F12EDD9AB37B9A86FDBEFE49DA97CB1C23BF022C44555C715F6F09B04B38DD7AEE4F22C88BD8D437311F27B5DB0E9340CFCF57471D55DBD1460F660CDAB03F03B06F6B55BBA28DA1B7EF75C6B35F73E591BF7BED9D4B5F30868F816C1F65ECBE466F94D2F8F21555B84FBACA654EDD11944FBFC9419F653B5F3FCB2B9C023BDBB04FF1C2921C7C365D1FFBD34EDA309EBA8FFCA7C3CF7CD7EFA0149546ADA2D4A210190E5722719B812023E1F61A788768802BC36ABAEFB97D8060A8F1F743E41B70643CE33D5392E620732E58C48B4D31207960AD1274EEC3C07A0D2BAFBC4365507B297476AEA276C0823D06F731E8CEC0849965B6A8A6D0B09CFCA9645744B6F0ACC38CA90A4D6950B30199E6FBA2E590D64E5396A4AC48C0D978892127108BD0FD8CBD2A1668FF10FFF3E568ECFA66110BDDBC4CC046AEB12B1D54A424D4E8612F4CE0A47E70565130958F67D24CBFF15B0439A464B33C71849E2AEE12079F019893C0C103E358E1C3AE416CC2D17901C490FFF8BDF2A0D1DA44FA4DBE9B4E31DB004FA8A0CEBCC1EADC56CFDEBFC791FA8EADDA7813B5D21328CC6AD76D9B12156396BA820C494219447B20A81CDAB23C77CB6E11760A5245B99B846685CFB273B251498B9637A27D40052777179E828209046C2FD1CE6285A7ADF6C9BDC52293A22A87C7B822429C1271B6FFAEEE02AE7D5475682E8792C32B6A13E130F7E2CFACDAD91AF54BC2D5FC77A0AC38F852D9500937CCDC8C02DBCD0FAFAC582322F48F6FC00551A97325A3CBC4186C4B53462FEEF714A0E44347536F04629644834ECBFF843E13794352CCCFC0946B8F0353E0B46E91ADDFC35A150F45BE711D637B4C5D368130F6A397DAC5A505F4A38399B1127B3186EEF3A6716B6650B37A43AAAF949857A41BB3BB019028551C8493C067E67A65FE8523D36145A51288B1B3E05CF2AB6FF496C3ED4466534CE7F0E3F19AE90B58263303F9CF5B2E040E3CD40136A78605D79B84141BECDB31896FD43E73111AE07DA894433E27F945114A945737AA1DCFE7648471C7A3075A27BFF47AE2F865A746FF549C0F7D5C58DAD7D4AC6A258049BD6E64B4752645E76F39E4DA9780D75AF0A6B4DD1665B6856D4F84E75A7D7BECC1DF94EDF2D538BCC83F950B87C338B76F32F50BF8C06E0FE08FE50DFF83F87E1D33B510EC2A8DC498C4551D864D5E42B8A76529A72B2DBDE8F4B552CF1E4A8AB85DD55677ABC4A6D6CC05674E0EAC7181CFD58F6F13D28CA7A365956D8037CB505725958C47B349399765998A979DF2DDFB85A9429AB90400CD25D84AD4C134DE91E5E7F961E93A35FF45EA819B7306D3C885F377E4255EDABB25FE907945CE6C0A16034F743F87AA74260D1D9429FBCAA0860ED6DD80CC3E3CB6383C322196D1EC464FF526FD87CE3E765AD3780E9F97898668AEA231012C91268FB0E6F684DF9926C58FAFCA44F68D16D2B5F0F78EB98D66D7DC0B998C0780F6DC4CCC1230752666E98008FF328B47571765F290D2BB87E71C7E89C4494F41271D144CC0032659B71DE0513743DE1B971F76602BFC11BCF73754B1443CE1E1E74124CCF336150F8752BD6E456B21CC7769E177BE0E0B66F76BE1268218DAE37784EE11732089EF97A8A8099020BE0747B528BF8134C9D4F7B5B54D144123AEB7DCFBF351DDE1AE2'::hll(12,5,256,1),
hll_hash_integer(1,0));

-- ----------------------------------------------------------------
-- Test auto explicit threshold values.
-- ----------------------------------------------------------------

-- ((((2^12 * 5) + 7) / 8) / 8) = 320
SELECT hll_print(hll_empty(12,5,-1,1));

-- ((((2^10 * 5) + 7) / 8) / 8) = 80
SELECT hll_print(hll_empty(10,5,-1,1));

-- ((((2^10 * 4) + 7) / 8) / 8) = 64
SELECT hll_print(hll_empty(10,4,-1,1));

-- ((((2^10 * 3) + 7) / 8) / 8) = 48
SELECT hll_print(hll_empty(10,3,-1,1));

-- ((((2^2 * 5) + 7) / 8) / 8) = 0
SELECT hll_print(hll_empty(2,5,-1,1));

-- ((((2^4 * 5) + 7) / 8) / 8) = 1
SELECT hll_print(hll_empty(4,5,-1,1));

-- ((((2^4 * 4) + 7) / 8) / 8) = 1
SELECT hll_print(hll_empty(4,4,-1,1));

-- ----------------------------------------------------------------
-- Test auto explicit threshold action.
-- ----------------------------------------------------------------

-- Should have auto-explicit value of 2.
-- ((((2^5 * 5) + 7) / 8) / 8) = 2
SELECT hll_print(hll_empty(5,5,-1,1));

-- Empty
SELECT hll_empty(5,5,-1,1);

-- Explicit
SELECT hll_add(
           hll_empty(5,5,-1,1), 
               hll_hash_integer(1,0));

-- Explicit
SELECT hll_add(
       hll_add(
           hll_empty(5,5,-1,1), 
               hll_hash_integer(1,0)),
               hll_hash_integer(2,0));

-- Now Sparse
SELECT hll_add(
       hll_add(
       hll_add(
           hll_empty(5,5,-1,1), 
               hll_hash_integer(1,0)),
               hll_hash_integer(2,0)),
               hll_hash_integer(3,0));
