#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Standard library imports
# Related third party imports (If you used pip/apt/yum to install)
# Local application/library specific imports (Look ma! I wrote it myself!)
"""Python shared memory dictionary."""
"""Standard init method.
:param name: Name for shared memory and semaphore if volatile
or path to file if persistent.
:param persist: True if name is the path to a file and this
shared memory dictionary should be written
out to the file for persistence between runs
and/or processes.
:param lock_timeout: Time in seconds before giving up on
acquiring an exclusive lock to the
dictionary.
:param auto_unlock: If the lock_timeout is hit, and this
is True, automatically bypass the
lock and use the dictionary anyway.
:type name: :class:`str`
:type persist: :class:`bool`
:type lock_timeout: :class:`int` or :class:`float`
:type auto_unlock: :class:`bool`
"""
"""IPC object safe name creator.
Semaphores and Shared Mmeory names allow up to 256 characters (dependong on OS) and must
begin with a /.
:param prefix: A string to prepend followed by _ and
then the dictionary's name.
:type prefix: :class:`str`
"""
# Hash lengths
# SHA1: 28
# SHA256: 44
# SHA512: 88
def safe_sem_name(self):
"""Unique semaphore name based on the dictionary name."""
def safe_shm_name(self):
"""Unique shared memory segment name based on the dictionary name."""
def semaphore(self):
"""Create or return already existing semaphore."""
self.safe_sem_name, flags=posix_ipc.O_CREAT, initial_value=1
)
def shared_mem(self):
"""Create or return already existing shared memory object."""
self.safe_shm_name, size=len(pickle.dumps(self.__internal_dict))
)
self.safe_shm_name, flags=posix_ipc.O_CREX, size=posix_ipc.PAGE_SIZE
)
def map_file(self):
"""Create or return mmap file resizing if necessary."""
int(
ceil(float(len(pickle.dumps(self.__internal_dict, 2))) / mmap.PAGESIZE)
* mmap.PAGESIZE
)
)
"""Load dictionary from shared memory or file if persistent and memory empty."""
# Read in internal data from map_file
# Curtis Pullen found that Python 3.4 throws EOFError
# instead of UnpicklingError that Python 3.6 throws
# when attempting to unpickle an empty file.
# If map_file is empty and persist_file is true, treat
# self.name as filename and attempt to load from disk.
# If map_file is empty, persist_file is False or
# self.name is empty create a new empty dictionary.
"""Save dictionary into shared memory and file if persistent."""
# Write out internal dict to map_file
"""Acquire an exclusive dict lock.
Loads dictionary data from memory or disk (if persistent) to
ensure data is up to date when lock is requested.
.. warnings also::
MacOS has a number of shortcomings with regards to
semaphores and shared memory segments, this is one
method contains one of them.
When the timeout is > 0, the call will wait no longer than
timeout seconds before either returning (having acquired
the semaphore) or raising a BusyError.
On platforms that don't support the sem_timedwait() API,
a timeout > 0 is treated as infinite. The call will not
return until its wait condition is satisfied.
Most platforms provide sem_timedwait(). macOS is a notable
exception. The module's Boolean constant
SEMAPHORE_TIMEOUT_SUPPORTED is True on platforms that
support sem_timedwait().
-- http://semanchuk.com/philip/posix_ipc/
"""
else:
"""Release the exclusive semaphore lock."""
def exclusive_lock(self):
"""A context manager for the lock to allow with statements for exclusive access."""
"""Destroy the object nicely."""
"""Set a key in the dictionary to a value."""
"""Get the value of a key from the dictionary."""
"""Represent the dictionary in a human readable format."""
"""Return the length of the dictionary."""
"""Remove an item from the dictionary."""
"""Completely clear the dictionary."""
"""Create and return a copy of the internal dictionary."""
"""Return true if a key is in the internal dictionary."""
"""Shared memory dictionary equality check with another shared memory dictionary."""
"""Shared memory dictionary non-equality check with another shared memory dictionary."""
isinstance(other, SHMDict) and self.safe_shm_name != other.safe_shm_name
)
"""Check if a key exists inside the dictionary."""
"""Iterate through the dictionary keys."""