@@ -98,6 +98,10 @@ function KeyValue(name, size) {
9898 t . write ( id , prepare , callback ) ;
9999 } ;
100100
101+ t . $cb_link = function ( id , toid , type , callback ) {
102+ t . link ( id , toid , type , callback ) ;
103+ } ;
104+
101105 F . path . verify ( 'databases' ) ;
102106 t . open ( ) ;
103107}
@@ -298,7 +302,7 @@ RP.close = function() {
298302 return self ;
299303} ;
300304
301- RP . insert = function ( value , callback , edgesid , id ) {
305+ RP . insert = function ( value , callback , id ) {
302306
303307 var self = this ;
304308 if ( self . $ready ) {
@@ -330,16 +334,20 @@ RP.insert = function(value, callback, edgesid, id) {
330334 var val = U . createBuffer ( type === 4 ? JSON . stringify ( value ) : value ) ;
331335
332336 // 1b TYPE, 4b CONNECTIONSID, 2b DATA-SIZE, DATA
333- var res = U . createBufferSize ( self . header . size ) . fill ( val , 8 , val . length + 8 ) ;
334- res . writeInt8 ( type ) ;
335- res . writeInt32BE ( edgesid || 0 , 1 ) ;
336- res . writeInt16BE ( val . length , 5 ) ;
337+ var res = insert ? U . createBufferSize ( self . header . size ) . fill ( val , 8 , val . length + 8 ) : U . createBufferSize ( self . header . size - 5 ) . fill ( val , 3 , val . length + 3 ) ;
338+
339+ if ( insert ) {
340+ res . writeInt8 ( type , 0 ) ;
341+ res . writeInt32BE ( 0 , 1 ) ;
342+ }
343+
344+ res . writeInt16BE ( val . length , insert ? 5 : 0 ) ;
337345
338346 if ( insert ) {
339347 self . bufferappend . push ( res ) ;
340348 self . $events . insert && self . emit ( 'insert' , id , value ) ;
341349 } else {
342- self . bufferupdate . push ( { buf : res , pos : id } ) ;
350+ self . bufferupdate . push ( { buf : res , pos : id , type : type } ) ;
343351 self . $events . update && self . emit ( 'update' , id , value ) ;
344352 }
345353
@@ -354,37 +362,147 @@ RP.insert = function(value, callback, edgesid, id) {
354362 throw new Error ( ERRREADY . format ( self . name ) ) ;
355363} ;
356364
357- RP . write = function ( id , prepare , callback ) {
365+ RP . getLinkId = function ( id , callback ) {
366+ var self = this ;
367+ var pos = 200 + ( ( id - 1 ) * self . header . size ) ;
368+ var tmp = U . createBufferSize ( 4 ) ;
369+ Fs . read ( self . fd , tmp , 0 , tmp . length , pos + 1 , ( err ) => callback ( err , tmp . readInt32BE ( 0 ) ) ) ;
370+ return self ;
371+ } ;
358372
373+ RP . setLinkId = function ( id , linkid , callback ) {
359374 var self = this ;
360- if ( self . $ready ) {
375+ var pos = 200 + ( ( id - 1 ) * self . header . size ) ;
376+ var buf = U . createBufferSize ( 4 ) ;
377+ buf . writeInt32BE ( linkid ) ;
378+ Fs . write ( self . fd , buf , 0 , buf . length , pos + 1 , function ( err , size ) {
379+ callback && callback ( err ) ;
380+ } ) ;
381+ return self ;
382+ } ;
361383
362- var insert = ! id ;
384+ RP . pushLinkId = function ( id , toid , type , callback , parentid ) {
363385
364- if ( insert ) {
365- if ( self . meta . removed && self . meta . removed . length ) {
366- id = self . removed . shift ( ) ;
367- insert = false ;
368- } else
369- id = self . index ++ ;
370- }
386+ var self = this ;
387+ var pos = 200 + ( ( id - 1 ) * self . header . size ) ;
388+ var buf = U . createBufferSize ( self . header . size ) ;
389+ var max = ( self . header . size - 9 ) / 5 >> 0 ;
371390
372- var res = U . createBufferSize ( self . header . size ) ;
391+ if ( id == null ) {
373392
374- // res.writeInt8(type);
375- // res.writeInt32BE(edgesid || 0, 1);
393+ id = self . index ++ ;
376394
377- prepare ( res ) ;
395+ buf . writeInt8 ( 5 ) ; // type, 1b
396+ buf . writeInt32BE ( parentid || 0 , 1 ) ; // link, 4b
397+ buf . writeInt16BE ( 1 , 6 ) ; // count, 2b
378398
399+ // TYPE, ID
400+ buf . writeInt8 ( type , 9 ) ;
401+ buf . writeInt32BE ( toid , 10 ) ;
402+
403+ self . bufferappend . push ( buf ) ;
379404 self . flush ( ) ;
380405 callback && callback ( null , id ) ;
381- return id ;
406+
407+ } else {
408+
409+ Fs . read ( self . fd , buf , 0 , buf . length , pos , function ( err ) {
410+
411+ if ( err ) {
412+ callback ( err ) ;
413+ return ;
414+ } else if ( buf [ 0 ] !== 5 ) {
415+ callback ( new Error ( 'Invalid value type for linking.' ) ) ;
416+ return ;
417+ }
418+
419+ var count = buf . readInt16BE ( 6 ) ;
420+ if ( count + 1 >= max ) {
421+ // we need to create new record because existing buffer is full
422+ self . pushLinkId ( 0 , toid , type , function ( err , id ) {
423+ // we return new id
424+ callback && callback ( err , id ) ;
425+ } , id ) ;
426+ return ;
427+ }
428+
429+ buf . writeInt16BE ( count + 1 , 6 ) ;
430+
431+ var off = 9 + ( count * 5 ) ;
432+ buf . writeInt8 ( type , off ) ;
433+ buf . writeInt32BE ( toid , off + 1 ) ;
434+
435+ Fs . write ( self . fd , buf , 0 , buf . length , pos , function ( err ) {
436+ callback && callback ( err , id ) ;
437+ } ) ;
438+ } ) ;
382439 }
383440
384- if ( callback )
385- setTimeout ( self . $cb_write , 100 , id , prepare , callback ) ;
386- else
387- throw new Error ( ERRREADY . format ( self . name ) ) ;
441+ return self ;
442+ } ;
443+
444+ RP . link = function ( fromid , toid , type , callback ) {
445+ var self = this ;
446+ if ( self . $ready ) {
447+
448+ var async = [ ] ;
449+ var aid = 0 ;
450+ var bid = 0 ;
451+
452+ async . push ( function ( next ) {
453+ self . getLinkId ( fromid , function ( err , id ) {
454+ aid = err ? null : id ;
455+ next ( ) ;
456+ } ) ;
457+ } ) ;
458+
459+ async . push ( function ( next ) {
460+ self . getLinkId ( toid , function ( err , id ) {
461+ bid = err ? null : id ;
462+ next ( ) ;
463+ } ) ;
464+ } ) ;
465+
466+ async . push ( function ( next ) {
467+ if ( aid == null ) {
468+ async . length = 0 ;
469+ next = null ;
470+ callback ( new Error ( 'Value (from) with "{0}" id does not exist' . format ( fromid ) ) ) ;
471+ } else if ( bid == null ) {
472+ async . length = 0 ;
473+ next = null ;
474+ callback ( new Error ( 'Value (to) with "{0}" id does not exist' . format ( toid ) ) ) ;
475+ } else
476+ next ( ) ;
477+ } ) ;
478+
479+ async . push ( function ( next ) {
480+ self . pushLinkId ( aid == 0 ? null : aid , toid , type , function ( err , id ) {
481+ if ( aid !== id )
482+ self . setLinkId ( fromid , id , next ) ;
483+ else
484+ next ( ) ;
485+ } ) ;
486+ } ) ;
487+
488+ async . push ( function ( next ) {
489+ self . pushLinkId ( bid == 0 ? null : bid , fromid , type , function ( err , id ) {
490+ if ( bid !== id )
491+ self . setLinkId ( toid , id , next ) ;
492+ else
493+ next ( ) ;
494+ } ) ;
495+ } ) ;
496+
497+ async . async ( function ( ) {
498+ console . log ( 'DONE' ) ;
499+ callback && callback ( null ) ;
500+ } ) ;
501+
502+ } else
503+ setTimeout ( self . $cb_link , 100 , fromid , toid , type , callback ) ;
504+
505+ return self ;
388506} ;
389507
390508RP . flush = function ( ) {
@@ -397,7 +515,8 @@ RP.flush = function() {
397515 if ( self . bufferupdate . length ) {
398516 self . writing = true ;
399517 var doc = self . bufferupdate . shift ( ) ;
400- Fs . write ( self . fd , doc . buf , 0 , doc . buf . length , 200 + ( doc . pos * self . header . size ) , self . $cb_writeupdate ) ;
518+ var offset = 200 + ( doc . pos * self . header . size ) ;
519+ Fs . write ( self . fd , doc . buf , 0 , doc . buf . length , offset + 5 , self . $cb_writeupdate ) ;
401520 return self ;
402521 } else if ( ! self . bufferappend . length )
403522 return self ;
@@ -421,9 +540,17 @@ RP.remove = function(id) {
421540 return self ;
422541} ;
423542
424- RP . update = function ( id , value , callback , edgesid ) {
543+ RP . update = function ( id , value , callback ) {
544+ var self = this ;
545+ self . insert ( value , callback , id - 1 ) ;
546+ return self ;
547+ } ;
548+
549+ RP . traverse = function ( id , type , callback ) {
425550 var self = this ;
426- self . insert ( value , callback , edgesid , id - 1 ) ;
551+ self . read ( id , function ( err , doc , linkid ) {
552+ console . log ( arguments ) ;
553+ } ) ;
427554 return self ;
428555} ;
429556
@@ -432,21 +559,33 @@ RP.get = RP.read = function(id, callback) {
432559 if ( self . $ready ) {
433560 var buf = U . createBufferSize ( self . header . size ) ;
434561 Fs . read ( self . fd , buf , 0 , buf . length , 200 + ( ( id - 1 ) * self . header . size ) , function ( err , size ) {
435- var edgesid = buf . readInt32BE ( 1 ) ;
436- var data = size ? buf . slice ( 8 , buf . readInt16BE ( 5 ) + 8 ) . toString ( 'utf8' ) : null ;
562+ var linkid = buf . readInt32BE ( 1 ) ;
563+ var data = buf [ 0 ] !== 5 ? ( size ? buf . slice ( 8 , buf . readInt16BE ( 5 ) + 8 ) . toString ( 'utf8' ) : null ) : null ;
437564 switch ( buf [ 0 ] ) {
565+ case 5 : // LINKS
566+
567+ var count = buf . readInt16BE ( 6 ) ; // 2b
568+ var links = [ ] ;
569+
570+ for ( var i = 0 ; i < count ; i ++ ) {
571+ var pos = 9 + ( i * 5 ) ;
572+ links . push ( { type : buf [ pos ] , id : buf . readInt32BE ( pos + 1 ) } ) ;
573+ }
574+
575+ callback ( err , links , linkid ) ;
576+ break ;
438577 case 4 : // JSON
439- callback ( err , data ? data . parseJSON ( true ) : null , edgesid ) ;
578+ callback ( err , data ? data . parseJSON ( true ) : null , linkid ) ;
440579 break ;
441580 case 3 : // BOOLEAN
442- callback ( err , data ? data === 'true' : false , edgesid ) ;
581+ callback ( err , data ? data === 'true' : false , linkid ) ;
443582 break ;
444583 case 2 : // NUMBER
445- callback ( err , data ? + data : 0 , edgesid ) ;
584+ callback ( err , data ? + data : 0 , linkid ) ;
446585 break ;
447586 case 1 : // STRING
448587 default :
449- callback ( err , data ? data : '' , edgesid ) ;
588+ callback ( err , data ? data : '' , linkid ) ;
450589 break ;
451590 }
452591 } ) ;
@@ -455,16 +594,6 @@ RP.get = RP.read = function(id, callback) {
455594 return self ;
456595} ;
457596
458- RP . read2 = function ( id , callback ) {
459- var self = this ;
460- if ( self . $ready ) {
461- var buf = U . createBufferSize ( self . header . size ) ;
462- Fs . read ( self . fd , buf , 0 , buf . length , 200 + ( ( id - 1 ) * self . header . size ) , err => callback ( err , buf ) ) ;
463- } else
464- setTimeout ( self . $cb_read2 , 100 , id , callback ) ;
465- return self ;
466- } ;
467-
468597RP . browse = function ( beg , end , callback , done ) {
469598 var self = this ;
470599
@@ -496,6 +625,8 @@ RP.browse = function(beg, end, callback, done) {
496625 var data = buf . slice ( 4 , size ) . toString ( 'utf8' ) ;
497626
498627 switch ( buf [ 0 ] ) {
628+ case 5 : // LINKS
629+ break ;
499630 case 4 : // JSON
500631 output = callback ( err , data . parseJSON ( true ) , counter ) ;
501632 break ;
0 commit comments