@@ -4,6 +4,7 @@ import { type StreamWriter } from '../storage/StreamWriter';
44export class AlternatingFileWriter {
55 private _streamId ?: string ;
66 private _count = 0 ;
7+ private _size = 0 ;
78 private _disposed = false ;
89
910 private readonly _streamWriter : StreamWriter ;
@@ -13,12 +14,13 @@ export class AlternatingFileWriter {
1314 private _currentAppendedLog ?: string ;
1415
1516 constructor (
17+ private readonly _fileSystem : FileSystem ,
1618 private readonly _mainFile : string ,
1719 private readonly _fallbackFile : string ,
18- private readonly _fileCapacity : number ,
19- private readonly _fileSystem : FileSystem ,
20+ private readonly _maxLines : number ,
21+ private readonly _maxSize ?: number ,
2022 ) {
21- if ( this . _fileCapacity <= 0 ) {
23+ if ( this . _maxLines <= 0 ) {
2224 throw new Error ( 'File capacity may not be less or equal to 0.' ) ;
2325 }
2426 this . _streamWriter = this . _fileSystem . streamWriter ;
@@ -42,7 +44,8 @@ export class AlternatingFileWriter {
4244 return ;
4345 }
4446
45- this . prepareBreadcrumbStream ( ) ;
47+ const appendLength = this . _currentAppendedLog . length + 1 ;
48+ this . prepareBreadcrumbStream ( appendLength ) ;
4649
4750 if ( ! this . _streamId ) {
4851 this . _logQueue . unshift ( this . _currentAppendedLog ) ;
@@ -53,10 +56,39 @@ export class AlternatingFileWriter {
5356 // if the queue is full and we can save more item in a batch
5457 // try to save as much as possible to speed up potential native operations
5558 this . _count += 1 ;
59+ this . _size += appendLength ;
60+
5661 const logsToAppend = [ this . _currentAppendedLog ] ;
5762
58- const restAppendingLogs = this . _logQueue . splice ( 0 , this . _fileCapacity - this . _count ) ;
63+ let logsToTake = 0 ;
64+ let currentCount = this . _count ;
65+ let currentSize = this . _size ;
66+
67+ for ( let i = 0 ; i < this . _logQueue . length ; i ++ ) {
68+ const log = this . _logQueue [ i ] ;
69+ if ( ! log ) {
70+ continue ;
71+ }
72+
73+ const logLength = log . length + 1 ;
74+
75+ if ( currentCount + 1 > this . _maxLines ) {
76+ break ;
77+ }
78+
79+ if ( this . _maxSize && currentSize + logLength >= this . _maxSize ) {
80+ break ;
81+ }
82+
83+ logsToTake ++ ;
84+ currentCount ++ ;
85+ currentSize += logLength ;
86+ }
87+
88+ const restAppendingLogs = this . _logQueue . splice ( 0 , logsToTake ) ;
5989 this . _count = this . _count + restAppendingLogs . length ;
90+ this . _size += restAppendingLogs . reduce ( ( sum , l ) => sum + l . length + 1 , 0 ) ;
91+
6092 logsToAppend . push ( ...restAppendingLogs ) ;
6193
6294 this . _streamWriter
@@ -76,24 +108,32 @@ export class AlternatingFileWriter {
76108 } ) ;
77109 }
78110
79- private prepareBreadcrumbStream ( ) {
111+ private prepareBreadcrumbStream ( newSize : number ) {
80112 if ( ! this . _streamId ) {
81113 this . _streamId = this . _streamWriter . create ( this . _mainFile ) ;
82- } else if ( this . _count >= this . _fileCapacity ) {
114+ } else if ( this . _count >= this . _maxLines || ( this . _maxSize && this . _size + newSize >= this . _maxSize ) ) {
115+ this . switchFile ( ) ;
116+ }
117+ }
118+
119+ private switchFile ( ) {
120+ if ( this . _streamId ) {
83121 const closeResult = this . _streamWriter . close ( this . _streamId ) ;
84122 if ( ! closeResult ) {
85123 return ;
86124 }
87- this . _streamId = undefined ;
125+ }
88126
89- const renameResult = this . _fileSystem . copySync ( this . _mainFile , this . _fallbackFile ) ;
90- if ( ! renameResult ) {
91- return ;
92- }
93- this . _streamId = this . _streamWriter . create ( this . _mainFile ) ;
127+ this . _streamId = undefined ;
94128
95- this . _count = 0 ;
129+ const renameResult = this . _fileSystem . copySync ( this . _mainFile , this . _fallbackFile ) ;
130+ if ( ! renameResult ) {
131+ return ;
96132 }
133+ this . _streamId = this . _streamWriter . create ( this . _mainFile ) ;
134+
135+ this . _count = 0 ;
136+ this . _size = 0 ;
97137 }
98138
99139 public dispose ( ) {
0 commit comments