or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

extensions.mdindex.mdjdbc.mdmvstore.mdserver.mdtools.md

mvstore.mddocs/

0

# Embedded MVStore

1

2

MVStore is H2 Database's advanced storage engine that can be used independently as a high-performance, persistent key-value store. It provides ACID transactions, multi-version concurrency control (MVCC), and various specialized data structures including maps, trees, and spatial indexes.

3

4

## Core MVStore Classes

5

6

### MVStore

7

8

The main store class that manages persistent key-value maps with ACID transactions.

9

10

```java { .api }

11

public final class MVStore implements AutoCloseable {

12

// Static factory methods

13

public static MVStore open(String fileName);

14

public static Builder builder();

15

16

// Map management

17

public <K, V> MVMap<K, V> openMap(String name);

18

public <M extends MVMap<K, V>, K, V> M openMap(String name, MVMap.MapBuilder<M, K, V> builder);

19

public <K, V> MVMap<K, V> openMap(String name, DataType keyType, DataType valueType);

20

public void removeMap(String name);

21

public Set<String> getMapNames();

22

23

// Store information

24

public Map<String, String> getLayoutMap();

25

public long getCurrentVersion();

26

public int getFileStore().getReadCount();

27

public int getFileStore().getWriteCount();

28

public long getFileStore().size();

29

30

// Transaction and persistence

31

public void commit();

32

public long commitAndSave();

33

public void rollback();

34

public void save();

35

36

// Store lifecycle

37

public void close();

38

public void closeImmediately();

39

public boolean isClosed();

40

public MVStoreException getPanicException();

41

42

// Configuration

43

public int getCacheSizeUsed();

44

public void setCacheSize(int mb);

45

public void setVersionsToKeep(int count);

46

public void setAutoCommitDelay(int millis);

47

}

48

```

49

50

**Usage Examples:**

51

52

```java

53

// Create/open file-based store

54

MVStore store = MVStore.open("data.mv");

55

56

// Create in-memory store

57

MVStore store = new MVStore.Builder().open();

58

59

// Open map

60

MVMap<String, String> map = store.openMap("users");

61

62

// Store data

63

map.put("user1", "Alice");

64

map.put("user2", "Bob");

65

66

// Commit changes

67

store.commit();

68

69

// Close store

70

store.close();

71

```

72

73

### MVStore.Builder

74

75

Builder pattern for configuring MVStore instances.

76

77

```java { .api }

78

public static class Builder {

79

public Builder fileName(String fileName);

80

public Builder cacheSize(int mb);

81

public Builder autoCommitDisabled();

82

public Builder autoCommitBufferSize(int kb);

83

public Builder compress();

84

public Builder compressHigh();

85

public Builder encryptionKey(char[] encryptionKey);

86

public Builder readOnly();

87

public Builder cacheConcurrency(int concurrency);

88

public Builder backgroundExceptionHandler(Thread.UncaughtExceptionHandler handler);

89

90

public MVStore open();

91

}

92

```

93

94

**Usage Examples:**

95

96

```java

97

// Configure store with builder

98

MVStore store = new MVStore.Builder()

99

.fileName("mydata.mv")

100

.cacheSize(64) // 64 MB cache

101

.compress() // Enable compression

102

.autoCommitBufferSize(1024) // 1 MB auto-commit buffer

103

.open();

104

105

// In-memory compressed store

106

MVStore memStore = new MVStore.Builder()

107

.compress()

108

.cacheSize(32)

109

.open();

110

111

// Read-only store

112

MVStore readOnlyStore = new MVStore.Builder()

113

.fileName("readonly.mv")

114

.readOnly()

115

.open();

116

117

// Encrypted store

118

char[] password = "mySecretPassword".toCharArray();

119

MVStore encryptedStore = new MVStore.Builder()

120

.fileName("encrypted.mv")

121

.encryptionKey(password)

122

.open();

123

```

124

125

### MVMap

126

127

Persistent map implementation with MVCC support.

128

129

