Решение на Concurrent Retry Executor от Диана Генева

Обратно към всички решения

Към профила на Диана Генева

Резултати

  • 10 точки от тестове
  • 0 бонус точки
  • 10 точки общо
  • 8 успешни тест(а)
  • 0 неуспешни тест(а)

Код

package main
import (
"fmt"
"sync"
)
var locker = &sync.Mutex{}
func OrderedLogDrainer(logs chan (chan string)) chan string {
result := make(chan string)
go drainChannels(logs, result)
return result
}
func drainChannels(logs chan (chan string), result chan string) {
orderedChannels := make(chan (chan string), 100)
var infinityChannelPointer *(chan (chan string))
infinityChannelPointer = &orderedChannels
var count int = 1
go fillLogs(logs, &count, &infinityChannelPointer)
for count > 0 {
for channel := range *infinityChannelPointer {
for log := range channel {
result <- log
}
}
count = count - 1
}
close(result)
}
func fillLogs(logs chan (chan string), count *int, infinityChannelPointer **(chan (chan string))) {
var logNumber int = 1
for log := range logs {
orderedChannel := make(chan string, 100)
go drainLog(logNumber, log, orderedChannel)
resizeInfinityChannel(count, infinityChannelPointer)
**infinityChannelPointer <- orderedChannel
logNumber++
}
close(**infinityChannelPointer)
}
func resizeInfinityChannel(count *int, infinityChannelPointer **(chan (chan string))) {
locker.Lock()
if len((**infinityChannelPointer)) == cap((**infinityChannelPointer)) {
(*count)++
channelSize := cap(**infinityChannelPointer) * 2
close(**infinityChannelPointer)
biggerChannel := make(chan (chan string), channelSize)
for logs := range **infinityChannelPointer {
biggerChannel <- logs
}
*infinityChannelPointer = &biggerChannel
}
locker.Unlock()
}
func drainLog(logNumber int, log chan string, formattedLog chan string) {
for content := range log {
formattedLog <- formatString(logNumber, content)
}
close(formattedLog)
}
func formatString(logNumber int, content string) string {
return fmt.Sprintf("%d\t%s", logNumber, content)
}

Лог от изпълнението

PASS
ok  	_/tmp/d20151110-19113-bsjmum	0.003s
PASS
ok  	_/tmp/d20151110-19113-bsjmum	0.003s
PASS
ok  	_/tmp/d20151110-19113-bsjmum	0.006s
PASS
ok  	_/tmp/d20151110-19113-bsjmum	0.003s
PASS
ok  	_/tmp/d20151110-19113-bsjmum	0.003s
PASS
ok  	_/tmp/d20151110-19113-bsjmum	0.705s
PASS
ok  	_/tmp/d20151110-19113-bsjmum	0.004s
PASS
ok  	_/tmp/d20151110-19113-bsjmum	0.007s

История (2 версии и 1 коментар)

Диана обнови решението на 09.11.2015 16:08 (преди над 2 години)

+package main
+
+import "fmt"
+
+func OrderedLogDrainer(logs chan (chan string)) chan string {
+ result := make(chan string)
+ go drainChannels(logs, result)
+ return result
+}
+
+func drainChannels(logs chan (chan string), result chan string) {
+ orderedChannels := make(chan (chan string), 100)
+ go fillLogs(logs, orderedChannels)
+ for channel := range orderedChannels {
+ for log := range channel {
+ result <- log
+ }
+ }
+ close(result)
+}
+
+func fillLogs(logs chan (chan string), orderedChannels chan (chan string)) {
+ var logNumber int = 1
+ for log := range logs {
+ orderedChannel := make(chan string, 100)
+ go drainLog(logNumber, log, orderedChannel)
+ orderedChannels <- orderedChannel
+ logNumber++
+ }
+ close(orderedChannels)
+}
+
+func drainLog(logNumber int, log chan string, formattedLog chan string) {
+ for content := range log {
+ formattedLog <- formatString(logNumber, content)
+ }
+ close(formattedLog)
+}
+
+func formatString(logNumber int, content string) string {
+ return fmt.Sprintf("%d\t%s", logNumber, content)
+}

Изглежда супер! Единственият проблем, който виждам е, че няма да работи с повече от 100 лога. В условието сме ограничили броя съобщения във всеки лог до 100, но никъде не сме казали, че ще има под 100 лога.

Диана обнови решението на 10.11.2015 14:56 (преди над 2 години)

package main
-import "fmt"
+import (
+ "fmt"
+ "sync"
+)
+var locker = &sync.Mutex{}
+
func OrderedLogDrainer(logs chan (chan string)) chan string {
result := make(chan string)
go drainChannels(logs, result)
return result
}
func drainChannels(logs chan (chan string), result chan string) {
orderedChannels := make(chan (chan string), 100)
- go fillLogs(logs, orderedChannels)
- for channel := range orderedChannels {
- for log := range channel {
- result <- log
+ var infinityChannelPointer *(chan (chan string))
+ infinityChannelPointer = &orderedChannels
+ var count int = 1
+ go fillLogs(logs, &count, &infinityChannelPointer)
+ for count > 0 {
+ for channel := range *infinityChannelPointer {
+ for log := range channel {
+ result <- log
+ }
}
+ count = count - 1
}
close(result)
}
-func fillLogs(logs chan (chan string), orderedChannels chan (chan string)) {
+func fillLogs(logs chan (chan string), count *int, infinityChannelPointer **(chan (chan string))) {
var logNumber int = 1
for log := range logs {
orderedChannel := make(chan string, 100)
go drainLog(logNumber, log, orderedChannel)
- orderedChannels <- orderedChannel
+
+ resizeInfinityChannel(count, infinityChannelPointer)
+
+ **infinityChannelPointer <- orderedChannel
logNumber++
}
- close(orderedChannels)
+ close(**infinityChannelPointer)
+}
+
+func resizeInfinityChannel(count *int, infinityChannelPointer **(chan (chan string))) {
+ locker.Lock()
+ if len((**infinityChannelPointer)) == cap((**infinityChannelPointer)) {
+ (*count)++
+ channelSize := cap(**infinityChannelPointer) * 2
+ close(**infinityChannelPointer)
+ biggerChannel := make(chan (chan string), channelSize)
+ for logs := range **infinityChannelPointer {
+ biggerChannel <- logs
+ }
+ *infinityChannelPointer = &biggerChannel
+ }
+ locker.Unlock()
}
func drainLog(logNumber int, log chan string, formattedLog chan string) {
for content := range log {
formattedLog <- formatString(logNumber, content)
}
close(formattedLog)
}
func formatString(logNumber int, content string) string {
return fmt.Sprintf("%d\t%s", logNumber, content)
}