Ola Svensson

181 papers A* 50A 6B 10C 2Journal 101Unranked 12
YearRankTypeTitle / Venue / Authors
2026 J jnl
CoRR
Vincent Cohen-Addad, Marina Drygala, Nathan Klein, Ola Svensson
2026 J jnl
CoRR
David P. Woodruff, Vincent Cohen-Addad, Lalit Jain, Jieming Mao, Song Zuo, MohammadHossein Bateni, Simina Brânzei, Michael P. Brenner, Lin Chen, Ying Feng, Lance Fortnow, Gang Fu, Ziyi Guan, Zahra Hadizadeh, Mohammad T. Hajiaghayi, Mahdi JafariRaviz, Adel Javanmard, Karthik C. S., Ken-ichi Kawarabayashi, Ravi Kumar, Silvio Lattanzi, Euiwoong Lee, Yi Li, Ioannis Panageas, Dimitris Paparas, Benjamin Przybocki, Bernardo Subercaseaux, Ola Svensson, Shayan Taherijam, Xuan Wu, Eylon Yogev, Morteza Zadimoghaddam, Samson Zhou, Yossi Matias, James Manyika, Vahab Mirrokni
2026 A conf
STACS
Ola Svensson
2026 J jnl
CoRR
Jan van den Brand, Inge Li Gørtz, Chirag Pabbaraju, Debmalya Panigrahi, Clifford Stein, Miltiadis Stouras, Ola Svensson, Ali Vakilian
2026 A* conf
SODA
Moran Feldman, Ola Svensson, Rico Zenklusen
2026 J jnl
Math. Oper. Res.
Moran Feldman, Paul Liu, Ashkan Norouzi-Fard, Ola Svensson, Rico Zenklusen
2025 J jnl
CoRR
Vincent Cohen-Addad, Fabrizio Grandoni, Euiwoong Lee, Chris Schwiegelshohn, Ola Svensson
2025 A* conf
STOC
Vincent Cohen-Addad, Fabrizio Grandoni, Euiwoong Lee, Chris Schwiegelshohn, Ola Svensson
2025 A* conf
STOC
Euiwoong Lee, Ola Svensson, Theophile Thiery
2025 J jnl
CoRR
Diptarka Chakraborty, Hendrik Fichtenberger, Bernhard Haeupler, Silvio Lattanzi, Ashkan Norouzi-Fard, Ola Svensson
2025 A conf
ITCS
Marina Drygala, Silvio Lattanzi, Andreas Maggiori, Miltiadis Stouras, Ola Svensson, Sergei Vassilvitskii
2025 A* conf
SODA
Joakim Blikstad, Ola Svensson, Radu Vintan, David Wajc
2025 J jnl
CoRR
Moran Feldman, Ola Svensson, Rico Zenklusen
2025 A* conf
FOCS
Joakim Blikstad, Ola Svensson, Radu Vintan, David Wajc
2025 J jnl
CoRR
Joakim Blikstad, Ola Svensson, Radu Vintan, David Wajc
2025 A* conf
STOC
Paul Dütting, Federico Fusco, Silvio Lattanzi, Ashkan Norouzi-Fard, Ola Svensson, Morteza Zadimoghaddam
2024 A* ed.
ICALP
Karl Bringmann, Martin Grohe, Gabriele Puppis, Ola Svensson
2024 A* conf
ICML
Étienne Bamas, Sai Ganesh Nagarajan, Ola Svensson
2024 J jnl
CoRR
Euiwoong Lee, Ola Svensson, Theophile Thiery
2024 J jnl
CoRR
Beatriz Borges, Negar Foroutan, Deniz Bayazit, Anna Sotnikova, Syrielle Montariol, Tanya Nazaretzky, Mohammadreza Banaei, Alireza Sakhaeirad, Philippe Servant, Seyed Parsa Neshaei, Jibril Frej, Angelika Romanou, Gail Weiss, Sepideh Mamooler, Zeming Chen, Simin Fan, Silin Gao, Mete Ismayilzada, Debjit Paul, Alexandre Schöpfer, Andrej Janchevski, Anja Tiede, Clarence Linden, Emanuele Troiani, Francesco Salvi, Freya Behrens, Giacomo Orsi, Giovanni Piccioli, Hadrien Sevel, Louis Coulon, Manuela Pineros-Rodriguez, Marin Bonnassies, Pierre Hellich, Puck van Gerwen, Sankalp Gambhir, Solal Pirelli, Thomas Blanchard, Timothée Callens, Toni Abi Aoun, Yannick Calvino Alonso, Yuri Cho, Alberto Silvio Chiappa, Antonio Sclocchi, Étienne Bruno, Florian Hofhammer, Gabriel Pescia, Geovani Rizk, Leello Dadi, Lucas Stoffl, Manoel Horta Ribeiro, Matthieu Bovel, Yueyang Pan, Aleksandra Radenovic, Alexandre Alahi, Alexander Mathis, Anne-Florence Bitbol, Boi Faltings, Cécile Hébert, Devis Tuia, François Maréchal, George Candea, Giuseppe Carleo, Jean-Cédric Chappelier, Nicolas Flammarion, Jean-Marie Fürbringer, Jean-Philippe Pellet, Karl Aberer, Lenka Zdeborová, Marcel Salathé, Martin Jaggi, Martin Rajman, Mathias Payer, Matthieu Wyart, Michael Gastpar, Michele Ceriotti, Ola Svensson, Olivier Lévêque, Paolo Ienne, Rachid Guerraoui, Robert West, Sanidhya Kashyap, Valerio Piazza, Viesturs Simanis, Viktor Kuncak, Volkan Cevher, Philippe Schwaller, Sacha Friedli, Patrick Jermann, Tanja Käser, Antoine Bosselut
2024 J jnl
CoRR
Marina Drygala, Silvio Lattanzi, Andreas Maggiori, Miltiadis Stouras, Ola Svensson, Sergei Vassilvitskii
2024 J jnl
CoRR
Joakim Blikstad, Ola Svensson, Radu Vintan, David Wajc
2024 A* conf
STOC
Joakim Blikstad, Ola Svensson, Radu Vintan, David Wajc
2024 J jnl
CoRR
Joakim Blikstad, Ola Svensson, Radu Vintan, David Wajc
2024 conf
SOSA
Joakim Blikstad, Ola Svensson, Radu Vintan, David Wajc
2024 J jnl
CoRR
Paul Dütting, Federico Fusco, Silvio Lattanzi, Ashkan Norouzi-Fard, Ola Svensson, Morteza Zadimoghaddam
2023 J jnl
CoRR
Étienne Bamas, Sai Ganesh Nagarajan, Ola Svensson
2023 A conf
AISTATS
Marina Drygala, Sai Ganesh Nagarajan, Ola Svensson
2023 J jnl
Dagstuhl Reports
Nicole Megow, Benjamin Moseley, David B. Shmoys, Ola Svensson, Sergei Vassilvitskii, Jens Schlöter
2023 J jnl
Math. Program.
Paritosh Garg, Linus Jordan, Ola Svensson
2023 J jnl
CoRR
Joakim Blikstad, Ola Svensson, Radu Vintan, David Wajc
2023 A* conf
ICML
Silvio Lattanzi, Ola Svensson, Sergei Vassilvitskii
2023 A* conf
SODA
Xinrui Jia, Ola Svensson, Weiqiang Yuan
2023 J jnl
J. ACM
Moran Feldman, Ashkan Norouzi-Fard, Ola Svensson, Rico Zenklusen
2023 A* conf
FOCS
Anupam Gupta, Madhusudhan Reddy Pittu, Ola Svensson, Rachel Yuan
2023 J jnl
CoRR
Anupam Gupta, Madhusudhan Reddy Pittu, Ola Svensson, Rachel Yuan
2022 J jnl
SIAM J. Comput.
Moran Feldman, Ola Svensson, Rico Zenklusen
2022 B conf
IPCO
Étienne Bamas, Marina Drygala, Ola Svensson
2022 J jnl
CoRR
Étienne Bamas, Marina Drygala, Ola Svensson
2022 A* conf
COLT
Buddhima Gamlath, Silvio Lattanzi, Ashkan Norouzi-Fard, Ola Svensson
2022 J jnl
Math. Program.
Xinrui Jia, Kshiteej Sheth, Ola Svensson
2022 J jnl
CoRR
Nikhil Bansal, Lars Rohwedder, Ola Svensson
2022 A* conf
STOC
Nikhil Bansal, Lars Rohwedder, Ola Svensson
2022 J jnl
Discret. Optim.
Daniel Bienstock, Yuri Faenza, Igor Malinovic, Monaldo Mastrolilli, Ola Svensson, Mark Zuckerberg
2022 A* conf
ICALP
Moran Feldman, Paul Liu, Ashkan Norouzi-Fard, Ola Svensson, Rico Zenklusen
2022 A conf
ESA
Moran Feldman, Ashkan Norouzi-Fard, Ola Svensson, Rico Zenklusen
2022 J jnl
CoRR
Moran Feldman, Ashkan Norouzi-Fard, Ola Svensson, Rico Zenklusen
2022 J jnl
CoRR
Xinrui Jia, Ola Svensson, Weiqiang Yuan
2022 conf
SOSA
Xinrui Jia, Lars Rohwedder, Kshiteej Sheth, Ola Svensson
2021 J jnl
CoRR
Friedrich Eisenbrand, Martina Gallato, Ola Svensson, Moritz Venzin
2021 A* conf
SODA
Hendrik Fichtenberger, Silvio Lattanzi, Ashkan Norouzi-Fard, Ola Svensson
2021 J jnl
SIAM J. Comput.
Nikhil Bansal, Aravind Srinivasan, Ola Svensson
2021 A* conf
NeurIPS
Buddhima Gamlath, Xinrui Jia, Adam Polak, Ola Svensson
2021 J jnl
CoRR
Buddhima Gamlath, Xinrui Jia, Adam Polak, Ola Svensson
2021 J jnl
SIAM J. Comput.
Moran Feldman, Ola Svensson, Rico Zenklusen
2021 A* conf
NeurIPS
Vincent Cohen-Addad, Silvio Lattanzi, Ashkan Norouzi-Fard, Christian Sohler, Ola Svensson
2021 J jnl
CoRR
Paritosh Garg, Linus Jordan, Ola Svensson
2021 B conf
IPCO
Paritosh Garg, Linus Jordan, Ola Svensson
2021 J jnl
CoRR
Moran Feldman, Ashkan Norouzi-Fard, Ola Svensson, Rico Zenklusen
2021 J jnl
CoRR
Xinrui Jia, Lars Rohwedder, Kshiteej Sheth, Ola Svensson
2020 J jnl
J. ACM
Ola Svensson, Jakub Tarnawski, László A. Végh
2020 J jnl
SIAM J. Comput.
Sara Ahmadian, Ashkan Norouzi-Fard, Ola Svensson, Justin Ward
2020 J jnl
CoRR
Hendrik Fichtenberger, Silvio Lattanzi, Ashkan Norouzi-Fard, Ola Svensson
2020 B conf
IPCO
Xinrui Jia, Kshiteej Sheth, Ola Svensson
2020 J jnl
CoRR
Xinrui Jia, Kshiteej Sheth, Ola Svensson
2020 A* conf
NeurIPS
Vincent Cohen-Addad, Silvio Lattanzi, Ashkan Norouzi-Fard, Christian Sohler, Ola Svensson
2020 J jnl
CoRR
Vincent Cohen-Addad, Silvio Lattanzi, Ashkan Norouzi-Fard, Christian Sohler, Ola Svensson
2020 A* conf
NeurIPS
Étienne Bamas, Andreas Maggiori, Lars Rohwedder, Ola Svensson
2020 J jnl
CoRR
Étienne Bamas, Andreas Maggiori, Lars Rohwedder, Ola Svensson
2020 A* conf
ICALP
Paritosh Garg, Sagar Kale, Lars Rohwedder, Ola Svensson
2020 J jnl
CoRR
Paritosh Garg, Sagar Kale, Lars Rohwedder, Ola Svensson
2020 J jnl
Dagstuhl Reports
Nicole Megow, David B. Shmoys, Ola Svensson
2020 J jnl
CoRR
Moran Feldman, Ashkan Norouzi-Fard, Ola Svensson, Rico Zenklusen
2020 A* conf
NeurIPS
Étienne Bamas, Andreas Maggiori, Ola Svensson
2020 J jnl
CoRR
Étienne Bamas, Andreas Maggiori, Ola Svensson
2020 A* conf
STOC
Moran Feldman, Ashkan Norouzi-Fard, Ola Svensson, Rico Zenklusen
2019 A ed.
ESA
Michael A. Bender, Ola Svensson, Grzegorz Herman
2019 A* conf
ICALP
Ola Svensson
2019 A* conf
SODA
Buddhima Gamlath, Sagar Kale, Ola Svensson
2019 J jnl
CoRR
Buddhima Gamlath, Sagar Kale, Ola Svensson
2019 A* conf
FOCS
Nikhil Bansal, Ola Svensson, Luca Trevisan
2019 J jnl
CoRR
Nikhil Bansal, Ola Svensson, Luca Trevisan
2019 J jnl
Math. Oper. Res.
Abbas Bazzi, Samuel Fiorini, Sebastian Pokutta, Ola Svensson
2019 A* conf
FOCS
Buddhima Gamlath, Michael Kapralov, Andreas Maggiori, Ola Svensson, David Wajc
2019 J jnl
CoRR
Buddhima Gamlath, Michael Kapralov, Andreas Maggiori, Ola Svensson, David Wajc
2019 A* conf
PODC
Buddhima Gamlath, Sagar Kale, Slobodan Mitrovic, Ola Svensson
2018 A* conf
SODA
Moran Feldman, Ola Svensson, Rico Zenklusen
2018 J jnl
Math. Oper. Res.
Moran Feldman, Ola Svensson, Rico Zenklusen
2018 A* conf
STOC
Ola Svensson, Jakub Tarnawski, László A. Végh
2018 conf
FSTTCS
Ola Svensson
2018 A* conf
ICML
Ashkan Norouzi-Fard, Jakub Tarnawski, Slobodan Mitrovic, Amir Zandieh, Aidasadat Mousavifar, Ola Svensson
2018 J jnl
CoRR
Ashkan Norouzi-Fard, Jakub Tarnawski, Slobodan Mitrovic, Amir Zandieh, Aida Mousavifar, Ola Svensson
2018 J jnl
Math. Program.
Ola Svensson, Jakub Tarnawski, László A. Végh
2018 C conf
ISCO
Yuri Faenza, Igor Malinovic, Monaldo Mastrolilli, Ola Svensson
2018 J jnl
CoRR
Yuri Faenza, Igor Malinovic, Monaldo Mastrolilli, Ola Svensson
2018 J jnl
IEEE Trans. Smart Grid
Teklemariam Tsegay Tesfay, Jean-Yves Le Boudec, Ola Svensson
2018 A* conf
ICALP
Buddhima Gamlath, Sangxia Huang, Ola Svensson
2018 J jnl
CoRR
Buddhima Gamlath, Sangxia Huang, Ola Svensson
2018 J jnl
Theory Comput.
Abbas Bazzi, Samuel Fiorini, Sangxia Huang, Ola Svensson
2018 J jnl
CoRR
Buddhima Gamlath, Sagar Kale, Slobodan Mitrovic, Ola Svensson
2017 J jnl
CoRR
Ola Svensson, Jakub Tarnawski, László A. Végh
2017 J jnl
CoRR
Moran Feldman, Ola Svensson, Rico Zenklusen
2017 A* conf
FOCS
Sara Ahmadian, Ashkan Norouzi-Fard, Ola Svensson, Justin Ward
2017 J jnl
ACM Trans. Algorithms
Chidambaram Annamalai, Christos Kalaitzis, Ola Svensson
2017 J jnl
ACM Trans. Algorithms
Hyung-Chan An, Ashkan Norouzi-Fard, Ola Svensson
2017 J jnl
SIAM J. Comput.
Hyung-Chan An, Mohit Singh, Ola Svensson
2017 A* conf
SODA
Abbas Bazzi, Samuel Fiorini, Sangxia Huang, Ola Svensson
2017 A* conf
FOCS
Ola Svensson, Jakub Tarnawski
2017 J jnl
CoRR
Ola Svensson, Jakub Tarnawski
2017 J jnl
Electron. Colloquium Comput. Complex.
Ola Svensson, Jakub Tarnawski
2017 A* conf
SODA
Christos Kalaitzis, Ola Svensson, Jakub Tarnawski
2016 A conf
ESA
Ola Svensson
2016 J jnl
SIAM J. Comput.
Shi Li, Ola Svensson
2016 J jnl
CoRR
Sara Ahmadian, Ashkan Norouzi-Fard, Ola Svensson, Justin Ward
2016 B conf
IPCO
Ola Svensson, Jakub Tarnawski, László A. Végh
2016 A* conf
STOC
Nikhil Bansal, Aravind Srinivasan, Ola Svensson
2016 conf
NIPS
Aditya Bhaskara, Mehrdad Ghadiri, Vahab S. Mirrokni, Ola Svensson
2016 A* conf
SODA
Moran Feldman, Ola Svensson, Rico Zenklusen
2016 J jnl
ACM Trans. Algorithms
Lukás Polácek, Ola Svensson
2016 J jnl
J. ACM
Tobias Mömke, Ola Svensson
2016 J jnl
CoRR
Abbas Bazzi, Samuel Fiorini, Sangxia Huang, Ola Svensson
2016 J jnl
CoRR
Christos Kalaitzis, Ola Svensson, Jakub Tarnawski
2015 A* conf
SODA
Moran Feldman, Ola Svensson, Rico Zenklusen
2015 A* conf
FOCS
Ola Svensson
2015 J jnl
CoRR
Ola Svensson
2015 B ed.
WAOA
Evripidis Bampis, Ola Svensson
2015 J jnl
Math. Program.
Hyung-Chan An, Aditya Bhaskara, Chandra Chekuri, Shalmoli Gupta, Vivek Madan, Ola Svensson
2015 A* conf
SODA
Chidambaram Annamalai, Christos Kalaitzis, Ola Svensson
2015 J jnl
CoRR
Ola Svensson, Jakub Tarnawski, László A. Végh
2015 A* conf
SODA
Hyung-Chan An, Ashkan Norouzi-Fard, Ola Svensson
2015 J jnl
CoRR
Nikhil Bansal, Ola Svensson, Aravind Srinivasan
2015 A* conf
FOCS
Abbas Bazzi, Samuel Fiorini, Sebastian Pokutta, Ola Svensson
2015 J jnl
CoRR
Abbas Bazzi, Samuel Fiorini, Sebastian Pokutta, Ola Svensson
2015 J jnl
Math. Program.
Christos Kalaitzis, Aleksander Madry, Alantha Newman, Lukás Polácek, Ola Svensson
2015 J jnl
CoRR
Moran Feldman, Ola Svensson, Rico Zenklusen
2015 J jnl
Theory Comput.
Sofya Raskhodnikova, Ola Svensson
2015 J jnl
Math. Program.
José Correa, Alberto Marchetti-Spaccamela, Jannik Matuschke, Leen Stougie, Ola Svensson, Víctor Verdugo, José Verschae
2014 J jnl
CoRR
Moran Feldman, Ola Svensson, Rico Zenklusen
2014 B conf
IPCO
Hyung-Chan An, Aditya Bhaskara, Chandra Chekuri, Shalmoli Gupta, Vivek Madan, Ola Svensson
2014 J jnl
CoRR
Chidambaram Annamalai, Christos Kalaitzis, Ola Svensson
2014 J jnl
CoRR
Hyung-Chan An, Ashkan Norouzi-Fard, Ola Svensson
2014 A* conf
FOCS
Hyung-Chan An, Mohit Singh, Ola Svensson
2014 J jnl
CoRR
Hyung-Chan An, Mohit Singh, Ola Svensson
2014 B conf
IPCO
Christos Kalaitzis, Aleksander Madry, Alantha Newman, Lukas Polacek, Ola Svensson
2014 J jnl
CoRR
Christos Kalaitzis, Aleksander Madry, Alantha Newman, Lukas Polacek, Ola Svensson
2014 B conf
IPCO
José R. Correa, Alberto Marchetti-Spaccamela, Jannik Matuschke, Leen Stougie, Ola Svensson, Victor Verdugo, José Verschae
2013 A* conf
STOC
Shi Li, Ola Svensson
2013 J jnl
CoRR
Hyung-Chan An, Aditya Bhaskara, Ola Svensson
2013 J jnl
Theory Comput.
Ola Svensson
2013 B conf
WG
Ola Svensson
2013 J jnl
Theor. Comput. Sci.
Monaldo Mastrolilli, Nikolaus Mutsanas, Ola Svensson
2012 J jnl
CoRR
Shi Li, Ola Svensson
2012 J jnl
ACM Trans. Comput. Theory
Mahdi Cheraghchi, Johan Håstad, Marcus Isaksson, Ola Svensson
2012 J jnl
CoRR
Ola Svensson
2012 conf
APPROX-RANDOM
Ola Svensson
2012 J jnl
CoRR
Lukas Polacek, Ola Svensson
2012 conf
ICALP (1)
Lukas Polacek, Ola Svensson
2012 J jnl
SIAM J. Comput.
Ola Svensson
2012 J jnl
ACM Trans. Algorithms
Florian Diedrich, Klaus Jansen, Lars Prädel, Ulrich M. Schwarz, Ola Svensson
2011 J jnl
CoRR
Tobias Mömke, Ola Svensson
2011 A* conf
FOCS
Tobias Mömke, Ola Svensson
2011 conf
CATS
Klaus Jansen, Lars Prädel, Ulrich M. Schwarz, Ola Svensson
2011 J jnl
J. ACM
Monaldo Mastrolilli, Ola Svensson
2011 J jnl
SIAM J. Comput.
Ola Svensson
2011 J jnl
SIAM J. Comput.
Christoph Ambühl, Monaldo Mastrolilli, Ola Svensson
2011 J jnl
Math. Oper. Res.
Christoph Ambühl, Monaldo Mastrolilli, Nikolaus Mutsanas, Ola Svensson
2011 A* conf
STOC
Ola Svensson
2010 conf
APPROX-RANDOM
Mahdi Cheraghchi, Johan Håstad, Marcus Isaksson, Ola Svensson
2010 J jnl
Electron. Colloquium Comput. Complex.
Mahdi Cheraghchi, Johan Håstad, Marcus Isaksson, Ola Svensson
2010 A* conf
STOC
Ola Svensson
2010 J jnl
Oper. Res. Lett.
Monaldo Mastrolilli, Maurice Queyranne, Andreas S. Schulz, Ola Svensson, Nelson A. Uhan
2010 J jnl
CoRR
Ola Svensson
2009 conf
ICALP (1)
Monaldo Mastrolilli, Ola Svensson
2008 A* conf
FOCS
Monaldo Mastrolilli, Ola Svensson
2008 conf
APPROX-RANDOM
Monaldo Mastrolilli, Nikolaus Mutsanas, Ola Svensson
2008 J jnl
Bull. EATCS
Christoph Ambühl, Monaldo Mastrolilli, Nikolaus Mutsanas, Ola Svensson
2007 A* conf
FOCS
Christoph Ambühl, Monaldo Mastrolilli, Ola Svensson
2007 B conf
IPCO
Christoph Ambühl, Monaldo Mastrolilli, Nikolaus Mutsanas, Ola Svensson
2006 conf
APPROX-RANDOM
Christoph Ambühl, Monaldo Mastrolilli, Ola Svensson
2006 conf
Ershov Memorial Conference
Ola Svensson, Sergei G. Vorobyov
2006 C conf
AAIM
Ola Svensson, Sergei G. Vorobyov
redb/extractors/database_exporters.py
← Index redb/extractors/database_exporters.py python
from abc import ABC, abstractmethod
from datetime import datetime, timezone
from dataclasses import asdict
import hashlib
import json
import inspect
from typing import Any, Dict, List, Union
from redb import settings
import traceback
from contextlib import contextmanager