```java { .api }

130

public class MVMap<K, V> {

131

// Basic map operations

132

public V put(K key, V value);

133

public V get(Object key);

134

public V remove(Object key);

135

public boolean containsKey(Object key);

136

public boolean containsValue(Object value);

137

public boolean isEmpty();

138

public long size();

139

public void clear();

140

141

// Bulk operations

142

public void putAll(Map<? extends K, ? extends V> m);

143

public Set<K> keySet();

144

public Collection<V> values();

145

public Set<Map.Entry<K, V>> entrySet();

146

147

// Versioned operations

148

public V put(K key, V value, boolean tryReplace);

149

public boolean replace(K key, V oldValue, V newValue);

150

public V putIfAbsent(K key, V value);

151

public boolean remove(Object key, Object value);

152

153

// Range operations

154

public K firstKey();

155

public K lastKey();

156

public K lowerKey(K key);

157

public K floorKey(K key);

158

public K ceilingKey(K key);

159

public K higherKey(K key);

160

161

// Cursor operations

162

public Cursor<K, V> cursor(K from);

163

public Cursor<K, V> cursor(K from, K to, boolean includeKey);

164

165

// Versioning

166

public MVMap<K, V> openVersion(long version);

167

public long getVersion();

168

169

// Map information

170

public String getName();

171

public DataType getKeyType();

172

public DataType getValueType();

173

public boolean isReadOnly();

174

}

175

```

176

177

**Usage Examples:**

178

179

```java

180

MVStore store = MVStore.open("data.mv");

181

MVMap<Integer, String> map = store.openMap("customers");

182

183

// Basic operations

184

map.put(1, "Alice Johnson");

185

map.put(2, "Bob Smith");

186

String customer = map.get(1); // "Alice Johnson"

187

188

// Conditional operations

189

String oldValue = map.putIfAbsent(3, "Charlie Brown"); // null if inserted

190

boolean replaced = map.replace(1, "Alice Johnson", "Alice Williams");

191

192

// Range queries

193

Integer firstId = map.firstKey(); // 1

194

Integer lastId = map.lastKey(); // 3

195

196

// Iteration

197

for (Map.Entry<Integer, String> entry : map.entrySet()) {

198

System.out.println(entry.getKey() + ": " + entry.getValue());

199

}

200

201

// Cursors for efficient range iteration

202

Cursor<Integer, String> cursor = map.cursor(2); // Start from key 2

203

while (cursor.hasNext()) {

204

System.out.println(cursor.next());

205

}

206

207

store.close();

208

```

209

210

### Transaction Support

211

212

MVStore provides built-in transaction support with MVCC.

213

214

```java { .api }

215

// Transaction methods in MVStore

216

public long getCurrentVersion();

217

public void rollback();

218

public void rollbackTo(long version);

219

220

// Versioned map access

221

public MVMap<K, V> openVersion(long version);

222

```

223

224

**Usage Examples:**

225

226

```java

227

MVStore store = MVStore.open("transactional.mv");

228

MVMap<String, Integer> accounts = store.openMap("accounts");

229

230

// Initial balances

231

accounts.put("alice", 1000);

232

accounts.put("bob", 500);

233

store.commit();

234

235

// Start transaction

236

long version = store.getCurrentVersion();

237

try {

238

// Transfer money

239

int aliceBalance = accounts.get("alice");

240

int bobBalance = accounts.get("bob");

241

242

if (aliceBalance >= 100) {

243

accounts.put("alice", aliceBalance - 100);

244

accounts.put("bob", bobBalance + 100);

245

store.commit(); // Commit transaction

246

} else {

247

store.rollbackTo(version); // Rollback on insufficient funds

248

}

249

} catch (Exception e) {

250

store.rollbackTo(version); // Rollback on error

251

throw e;

252

}

253

254

store.close();

255

```

256

257

## Advanced Data Types

258

259

### MVStore.Builder with Custom Data Types

260

261

```java { .api }

262

// Custom data type configuration

263

public <K, V> MVMap<K, V> openMap(String name, DataType keyType, DataType valueType);

264

265

public static class MapBuilder<M extends MVMap<K, V>, K, V> {

266

public MapBuilder<M, K, V> keyType(DataType keyType);

267

public MapBuilder<M, K, V> valueType(DataType valueType);

268

public M create();

269

}

270

```

271

272

**Available Data Types:**

273

274

```java { .api }

275

public interface DataType {

276

// Built-in data types

277

DataType STRING_TYPE = new StringDataType();

278

DataType BYTE_ARRAY_TYPE = new ByteArrayDataType();

279

DataType OBJECT_TYPE = new ObjectDataType();

280

281

// Type operations

282

int compare(Object a, Object b);

283

int getMemory(Object obj);

284

void write(WriteBuffer buff, Object obj);

285

Object read(ByteBuffer buff);

286

}

287

```

288

289

**Usage Examples:**

290

291

