Skip to main content

No project description provided

Project description

MemStore

MemStore is a lightweight in-memory database written in Python. It supports key-value storage with integer IDs, single-field indexing, filtering by field values, and slicing records using integer-based positions. It uses dictionaries for data storage and retrieval.


Installation

Since MemStore is a single-class implementation, you can simply include it in your project. No external package installation is required. Alternatively, if packaged:

pip install memstore

Usage Examples

1. Initialize the Database

Create a database with optional indexes:

from memstore import MemStore

# Initialize with indexes on 'name' and 'age'
db = MemStore(indexes=['name', 'age'])

2. Insert Records

Add a single record and get its ID:

# Insert a single record
record_id = db.add({'name': 'Alice', 'age': 25, 'city': 'New York'})
print(f"Inserted record with ID: {record_id}")  # Output: Inserted record with ID: 0

3. Query Records

Retrieve records by ID or filter by field values:

# Get by ID
record = db.get(0)
print(record)  # Output: {'name': 'Alice', 'age': 25, 'city': 'New York'}

# Filter by indexed field
alice_records = db.filter({'name': 'Alice'})
print(alice_records)  # Output: [(0, {'name': 'Alice', 'age': 25, 'city': 'New York'})]

# Filter by non-indexed field
ny_records = db.filter({'city': 'New York'})
print(ny_records)  # Output: [(0, {'name': 'Alice', 'age': 25, 'city': 'New York'})]

# Filter with multiple conditions (mixed indexed and non-indexed)
alice_25_records = db.filter({'name': 'Alice', 'age': 25})
print(alice_25_records)  # Output: [(0, {'name': 'Alice', 'age': 25, 'city': 'New York'})]

4. Filter First and Last Records

Retrieve the first or last inserted record matching specific conditions:

# Add more records with duplicate names
db.add({'name': 'Bob', 'age': 30, 'city': 'Boston'})  # ID: 1
db.add({'name': 'Alice', 'age': 26, 'city': 'Boston'})  # ID: 2
db.add({'name': 'Charlie', 'age': 35, 'city': 'Chicago'})  # ID: 3

# Get the first inserted Alice (earliest by ID)
first_alice = db.filter_first({'name': 'Alice'})
print(first_alice)  # Output: {'name': 'Alice', 'age': 25, 'city': 'New York'}

# Get the last inserted Alice (latest by ID)
last_alice = db.filter_last({'name': 'Alice'})
print(last_alice)  # Output: {'name': 'Alice', 'age': 26, 'city': 'Boston'}

# Filter first with multiple conditions
first_boston = db.filter_first({'city': 'Boston'})
print(first_boston)  # Output: {'name': 'Bob', 'age': 30, 'city': 'Boston'}

# Filter last with multiple conditions
last_boston = db.filter_last({'city': 'Boston'})
print(last_boston)  # Output: {'name': 'Alice', 'age': 26, 'city': 'Boston'}

# No match returns None
no_match = db.filter_first({'name': 'David'})
print(no_match)  # Output: None

5. List All Records

Retrieve all records in the database:

all_records = db.all()
for record_id, record in all_records:
    print(f"ID {record_id}: {record}")
# Output:
# ID 0: {'name': 'Alice', 'age': 25, 'city': 'New York'}
# ID 1: {'name': 'Bob', 'age': 30, 'city': 'Boston'}
# ID 2: {'name': 'Alice', 'age': 26, 'city': 'Boston'}
# ID 3: {'name': 'Charlie', 'age': 35, 'city': 'Chicago'}

6. Slice Records with islice

Retrieve a subset of records using integer-based slicing with islice:

# Slice from start to position 2 (exclusive)
slice_1 = db.islice(stop=2)
print(slice_1)
# Output: [(0, {'name': 'Alice', 'age': 25, 'city': 'New York'}),
#          (1, {'name': 'Bob', 'age': 30, 'city': 'Boston'})]

# Slice from position 1 to 3
slice_2 = db.islice(1, 3)
print(slice_2)
# Output: [(1, {'name': 'Bob', 'age': 30, 'city': 'Boston'}),
#          (2, {'name': 'Alice', 'age': 26, 'city': 'Boston'})]

# Slice with step (every second record)
slice_3 = db.islice(0, None, 2)
print(slice_3)
# Output: [(0, {'name': 'Alice', 'age': 25, 'city': 'New York'}),
#          (2, {'name': 'Alice', 'age': 26, 'city': 'Boston'})]

# Slice with negative indexes (last two records)
slice_4 = db.islice(-2, None)
print(slice_4)
# Output: [(2, {'name': 'Alice', 'age': 26, 'city': 'Boston'}),
#          (3, {'name': 'Charlie', 'age': 35, 'city': 'Chicago'})]