class DatabaseExporter(ABC):
    @abstractmethod
    def export(self, data: Any, **kwargs) -> bool:
        """Export data to the database"""
        pass

class ElasticsearchExporter(DatabaseExporter):
    def __init__(self, logger: Any, index_prefix: str):
        self.client = settings.get_elasticsearch_client()
        self.index_prefix = index_prefix
        self.log = logger

    def export(self, data: Any, **kwargs) -> bool:
        self.log.debug(inspect.currentframe().f_code.co_name)
        if not isinstance(data, list):
            data = [data]
            
        now_t = datetime.now(timezone.utc).strftime("%Y-%m-%d %H:%M:%S")
        index = kwargs.get('index')
        tag = kwargs.get('tag')
        hashes = kwargs.get('hashes')
        
        for dataclass_ in data:
            try:
                # Convert dataclass to dict and filter out None values
                document = {k: v for k, v in asdict(dataclass_).items() if v is not None}
                
                if tag:
                    document["tag"] = tag
                document |= hashes
                document["timestamp_utc"] = now_t
                document["known_benign"] = kwargs.get('known_benign', False)
                document["known_malicious"] = kwargs.get('known_malicious', False)

                if "_id" in document:
                    tmp_id = document.pop("_id") + document["sha256"]
                    _id = hashlib.sha256(tmp_id.encode()).hexdigest()
                else:
                    _id = document["sha256"]

                doc_dump = json.dumps(document)
                self.client.index(index=index, id=_id, document=doc_dump)
                
            except Exception as e:
                self.log.error(f"Failed to export to Elasticsearch: {e}")
                return False
                
        return True

