dataply 0.0.26-alpha.4 → 0.0.26-alpha.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,6 @@
1
1
  import { type DataplyOptions, type DataplyMetadata } from '../types';
2
2
  import { type IHookall } from 'hookall';
3
+ import { Ryoiki } from 'ryoiki';
3
4
  import { PageFileSystem } from './PageFileSystem';
4
5
  import { RowTableEngine } from './RowTableEngine';
5
6
  import { TextCodec } from '../utils/TextCodec';
@@ -47,7 +48,23 @@ export declare class DataplyAPI {
47
48
  private txIdCounter;
48
49
  /** Promise-chain mutex for serializing write operations */
49
50
  private writeQueue;
51
+ /** Lock manager. Used for managing transactions */
52
+ protected readonly latcher: Ryoiki;
50
53
  constructor(file: string, options: DataplyOptions);
54
+ /**
55
+ * Acquire a read lock on the given page ID and execute the given function.
56
+ * @param pageId Page ID to acquire a read lock on
57
+ * @param fn Function to execute while holding the read lock
58
+ * @returns The result of the given function
59
+ */
60
+ latchReadLock<T>(pageId: number, fn: () => Promise<T>): Promise<T>;
61
+ /**
62
+ * Acquire a write lock on the given page ID and execute the given function.
63
+ * @param pageId Page ID to acquire a write lock on
64
+ * @param fn Function to execute while holding the write lock
65
+ * @returns The result of the given function
66
+ */
67
+ latchWriteLock<T>(pageId: number, fn: () => Promise<T>): Promise<T>;
51
68
  /**
52
69
  * Verifies if the page file is a valid Dataply file.
53
70
  * The metadata page must be located at the beginning of the Dataply file.
@@ -1,5 +1,6 @@
1
1
  import type { IndexPage, MetadataPage, DataplyOptions } from '../types';
2
2
  import type { Transaction } from './transaction/Transaction';
3
+ import { AsyncMVCCTransaction } from 'mvcc-api';
3
4
  import { PageManagerFactory } from './Page';
4
5
  import { WALManager } from './WALManager';
5
6
  import { PageMVCCStrategy } from './PageMVCCStrategy';
@@ -17,6 +18,7 @@ export declare class PageFileSystem {
17
18
  protected readonly walManager: WALManager | null;
18
19
  protected readonly pageManagerFactory: PageManagerFactory;
19
20
  protected readonly pageStrategy: PageMVCCStrategy;
21
+ protected readonly rootTransaction: AsyncMVCCTransaction<PageMVCCStrategy, number, Uint8Array>;
20
22
  protected readonly logger: Logger;
21
23
  /** 글로벌 동기화(체크포인트/커밋)를 위한 Mutex */
22
24
  private lockPromise;
@@ -39,6 +41,10 @@ export declare class PageFileSystem {
39
41
  * Returns the page strategy for transaction use.
40
42
  */
41
43
  getPageStrategy(): PageMVCCStrategy;
44
+ /**
45
+ * Returns the root MVCC transaction.
46
+ */
47
+ getRootTransaction(): AsyncMVCCTransaction<PageMVCCStrategy, number, Uint8Array>;
42
48
  /**
43
49
  * Updates the bitmap status for a specific page.
44
50
  * @param pageId The ID of the page to update
@@ -134,16 +140,10 @@ export declare class PageFileSystem {
134
140
  * @param tx Transaction
135
141
  */
136
142
  setFreePage(pageId: number, tx: Transaction): Promise<void>;
137
- /**
138
- * WAL에 커밋합니다.
139
- * @param dirtyPages 변경된 페이지들
140
- */
141
- commitToWAL(dirtyPages: Map<number, Uint8Array>): Promise<void>;
142
143
  /**
143
144
  * 체크포인트를 수행합니다.
144
- * 1. 메모리의 더티 페이지를 DB 파일에 기록 (Flush)
145
- * 2. DB 파일 물리적 동기화 (Sync/fsync)
146
- * 3. WAL 로그 파일 비우기 (Clear/Truncate)
145
+ * 1. DB 파일 물리적 동기화 (Sync/fsync)
146
+ * 2. WAL 로그 파일 비우기 (Clear/Truncate)
147
147
  */
148
148
  checkpoint(): Promise<void>;
149
149
  /**
@@ -1,23 +1,20 @@
1
+ import { AsyncMVCCStrategy } from 'mvcc-api';
1
2
  /**
2
3
  * 페이지 수준 MVCC Strategy.
3
4
  * mvcc-api의 AsyncMVCCStrategy를 상속하여 디스크 I/O를 담당합니다.
5
+ * 캐시 및 버퍼 관리는 mvcc-api의 AsyncMVCCTransaction이 담당합니다.
4
6
  *
5
7
  * 키: 페이지 ID (number)
6
8
  * 값: 페이지 데이터 (Uint8Array)
7
9
  */
8
- export declare class PageMVCCStrategy {
10
+ export declare class PageMVCCStrategy extends AsyncMVCCStrategy<number, Uint8Array> {
9
11
  private readonly fileHandle;
10
12
  private readonly pageSize;
11
- /** LRU 캐시 (페이지 ID -> 페이지 데이터) */
12
- private readonly cache;
13
- /** 디스크에 기록되지 않은 변경된 페이지들 (페이지 ID -> 페이지 데이터) */
14
- private readonly dirtyPages;
15
13
  /** 파일 크기 (논리적) */
16
14
  private fileSize;
17
- constructor(fileHandle: number, pageSize: number, cacheCapacity: number);
15
+ constructor(fileHandle: number, pageSize: number);
18
16
  /**
19
17
  * 디스크에서 페이지를 읽습니다.
20
- * 캐시에 있으면 캐시에서 반환합니다.
21
18
  * @param pageId 페이지 ID
22
19
  * @returns 페이지 데이터
23
20
  */
@@ -29,22 +26,7 @@ export declare class PageMVCCStrategy {
29
26
  */
30
27
  write(pageId: number, data: Uint8Array): Promise<void>;
31
28
  /**
32
- * 더티 페이지들을 메인 디스크 파일에 일괄 기록합니다.
33
- * WAL 체크포인트 시점에 호출되어야 합니다.
34
- */
35
- flush(): Promise<void>;
36
- /**
37
- * 지정된 페이지들만 디스크에 기록합니다.
38
- * WAL 없이 트랜잭션 커밋 시, 해당 트랜잭션의 dirty pages만 선택적으로 flush합니다.
39
- * @param pages 기록할 페이지 맵 (PageID -> PageData)
40
- */
41
- flushPages(pages: Map<number, Uint8Array>): Promise<void>;
42
- /**
43
- * 메인 DB 파일의 물리적 동기화를 수행합니다 (fsync).
44
- */
45
- sync(): Promise<void>;
46
- /**
47
- * 페이지 삭제 (실제로는 캐시에서만 제거)
29
+ * 페이지 삭제.
48
30
  * 실제 페이지 해제는 상위 레이어(FreeList)에서 관리합니다.
49
31
  * @param pageId 페이지 ID
50
32
  */
@@ -56,13 +38,13 @@ export declare class PageMVCCStrategy {
56
38
  */
57
39
  exists(pageId: number): Promise<boolean>;
58
40
  /**
59
- * 현재 파일 크기 반환
41
+ * 메인 DB 파일의 물리적 동기화를 수행합니다 (fsync).
60
42
  */
61
- getFileSize(): number;
43
+ sync(): Promise<void>;
62
44
  /**
63
- * 캐시 초기화
45
+ * 현재 파일 크기 반환
64
46
  */
65
- clearCache(): void;
47
+ getFileSize(): number;
66
48
  private _readFromDisk;
67
49
  private _writeToDisk;
68
50
  }
@@ -1,5 +1,5 @@
1
1
  import type { DataplyMetadata, DataplyOptions } from '../types';
2
- import { BPTreeAsync } from 'serializable-bptree';
2
+ import { BPTreePureAsync } from 'serializable-bptree';
3
3
  import { RowIdentifierStrategy } from './RowIndexStrategy';
4
4
  import { PageFileSystem } from './PageFileSystem';
5
5
  import { Row } from './Row';
@@ -12,7 +12,7 @@ export declare class RowTableEngine {
12
12
  protected readonly pfs: PageFileSystem;
13
13
  protected readonly txContext: TransactionContext;
14
14
  protected readonly options: Required<DataplyOptions>;
15
- protected readonly bptree: BPTreeAsync<number, number>;
15
+ protected readonly bptree: BPTreePureAsync<number, number>;
16
16
  protected readonly strategy: RowIdentifierStrategy;
17
17
  protected readonly order: number;
18
18
  protected readonly factory: PageManagerFactory;
@@ -27,13 +27,6 @@ export declare class RowTableEngine {
27
27
  private readonly logger;
28
28
  private initialized;
29
29
  constructor(pfs: PageFileSystem, txContext: TransactionContext, options: Required<DataplyOptions>, logger: Logger);
30
- /**
31
- * Retrieves the BPTree transaction associated with the given transaction.
32
- * If it doesn't exist, it creates a new one and registers commit/rollback hooks.
33
- * @param tx Dataply transaction
34
- * @returns BPTree transaction
35
- */
36
- private getBPTreeTransaction;
37
30
  /**
38
31
  * Initializes the B+ Tree.
39
32
  */
@@ -1,11 +1,12 @@
1
1
  import type { PageFileSystem } from '../PageFileSystem';
2
- import { BPTreeAsyncTransaction } from 'serializable-bptree';
2
+ import type { AsyncMVCCTransaction } from 'mvcc-api';
3
+ import type { PageMVCCStrategy } from '../PageMVCCStrategy';
3
4
  import { LockManager } from './LockManager';
4
5
  import { TransactionContext } from './TxContext';
5
- import { PageMVCCStrategy } from '../PageMVCCStrategy';
6
6
  /**
7
7
  * Transaction class.
8
8
  * Manages the lifecycle and resources of a database transaction.
9
+ * Internally wraps a nested AsyncMVCCTransaction for snapshot isolation.
9
10
  */
10
11
  export declare class Transaction {
11
12
  readonly context: TransactionContext;
@@ -17,47 +18,28 @@ export declare class Transaction {
17
18
  private heldLocks;
18
19
  /** Held page locks (PageID -> LockID) */
19
20
  private pageLocks;
20
- /** Dirty Pages modified by the transaction: PageID -> Modified Page Buffer */
21
- private dirtyPages;
22
- /** Undo pages: PageID -> Original Page Buffer (Snapshot) */
23
- private undoPages;
24
- /** BPTree Transaction instance */
25
- private bptreeTx?;
26
- /** Whether the BPTree transaction is dirty */
27
- private bptreeDirty;
28
21
  /** List of callbacks to execute on commit */
29
22
  private commitHooks;
30
- /** Page MVCC Strategy for disk access */
31
- private readonly pageStrategy;
23
+ /** Nested MVCC Transaction for snapshot isolation (lazy init) */
24
+ private mvccTx;
25
+ /** Root MVCC Transaction reference */
26
+ private readonly rootTx;
32
27
  /** Release function for global write lock, set by DataplyAPI */
33
28
  private _writeLockRelease;
34
29
  /**
35
30
  * @param id Transaction ID
36
31
  * @param context Transaction context
37
- * @param pageStrategy Page MVCC Strategy for disk I/O
32
+ * @param rootTx Root MVCC Transaction
38
33
  * @param lockManager LockManager instance
39
34
  * @param pfs Page File System
40
35
  */
41
- constructor(id: number, context: TransactionContext, pageStrategy: PageMVCCStrategy, lockManager: LockManager, pfs: PageFileSystem);
36
+ constructor(id: number, context: TransactionContext, rootTx: AsyncMVCCTransaction<PageMVCCStrategy, number, Uint8Array>, lockManager: LockManager, pfs: PageFileSystem);
42
37
  /**
43
- * Sets the BPTree transaction.
44
- * @param tx BPTree transaction
38
+ * Lazily initializes the nested MVCC transaction.
39
+ * This ensures the snapshot is taken at the time of first access,
40
+ * picking up the latest committed root version.
45
41
  */
46
- __setBPTreeTransaction(tx: BPTreeAsyncTransaction<number, number>): void;
47
- /**
48
- * Returns the BPTree transaction.
49
- * @returns BPTree transaction
50
- */
51
- __getBPTreeTransaction(): BPTreeAsyncTransaction<number, number> | undefined;
52
- /**
53
- * Marks the BPTree transaction as dirty.
54
- */
55
- __markBPTreeDirty(): void;
56
- /**
57
- * Returns whether the BPTree transaction is dirty.
58
- * @returns True if dirty
59
- */
60
- __isBPTreeDirty(): boolean;
42
+ private ensureMvccTx;
61
43
  /**
62
44
  * Registers a commit hook.
63
45
  * @param hook Function to execute
@@ -73,13 +55,13 @@ export declare class Transaction {
73
55
  */
74
56
  __hasWriteLockRelease(): boolean;
75
57
  /**
76
- * Reads a page. Uses dirty buffer if available, otherwise disk.
58
+ * Reads a page through the MVCC transaction.
77
59
  * @param pageId Page ID
78
60
  * @returns Page data
79
61
  */
80
62
  readPage(pageId: number): Promise<Uint8Array>;
81
63
  /**
82
- * Writes a page to the transaction buffer.
64
+ * Writes a page through the MVCC transaction.
83
65
  * @param pageId Page ID
84
66
  * @param data Page data
85
67
  */
@@ -97,10 +79,6 @@ export declare class Transaction {
97
79
  * Rolls back the transaction.
98
80
  */
99
81
  rollback(): Promise<void>;
100
- /**
101
- * Returns the dirty pages map.
102
- */
103
- __getDirtyPages(): Map<number, Uint8Array>;
104
82
  /**
105
83
  * Releases all locks.
106
84
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dataply",
3
- "version": "0.0.26-alpha.4",
3
+ "version": "0.0.26-alpha.6",
4
4
  "description": "A lightweight storage engine for Node.js with support for MVCC, WAL.",
5
5
  "license": "MIT",
6
6
  "author": "izure <admin@izure.org>",
@@ -47,8 +47,8 @@
47
47
  "dependencies": {
48
48
  "cache-entanglement": "^1.7.1",
49
49
  "hookall": "^2.2.0",
50
- "mvcc-api": "^1.3.6",
50
+ "mvcc-api": "^1.3.7",
51
51
  "ryoiki": "^1.2.0",
52
- "serializable-bptree": "^8.4.1"
52
+ "serializable-bptree": "^9.0.0"
53
53
  }
54
- }
54
+ }