7. Access Records with iloc

Retrieve records by integer position using iloc, supporting both single index and slice operations:

# Get a single record by position
record = db.iloc[1]
print(record)  # Output: {'name': 'Bob', 'age': 30, 'city': 'Boston'}

# Get the last record using negative index
last_record = db.iloc[-1]
print(last_record)  # Output: {'name': 'Charlie', 'age': 35, 'city': 'Chicago'}

# Slice records with iloc
slice_iloc = db.iloc[1:3]
print(slice_iloc)
# Output: [(1, {'name': 'Bob', 'age': 30, 'city': 'Boston'}),
#          (2, {'name': 'Alice', 'age': 26, 'city': 'Boston'})]

# Slice with step using iloc
slice_step = db.iloc[0::2]
print(slice_step)
# Output: [(0, {'name': 'Alice', 'age': 25, 'city': 'New York'}),
#          (2, {'name': 'Alice', 'age': 26, 'city': 'Boston'})]

8. Delete Records

Remove a record by ID:

success = db.delete(0)
print(f"Delete successful: {success}")  # Output: Delete successful: True
print(db.all())  # Output: [(1, {'name': 'Bob', 'age': 30, 'city': 'Boston'}),
#                           (2, {'name': 'Alice', 'age': 26, 'city': 'Boston'}),
#                           (3, {'name': 'Charlie', 'age': 35, 'city': 'Chicago'})]

9. Manage Indexes

Add or remove indexes dynamically:

# Add a new index
db.add_index('city')
print(db.filter({'city': 'Boston'}))  # Output: [(1, {'name': 'Bob', 'age': 30, 'city': 'Boston'}),
#                                               (2, {'name': 'Alice', 'age': 26, 'city': 'Boston'})]

# Drop an index
db.drop_index('name')
print('name' in db._indexes)  # Output: False

Notes

  • Data Structure: Records are stored as dictionaries with integer IDs assigned sequentially using itertools.count(). Lower IDs represent earlier insertions, and higher IDs represent later insertions.
  • Indexes: Only single-field indexes are supported (e.g., 'name'). Composite indexes are not available.
  • Filtering:
    • The filter method retrieves all records matching specified field-value pairs, using indexes when available for efficiency. It works with both indexed and non-indexed fields and returns a list of (id, record) tuples.
    • The filter_first method retrieves the earliest inserted record (lowest ID) matching the conditions, returning a dictionary or None if no match.
    • The filter_last method retrieves the latest inserted record (highest ID) matching the conditions, returning a dictionary or None if no match.
  • Slicing with islice: The islice method allows positional slicing of records using integer indexes (positive or negative), supporting start, stop, and step parameters. It returns a list of (id, record) tuples.
  • Positional Access with iloc: The iloc property provides a pandas-like interface for accessing records by integer position. It supports single integer indexing (returns a record dictionary or None if out of range) and slicing (returns a list of (id, record) tuples).
  • Limitations: No field validation or update methods are provided. Deletion and retrieval are ID-based or filter-based only.
  • Dependencies: Uses only Python standard library modules (collections, functools, itertools, operator, typing).

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

memstore-0.2.5.3.tar.gz (5.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

memstore-0.2.5.3-py3-none-any.whl (5.3 kB view details)

Uploaded Python 3

File details

Details for the file memstore-0.2.5.3.tar.gz.

File metadata

  • Download URL: memstore-0.2.5.3.tar.gz
  • Upload date:
  • Size: 5.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.1.1 CPython/3.10.12 Linux/6.8.0-55-generic

File hashes

Hashes for memstore-0.2.5.3.tar.gz
Algorithm Hash digest
SHA256 22dec4a7f41871c71fddb27cdc73461de1fcb3b2ce235ea2e8d329ade75e2ecd
MD5 84f2b97d891cf20dbd78bca8f9434e70
BLAKE2b-256 3757ec2966924f1022656da69c06dd1d85b4751f49f508c13c4b60d37d0b3028

See more details on using hashes here.

File details

Details for the file memstore-0.2.5.3-py3-none-any.whl.

File metadata

  • Download URL: memstore-0.2.5.3-py3-none-any.whl
  • Upload date:
  • Size: 5.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.1.1 CPython/3.10.12 Linux/6.8.0-55-generic

File hashes

Hashes for memstore-0.2.5.3-py3-none-any.whl
Algorithm Hash digest
SHA256 531cdaaf2a363e64b407b329b1edbca5d6f3ebccf87f30977815610fae5d0ab6
MD5 2557f15da121433d80fb8135a651160e
BLAKE2b-256 22786c6d3df52731ef0199ba8718a3bf3fea4d0a7c93e2264e6d733784fe15cf

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page