class PrintExporter(DatabaseExporter):
    """Exporter that prints results instead of uploading to database (for dry-run mode)"""
    def __init__(self, logger: Any, index_prefix: str):
        self.index_prefix = index_prefix
        self.log = logger
        self.log.debug(f"PrintExporter initialized with index_prefix: {index_prefix}")

    def export(self, data: Any, **kwargs) -> bool:
        try:
            import json
            from dataclasses import asdict, is_dataclass

            self.log.debug(f"PrintExporter.export called with data type: {type(data)}")

            if data is None:
                self.log.debug("PrintExporter.export: data is None, returning True")
                return True

            if not isinstance(data, list):
                data = [data]

            for i, item in enumerate(data):
                if is_dataclass(item) and not isinstance(item, type):
                    # Convert dataclass instance to dict
                    try:
                        item_dict = asdict(item)
                        print(json.dumps(item_dict, indent=2, default=str))
                    except Exception as e:
                        self.log.error(f"PrintExporter.export: Error converting dataclass: {e}")
                        print(str(item))
                elif isinstance(item, dict):
                    # Already a dict, print as JSON
                    print(json.dumps(item, indent=2, default=str))
                else:
                    # Fallback for other types
                    print(json.dumps(item, indent=2, default=str) if not isinstance(item, str) else item)

            self.log.debug("PrintExporter.export: completed successfully")
            return True
        except Exception as e:
            self.log.error(f"PrintExporter.export: Failed to print data: {e}")
            return False