```java

292

// String keys, Object values

293

MVMap<String, Object> objectMap = store.openMap("objects",

294

new StringDataType(), new ObjectDataType());

295

296

// Custom serializable objects

297

MVMap<String, Customer> customerMap = store.openMap("customers",

298

new StringDataType(), new ObjectDataType());

299

300

customerMap.put("cust1", new Customer("Alice", "alice@example.com"));

301

Customer customer = customerMap.get("cust1");

302

```

303

304

## Specialized Maps

305

306

### RTRee Maps (Spatial Indexing)

307

308

MVStore includes spatial indexing support through R-tree implementation.

309

310

```java { .api }

311

public class MVRTreeMap<V> extends MVMap<Spatial, V> {

312

public static <V> MVRTreeMap<V> create(MVStore store, String name, DataType valueType);

313

314

// Spatial queries

315

public Iterator<V> findIntersectingKeys(Spatial bounds);

316

public Iterator<V> findContainedKeys(Spatial bounds);

317

318

// Spatial operations

319

public V add(Spatial key, V value);

320

public boolean remove(Spatial key, V value);

321

}

322

```

323

324

**Usage Examples:**

325

326

```java

327

import org.h2.mvstore.rtree.*;

328

329

MVStore store = MVStore.open("spatial.mv");

330

MVRTreeMap<String> rtree = MVRTreeMap.create(store, "locations", new StringDataType());

331

332

// Add spatial objects (rectangles defined by min/max x,y coordinates)

333

rtree.add(new SpatialKey(0, 0, 10, 10), "Location A");

334

rtree.add(new SpatialKey(5, 5, 15, 15), "Location B");

335

rtree.add(new SpatialKey(20, 20, 30, 30), "Location C");

336

337

// Spatial queries

338

SpatialKey searchArea = new SpatialKey(0, 0, 12, 12);

339

Iterator<String> results = rtree.findIntersectingKeys(searchArea);

340

while (results.hasNext()) {

341

System.out.println("Found: " + results.next());

342

}

343

344

store.close();

345

```

346

347

### StreamStore (Large Object Storage)

348

349

For storing large objects that don't fit efficiently in regular maps.

350

351

```java { .api }

352

public class StreamStore {

353

public StreamStore(MVStore store);

354

355

// Store large objects

356

public byte[] put(byte[] data);

357

public InputStream put(InputStream in) throws IOException;

358

359

// Retrieve large objects

360

public byte[] get(byte[] id);

361

public InputStream get(byte[] id) throws IOException;

362

363

// Remove large objects

364

public boolean remove(byte[] id);

365

366

// Stream information

367

public long length(byte[] id);

368

}

369

```

370

371

**Usage Examples:**

372

373

```java

374

MVStore store = MVStore.open("blobs.mv");

375

StreamStore streamStore = new StreamStore(store);

376

377

// Store large file

378

File largeFile = new File("large_document.pdf");

379

try (FileInputStream fis = new FileInputStream(largeFile)) {

380

InputStream result = streamStore.put(fis);

381

byte[] id = IOUtils.toByteArray(result); // Get identifier

382

383

// Later retrieve the file

384

try (InputStream retrieved = streamStore.get(id);

385

FileOutputStream fos = new FileOutputStream("retrieved_document.pdf")) {

386

IOUtils.copy(retrieved, fos);

387

}

388

}

389

390

store.close();

391

```

392

393

## Performance and Tuning

394

395

### Cache Configuration

396

397

```java

398

MVStore store = new MVStore.Builder()

399

.fileName("performance.mv")

400

.cacheSize(128) // 128 MB cache

401

.cacheConcurrency(16) // 16-way concurrent cache

402

.open();

403

404

// Runtime cache adjustments

405

store.setCacheSize(256); // Increase to 256 MB

406

```

407

408

### Auto-Commit Settings

409

410

```java

411

MVStore store = new MVStore.Builder()

412

.fileName("autocommit.mv")

413

.autoCommitBufferSize(2048) // 2 MB buffer before auto-commit

414

.open();

415

416

// Disable auto-commit for batch operations

417

MVStore batchStore = new MVStore.Builder()

418

.fileName("batch.mv")

419

.autoCommitDisabled()

420

.open();

421

422

// Manual commit control

423

MVMap<String, String> map = batchStore.openMap("data");

424

for (int i = 0; i < 100000; i++) {

425

map.put("key" + i, "value" + i);

426

if (i % 10000 == 0) {

427

batchStore.commit(); // Periodic commits

428

}

429

}

430

batchStore.commit();

431

```

432

433

### Compression

434

435

