class_docstr: Serialize a Dataflow to a lmdb database, where the keys are indices and values
  are serialized datapoints.
  
  You will need to ``pip install lmdb`` to use it.
  
  Example:
  
  .. code-block:: python
  
      LMDBSerializer.save(my_df, "output.lmdb")
  
      new_df = LMDBSerializer.load("output.lmdb", shuffle=True)
class_docstr_tok: ["Serialize","a","Dataflow","to","a","lmdb","database",",","where","the","keys","are","indices","and","values","are","serialized","datapoints",".","You","will","need","to","``","pip","install","lmdb","``","to","use","it",".","Example",":","..","code-block",":",":","python","LMDBSerializer.save","(","my_df",",","``","output.lmdb","''",")","new_df","=","LMDBSerializer.load","(","``","output.lmdb","''",",","shuffle=True",")"]
docstr: Args:
      df (DataFlow): the DataFlow to serialize.
      path (str): output path. Either a directory or an lmdb file.
      write_frequency (int): the frequency to write back data to disk.
          A smaller value reduces memory usage.
docstr_tok: ["Args",":","df","(","DataFlow",")",":","the","DataFlow","to","serialize",".","path","(","str",")",":","output","path",".","Either","a","directory","or","an","lmdb","file",".","write_frequency","(","int",")",":","the","frequency","to","write","back","data","to","disk",".","A","smaller","value","reduces","memory","usage","."]
code: def save(df, path, write_frequency=5000):
      """
      Args:
          df (DataFlow): the DataFlow to serialize.
          path (str): output path. Either a directory or an lmdb file.
          write_frequency (int): the frequency to write back data to disk.
              A smaller value reduces memory usage.
      """
      assert isinstance(df, DataFlow), type(df)
      isdir = os.path.isdir(path)
      if isdir:
          assert not os.path.isfile(
              os.path.join(path, "data.mdb")
          ), "LMDB file exists!"
      else:
          assert not os.path.isfile(
              path
          ), "LMDB file {} exists!".format(path)
      # It's OK to use super large map_size on Linux, but not on other platforms
      # See: https://github.com/NVIDIA/DIGITS/issues/206
      map_size = (
          1099511627776 * 2
          if platform.system() == "Linux"
          else 128 * 10**6
      )
      db = lmdb.open(
          path,
          subdir=isdir,
          map_size=map_size,
          readonly=False,
          meminit=False,
          map_async=True,
      )  # need sync() at the end
      size = _reset_df_and_get_size(df)
  
      # put data into lmdb, and doubling the size if full.
      # Ref: https://github.com/NVIDIA/DIGITS/pull/209/files
      def put_or_grow(txn, key, value):
          try:
              txn.put(key, value)
              return txn
          except lmdb.MapFullError:
              pass
          txn.abort()
          curr_size = db.info()["map_size"]
          new_size = curr_size * 2
          logger.info(
              "Doubling LMDB map_size to {:.2f}GB".format(
                  new_size / 10**9
              )
          )
          db.set_mapsize(new_size)
          txn = db.begin(write=True)
          txn = put_or_grow(txn, key, value)
          return txn
  
      with get_tqdm(total=size) as pbar:
          idx = -1
  
          # LMDB transaction is not exception-safe!
          # although it has a context manager interface
          txn = db.begin(write=True)
          for idx, dp in enumerate(df):
              txn = put_or_grow(
                  txn, "{:08}".format(idx).encode("ascii"), dumps(dp)
              )
              pbar.update()
              if (idx + 1) % write_frequency == 0:
                  txn.commit()
                  txn = db.begin(write=True)
          txn.commit()
  
          keys = [
              "{:08}".format(k).encode("ascii") for k in range(idx + 1)
          ]
          with db.begin(write=True) as txn:
              txn = put_or_grow(txn, b"__keys__", dumps(keys))
  
          logger.info("Flushing database ...")
          db.sync()
      db.close()
  
imports: import numpy
  import os
  import platform
  from collections import defaultdict
  from ..utils import logger
  from ..utils.serialize import dumps, loads
  from ..utils.develop import create_dummy_class
  from ..utils.utils import get_tqdm
  from .base import DataFlow
  from .common import FixedSizeData, MapData
  from .format import HDF5Data, LMDBData, DiskCacheData
  from .raw import DataFromGenerator, DataFromList
label_desc: Use image node_id 1 for calling the LMDBSerializer obj's underlying member method code with example usage: obj.save(df, path, write_frequency) and returns: txn, txn