class ClickHouseExporter(DatabaseExporter):
    def __init__(self, logger: Any, index_prefix: str, client=None):
        self.index_prefix = index_prefix
        self.log = logger
        self.client = client

    @contextmanager
    def clickhouse_connection(self):
        client = settings.create_clickhouse_client()
        try:
            yield client
        finally:
            try:
                client.close()
            except:
                pass
    # def export(self, data: Any, **kwargs) -> bool:
    #     try:
    #         # Handle multi-table export case
    #         # if isinstance(data, dict) and 'multi_table' in data:
    #         #     for table_name, table_data in data.items():
    #         #         if table_name != 'multi_table' and isinstance(table_data, dict) and 'table' in table_data:
    #         #             self.log.debug(f"Exporting to table: {table_data['table']}")
    #         #             self.log.debug(f"Column names: {table_data['column_names']}")
    #         #             self.log.debug(f"Column types: {table_data['column_type_names']}")
    #         #             self.log.debug(f"Data sample: {table_data['data'][0] if table_data['data'] else 'No data'}")
                        
    #         #             try:
    #         #                 result = self.client.insert(
    #         #                     table_data['table'],
    #         #                     table_data['data'],
    #         #                     column_names=table_data['column_names'],
    #         #                     column_type_names=table_data['column_type_names']
    #         #                 )
    #         #                 if not result:
    #         #                     self.log.error(f"Failed to insert into table {table_data['table']}")
    #         #                     return False
    #         #             except Exception as e:
    #         #                 self.log.error(f"Error inserting into table {table_data['table']}: {e}")
    #         #                 self.log.error(f"Data that caused error: {table_data['data']}")
    #         #                 return False
    #         #     return True

    #         if isinstance(data, dict) and 'multi_table' in data:
    #             for table_name, table_data in data.items():
    #                 if table_name != 'multi_table' and isinstance(table_data, dict) and 'table' in table_data:
    #                     self.log.debug(f"Exporting to table: {table_data['table']}")
                        
    #                     # Validate each row before insert
    #                     for row in table_data['data']:
    #                         for val, col_name, col_type in zip(row, table_data['column_names'], 
    #                                                         table_data['column_type_names']):
    #                             # Check for empty strings
    #                             if isinstance(val, str) and not val:
    #                                 self.log.error(f"Empty string found for column {col_name}")
    #                                 raise ValueError(f"Empty string not allowed for column {col_name}")
                                
    #                             # Log all string values for certificate_serial_number
    #                             if col_name == 'certificate_serial_number':
    #                                 self.log.debug(f"Serial number value: '{val}', type: {type(val)}, "
    #                                             f"repr: {repr(val)}")
                        
    #                     try:
    #                         result = self.client.insert(
    #                             table_data['table'],
    #                             table_data['data'],
    #                             column_names=table_data['column_names'],
    #                             column_type_names=table_data['column_type_names']
    #                         )
    #                         if not result:
    #                             self.log.error(f"Failed to insert into table {table_data['table']}")
    #                             return False
    #                     except Exception as e:
    #                         self.log.error(f"Error inserting into table {table_data['table']}: {e}")
    #                         self.log.error(f"Data that caused error: {table_data['data']}")
    #                         return False
    #             return True

    #         # Handle single table case
    #         table = kwargs.get('table')
    #         if not table:
    #             raise ValueError("Table name must be provided for ClickHouse export")
            
    #         # Unpack the tuple returned by prepare_export_data
    #         if isinstance(data, tuple):
    #             if len(data) != 3:
    #                 raise ValueError("Data tuple must contain exactly 3 elements: (data, column_names, column_type_names)")
    #             insert_data, column_names, column_type_names = data
    #         else:
    #             # Use provided column names and types from kwargs
    #             insert_data = data
    #             column_names = kwargs.get('column_names')
    #             column_type_names = kwargs.get('column_type_names')
                
    #         if not (column_names and column_type_names):
    #             raise ValueError("column_names and column_type_names must be provided")

    #         # Ensure data is in list format for batch insert
    #         if not isinstance(insert_data, list):
    #             insert_data = [insert_data]
                
    #         self.client.insert(
    #             table,
    #             insert_data,
    #             column_names=column_names,
    #             column_type_names=column_type_names
    #         )
    #         return True
            
    #     except Exception as e:
    #         self.log.error(f"Failed to export to ClickHouse: {e}")
    #         return False

    def get_client(self):
        """Get existing client or create new one if needed"""
        if self.client:
            return self.client
        try:
            return settings.create_clickhouse_client() 
        except Exception as e:
            self.log.error(f"Failed to create ClickHouse client: {e}")
            return None
            
    # WORKING SIMPLE VERSION
    def export(self, data: Any, **kwargs) -> bool:
        try:
            # # Handle multi-table export case
            # # if isinstance(data, dict) and 'multi_table' in data:
            # #     for table_data in data.values():
            # #         if isinstance(table_data, dict) and 'table' in table_data:
            # #             result = self.client.insert(
            # #                 table_data['table'],
            # #                 table_data['data'],
            # #                 column_names=table_data['column_names'],
            # #                 column_type_names=table_data['column_type_names']
            # #             )
            # #             if not result:  # If any insert fails, return False
            # #                 return False
            # #     return True
            # if isinstance(data, dict) and 'multi_table' in data:
            #     for key, table_data in data.items():
            #         if key != 'multi_table' and isinstance(table_data, dict) and 'table' in table_data:
            #             # Add type hints
            #             typed_data = []
            #             for row in table_data['data']:
            #                 typed_row = []
            #                 for val, type_name in zip(row, table_data['column_type_names']):
            #                     if isinstance(val, str) and not val:
            #                         val = 'UNKNOWN'
            #                     if type_name == 'String' or 'LowCardinality(String)' in type_name:
            #                         val = str(val) if val is not None else 'UNKNOWN'
            #                     typed_row.append(val)
            #                 typed_data.append(typed_row)
                        
            #             table_data['data'] = typed_data
                        
            #             result = self.client.insert(
            #                 table_data['table'],
            #                 table_data['data'],
            #                 column_names=table_data['column_names'],
            #                 column_type_names=table_data['column_type_names'],
            #                 settings={'input_format_values_interpret_expressions': 0}  # Disable type inference
            #             )
            #             if not result:
            #                 return False
            #         return True

            # Get a new client connection for this export operation
            with self.clickhouse_connection() as client:
                if not client:
                    return False

                # LAST WORKING VERSION
                if isinstance(data, dict) and 'multi_table' in data:
                    for key, table_data in data.items():
                        if key != 'multi_table' and isinstance(table_data, dict) and 'table' in table_data:
                            # Debug logging
                            self.log.debug(f"Processing table: {table_data['table']}")
                            self.log.debug(f"Column names: {table_data['column_names']}")
                            self.log.debug(f"Column types: {table_data['column_type_names']}")
                            
                            typed_data = []
                            for row_idx, row in enumerate(table_data['data']):
                                typed_row = []
                                for val_idx, (val, type_name, col_name) in enumerate(
                                    zip(row, table_data['column_type_names'], table_data['column_names'])
                                ):
                                    try:
                                        # Handle different types
                                        if val is None:
                                            if 'Nullable' in type_name:
                                                val = None  # Keep None for Nullable columns
                                            elif 'Array' in type_name:
                                                val = []
                                            elif 'Int' in type_name or 'UInt' in type_name:
                                                val = 0
                                            elif 'FixedString(16)' in type_name:
                                                val = b'\x00' * 16  # Binary FixedString
                                            elif 'String' in type_name or 'LowCardinality' in type_name:
                                                val = 'UNKNOWN'
                                            elif 'DateTime' in type_name:
                                                val = datetime.now(timezone.utc)
                                            elif 'Boolean' in type_name:
                                                val = False
                                            else:
                                                self.log.error(f"Unhandled type {type_name} for null value")
                                                val = 'UNKNOWN'
                                        
                                        # Log problematic values
                                        if isinstance(val, str) and not val.strip():
                                            self.log.warning(f"Empty string found in table {table_data['table']}, "
                                                        f"column {col_name}, row {row_idx}")
                                        
                                        # Ensure array types are always lists
                                        if 'Array' in type_name and not isinstance(val, list):
                                            val = [val]
                                        
                                        typed_row.append(val)
                                    except Exception as e:
                                        self.log.error(f"Error processing value in table {table_data['table']}, "
                                                    f"column {col_name} ({type_name}), "
                                                    f"row {row_idx}, value: {repr(val)}")
                                        raise
                                        
                                typed_data.append(typed_row)
                            
                            table_data['data'] = typed_data

                            # Skip insert if there is nothing to insert
                            if not typed_data:
                                self.log.debug(f"No data to insert for table {table_data['table']}, skipping.")
                                continue

                            # Debug log the first row of data
                            self.log.debug(f"Sample row for {table_data['table']}: {typed_data[0]}")

                            result = client.insert(
                                table_data['table'],
                                table_data['data'],
                                column_names=table_data['column_names'],
                                column_type_names=table_data['column_type_names'],
                                settings={'input_format_values_interpret_expressions': 0}
                            )
                            if not result:
                                self.log.error(f"Insert failed for table {table_data['table']}")
                                return False
                    return True

                # Handle single table case
                table = kwargs.get('table')
                if not table:
                    raise ValueError("Table name must be provided for ClickHouse export")
                
                # Unpack the tuple returned by prepare_export_data
                if isinstance(data, tuple):
                    if len(data) != 3:
                        raise ValueError("Data tuple must contain exactly 3 elements: (data, column_names, column_type_names)")
                    insert_data, column_names, column_type_names = data
                else:
                    # Use provided column names and types from kwargs
                    insert_data = data
                    column_names = kwargs.get('column_names')
                    column_type_names = kwargs.get('column_type_names')
                    
                if not (column_names and column_type_names):
                    raise ValueError("column_names and column_type_names must be provided")

                # Ensure data is in list format for batch insert
                if not isinstance(insert_data, list):
                    insert_data = [insert_data]

                # Skip insert if there is nothing to insert
                if not insert_data:
                    self.log.debug(f"No data to insert for table {table}, skipping.")
                    return True

                client.insert(
                    table,
                    insert_data,
                    column_names=column_names,
                    column_type_names=column_type_names,
                    settings={'input_format_values_interpret_expressions': 0}  # Disable type inference
                )
                return True

        except TypeError as e:
            # Get the actual value causing the error from the exception traceback
            import sys
            exc_type, exc_value, exc_traceback = sys.exc_info()
            
            # Walk through the traceback to find the frame with the problematic value
            current = exc_traceback
            while current:
                if 'string.py' in current.tb_frame.f_code.co_filename and '_data_size' in current.tb_frame.f_code.co_name:
                    locals_dict = current.tb_frame.f_locals
                    problematic_value = locals_dict.get('x')
                    self.log.error(f"TypeError with value: {problematic_value} (type: {type(problematic_value)})")
                    self.log.error(f"Full locals at error: {locals_dict}")
                    break
                current = current.tb_next
            
            self.log.error(f"Failed to export to ClickHouse: {e}")
            self.log.error("Full traceback:")
            self.log.error(traceback.format_exc())
            return False
        except Exception as e:
            self.log.error(f"Failed to export to ClickHouse: {e}")
            self.log.error(traceback.format_exc())
            return False
        finally:
            # Only close if we created a new client
            if client and client != self.client:
                # Close the client connection
                try:
                    client.close()
                except:
                    pass