Преглед на файлове

optimize table lookup performance

xuty преди 4 години
родител
ревизия
41fc510709
променени са 3 файла, в които са добавени 42 реда и са изтрити 4 реда
  1. 3 2
      lib/terminal/ansi.dart
  2. 7 2
      lib/terminal/csi.dart
  3. 32 0
      lib/utli/lookup_table.dart

+ 3 - 2
lib/terminal/ansi.dart

@@ -3,6 +3,7 @@ import 'dart:collection';
 import 'package:xterm/terminal/csi.dart';
 import 'package:xterm/terminal/osc.dart';
 import 'package:xterm/terminal/terminal.dart';
+import 'package:xterm/utli/lookup_table.dart';
 
 /// Handler of terminal sequences. Returns true if the sequence is consumed,
 /// false to indicate that the sequence is not completed and no charater is
@@ -34,7 +35,7 @@ bool ansiHandler(Queue<int> queue, Terminal terminal) {
   return true;
 }
 
-final _ansiHandlers = <int, AnsiHandler>{
+final _ansiHandlers = FastLookupTable({
   '['.codeUnitAt(0): csiHandler,
   ']'.codeUnitAt(0): oscHandler,
   '7'.codeUnitAt(0): _ansiSaveCursorHandler,
@@ -52,7 +53,7 @@ final _ansiHandlers = <int, AnsiHandler>{
   '+'.codeUnitAt(0): _voidHandler(1), // TODO: G3 (vt220)
   '>'.codeUnitAt(0): _voidHandler(0), // TODO: Normal Keypad
   '='.codeUnitAt(0): _voidHandler(0), // TODO: Application Keypad
-};
+});
 
 AnsiHandler _voidHandler(int sequenceLength) {
   return (queue, terminal) {

+ 7 - 2
lib/terminal/csi.dart

@@ -3,10 +3,11 @@ import 'dart:collection';
 import 'package:xterm/terminal/modes.dart';
 import 'package:xterm/terminal/sgr.dart';
 import 'package:xterm/terminal/terminal.dart';
+import 'package:xterm/utli/lookup_table.dart';
 
 typedef CsiSequenceHandler = void Function(CSI, Terminal);
 
-final _csiHandlers = <int, CsiSequenceHandler>{
+final _csiHandlers = FastLookupTable({
   'c'.codeUnitAt(0): csiSendDeviceAttributesHandler,
   'd'.codeUnitAt(0): csiLinePositionAbsolute,
   'f'.codeUnitAt(0): csiCursorPositionHandler,
@@ -34,7 +35,7 @@ final _csiHandlers = <int, CsiSequenceHandler>{
   'T'.codeUnitAt(0): csiScrollDownHandler,
   'X'.codeUnitAt(0): csiEraseCharactersHandler,
   '@'.codeUnitAt(0): csiInsertBlankCharactersHandler,
-};
+});
 
 class CSI {
   CSI({
@@ -53,6 +54,8 @@ class CSI {
   }
 }
 
+/// Parse a CSI from the head of the queue. Return null if the CSI isn't
+/// complete.
 CSI? _parseCsi(Queue<int> queue) {
   final paramBuffer = StringBuffer();
   final intermediates = <int>[];
@@ -98,6 +101,8 @@ CSI? _parseCsi(Queue<int> queue) {
   }
 }
 
+/// CSI - Control Sequence Introducer: sequence starting with ESC [ (7bit) or
+/// CSI (\x9B, 8bit)
 bool csiHandler(Queue<int> queue, Terminal terminal) {
   final csi = _parseCsi(queue);
 

+ 32 - 0
lib/utli/lookup_table.dart

@@ -0,0 +1,32 @@
+/// Fixed-size list based lookup table, optimized for small positive integer
+/// keys.
+class FastLookupTable<T> {
+  FastLookupTable(Map<int, T> data) {
+    var maxIndex = data.keys.first;
+
+    for (var key in data.keys) {
+      if (key > maxIndex) {
+        maxIndex = key;
+      }
+    }
+
+    this._maxIndex = maxIndex;
+
+    _table = List<T?>.filled(maxIndex + 1, null);
+
+    for (var entry in data.entries) {
+      _table[entry.key] = entry.value;
+    }
+  }
+
+  late final List<T?> _table;
+  late final int _maxIndex;
+
+  operator [](int index) {
+    if (index > _maxIndex) {
+      return null;
+    }
+
+    return _table[index];
+  }
+}