```java

436

// Enable compression for space efficiency

437

MVStore compressedStore = new MVStore.Builder()

438

.fileName("compressed.mv")

439

.compress() // Default compression

440

.open();

441

442

// High compression (slower but smaller files)

443

MVStore highCompressStore = new MVStore.Builder()

444

.fileName("high_compress.mv")

445

.compressHigh()

446

.open();

447

```

448

449

## Error Handling and Recovery

450

451

### Exception Handling

452

453

```java { .api }

454

public class MVStoreException extends RuntimeException {

455

public int getErrorCode();

456

public static final int ERROR_WRITING_FAILED = 1;

457

public static final int ERROR_FILE_CORRUPT = 2;

458

public static final int ERROR_FILE_LOCKED = 3;

459

public static final int ERROR_READING_FAILED = 4;

460

// ... other error codes

461

}

462

```

463

464

**Usage Examples:**

465

466

```java

467

try {

468

MVStore store = MVStore.open("problematic.mv");

469

MVMap<String, String> map = store.openMap("data");

470

471

// Operations that might fail

472

map.put("key", "value");

473

store.commit();

474

475

} catch (MVStoreException e) {

476

switch (e.getErrorCode()) {

477

case MVStoreException.ERROR_FILE_LOCKED:

478

System.err.println("Database file is locked by another process");

479

break;

480

case MVStoreException.ERROR_FILE_CORRUPT:

481

System.err.println("Database file is corrupted");

482

break;

483

case MVStoreException.ERROR_WRITING_FAILED:

484

System.err.println("Failed to write to database file");

485

break;

486

default:

487

System.err.println("MVStore error: " + e.getMessage());

488

}

489

}

490

```

491

492

### Panic Mode and Recovery

493

494

```java

495

MVStore store = MVStore.open("recovery.mv");

496

497

// Check for panic state

498

MVStoreException panicException = store.getPanicException();

499

if (panicException != null) {

500

System.err.println("Store is in panic mode: " + panicException.getMessage());

501

// Handle recovery or close immediately

502

store.closeImmediately();

503

return;

504

}

505

506

// Normal operations

507

MVMap<String, String> map = store.openMap("data");

508

// ... use map

509

510

store.close();

511

```

512

513

## Best Practices

514

515

### Resource Management

516

517

```java

518

public class MVStoreManager implements AutoCloseable {

519

private final MVStore store;

520

private final Map<String, MVMap<?, ?>> openMaps;

521

522

public MVStoreManager(String fileName) {

523

this.store = MVStore.open(fileName);

524

this.openMaps = new ConcurrentHashMap<>();

525

}

526

527

@SuppressWarnings("unchecked")

528

public <K, V> MVMap<K, V> getMap(String name, DataType keyType, DataType valueType) {

529

return (MVMap<K, V>) openMaps.computeIfAbsent(name,

530

n -> store.openMap(n, keyType, valueType));

531

}

532

533

public void commit() {

534

store.commit();

535

}

536

537

@Override

538

public void close() {

539

try {

540

store.close();

541

} catch (Exception e) {

542

System.err.println("Error closing MVStore: " + e.getMessage());

543

}

544

}

545

}

546

547

// Usage with try-with-resources

548

try (MVStoreManager manager = new MVStoreManager("app.mv")) {

549

MVMap<String, String> config = manager.getMap("config",

550

new StringDataType(), new StringDataType());

551

552

config.put("app.version", "1.0.0");

553

config.put("app.name", "MyApplication");

554

555

manager.commit();

556

} // Automatically closes store

557

```

558

559

### Concurrent Access

560

561

```java

562

public class ConcurrentMVStore {

563

private final MVStore store;

564

private final MVMap<String, String> data;

565

private final ReadWriteLock lock = new ReentrantReadWriteLock();

566

567

public ConcurrentMVStore(String fileName) {

568

this.store = MVStore.open(fileName);

569

this.data = store.openMap("data");

570

}

571

572

public String get(String key) {

573

lock.readLock().lock();

574

try {

575

return data.get(key);

576

} finally {

577

lock.readLock().unlock();

578

}

579

}

580

581

public void put(String key, String value) {

582

lock.writeLock().lock();

583

try {

584

data.put(key, value);

585

store.commit();

586

} finally {

587

lock.writeLock().unlock();

588

}

589

}

590

591

public void close() {

592

lock.writeLock().lock();

593

try {

594

store.close();

595

} finally {

596

lock.writeLock().unlock();

597

}

598

}

599

}

600

```