def add(self, data, value=None, timestamp=None, namespace=None,
            debug=False):
        if value is not None:
            return self.add(((data, value),), timestamp=timestamp,
                            namespace=namespace, debug=debug)
        writer = self.writer
        if writer is None:
            raise GaugedUseAfterFreeError
        if timestamp is None:
            timestamp = long(time() * 1000)
        config = self.config
        block_size = config.block_size
        this_block = timestamp // block_size
        this_array = (timestamp % block_size) // config.resolution
        if namespace is None:
            namespace = config.namespace
        if this_block < self.current_block or \
                (this_block == self.current_block and
                 this_array < self.current_array):
            if config.append_only_violation == Writer.ERROR:
                msg = 'Gauged is append-only; timestamps must be increasing'
                raise GaugedAppendOnlyError(msg)
            elif config.append_only_violation == Writer.REWRITE:
                this_block = self.current_block
                this_array = self.current_array
            else:
                return
        if isinstance(data, unicode):
            data = data.encode('utf8')
        if debug:
            return self.debug(timestamp, namespace, data)
        if this_block > self.current_block:
            self.flush_blocks()
            self.current_block = this_block
            self.current_array = this_array
        elif this_array > self.current_array:
            if not Gauged.writer_flush_arrays(writer, self.current_array):
                raise MemoryError
            self.current_array = this_array
        data_points = 0
        namespace_statistics = self.statistics[namespace]
        whitelist = config.key_whitelist
        skip_long_keys = config.key_overflow == Writer.IGNORE
        skip_gauge_nan = config.gauge_nan == Writer.IGNORE
        if isinstance(data, str) and skip_gauge_nan \
                and skip_long_keys and whitelist is None:
            data_points = c_uint32(0)
            if not Gauged.writer_emit_pairs(writer, namespace, data,
                                            byref(data_points)):
                raise MemoryError
            data_points = data_points.value
        else:
            if isinstance(data, dict):
                data = data.iteritems()
            elif isinstance(data, str):
                data = self.parse_query(data)
            emit = Gauged.writer_emit
            for key, value in data:
                key = to_bytes(key)
                if whitelist is not None and key not in whitelist:
                    continue
                try:
                    value = float(value)
                except ValueError:
                    value = float('nan')
                if value != value:
                    if skip_gauge_nan:
                        continue
                    raise GaugedNaNError
                success = emit(writer, namespace, key, c_float(value))
                if success != 1:
                    if not success:
                        raise MemoryError
                    elif success == Writer.KEY_OVERFLOW and not skip_long_keys:
                        msg = 'Key is larger than the driver allows '
                        msg += '(%s)' % key
                        raise GaugedKeyOverflowError(msg)
                data_points += 1
        namespace_statistics.data_points += data_points
        if self.flush_now:
            self.flush()