Go 外部排序-网络版
目录结果
main.go
package main import (
"NetworkSort/pipeline"
"fmt"
"os"
"bufio"
) func main() {
const filename = "large.in"
const n = 100000000
file, err := os.Create(filename)
if err != nil {
panic(err)
}
defer file.Close()
p := pipeline.RandomSource(n)
writer := bufio.NewWriter(file)
pipeline.WriterSink(writer, p)
writer.Flush() file, err = os.Open(filename)
if err != nil {
panic(err)
}
defer file.Close()
p = pipeline.ReaderSource(bufio.NewReader(file), -1)
count := 0
for v := range p {
fmt.Println(v)
count ++
if count >= 100 {
break
}
}
}
sort.go
package main import (
"os"
"NetworkSort/pipeline"
"bufio"
"fmt"
"strconv"
) func main() {
p := createNetworkPipeline("small.in", 512, 4)
writeToFile(p, "small.out")
printFile("small.out")
} func printFile(filename string) {
file, err := os.Open(filename)
if err != nil {
panic(err)
}
defer file.Close()
p := pipeline.ReaderSource(file, -1)
count := 0
for v:= range p {
fmt.Println(v)
count ++
if count >= 100 {
break
}
}
} func writeToFile(p <-chan int, filename string) {
file, err := os.Create(filename)
if err != nil {
panic(err)
}
defer file.Close()
writer := bufio.NewWriter(file)
defer writer.Flush()
pipeline.WriterSink(writer, p) } func createNetworkPipeline(filename string, fileSize, chunkCount int) <-chan int {
chunkSize := fileSize / chunkCount
pipeline.Init()
var sortAddr []string
for i := 0; i < chunkCount; i ++ {
file, err := os.Open(filename)
if err != nil {
panic(err)
}
file.Seek(int64(i * chunkSize), 0)
source := pipeline.ReaderSource(bufio.NewReader(file), chunkSize)
addr := "127.0.0.1:" + strconv.Itoa(7000 + i)
fmt.Println("addr:", addr)
pipeline.NetworkSink(addr, pipeline.InMemorySort(source))
sortAddr = append(sortAddr, addr)
}
return nil
var sortResults []<-chan int
for _, addr := range sortAddr {
sortResults = append(sortResults, pipeline.NetworkSource(addr))
}
return pipeline.MergeN(sortResults ...)
}
nodes.go
package pipeline import (
"sort"
"io"
"encoding/binary"
"math/rand"
"time"
"fmt"
) var startTime time.Time func Init() {
startTime = time.Now()
} func ArraySource(a ...int) <-chan int {
out := make(chan int, 1024)
go func() {
for _, v := range a{
out <- v
}
close(out)
}()
return out
} func InMemorySort(in <-chan int) <-chan int {
out := make(chan int, 1024)
go func() {
// Read into memory
var a []int
for v := range in {
a = append(a, v)
}
fmt.Println("Read done:", time.Now().Sub(startTime))
// Sort
sort.Ints(a)
fmt.Println("InMemSort done:", time.Now().Sub(startTime)) // Output
for _, v := range a {
out <- v
}
close(out)
}()
return out
} func Merge(in1, in2 <-chan int) <-chan int {
out := make(chan int, 1024)
go func() {
v1, ok1 := <- in1
v2, ok2 := <- in2
for ok1 || ok2 {
if !ok2 || (ok1 && v1 <= v2) {
out <- v1
v1, ok1 = <-in1
} else {
out <- v2
v2, ok2 = <-in2
}
}
close(out)
fmt.Println("Merge done:", time.Now().Sub(startTime)) }()
return out
} func ReaderSource(reader io.Reader, chunkSize int) <-chan int {
out := make(chan int, 1024)
go func() {
buffer := make([]byte, 8)
bytesRead := 0
for {
n, err := reader.Read(buffer)
bytesRead += n
if n > 0 {
v := int(binary.BigEndian.Uint64(buffer))
out <- v
}
if err != nil || (chunkSize != -1 && bytesRead >= chunkSize){
break
}
}
close(out)
}()
return out
} func WriterSink(writer io.Writer, in <-chan int) {
for v := range in {
buffer := make([]byte, 8)
binary.BigEndian.PutUint64(buffer, uint64(v))
writer.Write(buffer)
}
} func RandomSource(count int) <-chan int {
out := make(chan int)
go func() {
for i:=0; i<count; i++ {
out <- rand.Int()
}
close(out)
}()
return out
} func MergeN(inputs ...<-chan int) <-chan int{
if len(inputs) == 1{
return inputs[0]
}
m := len(inputs) / 2 // merge inputs[0...m] and inputs[m...end]
return Merge(MergeN(inputs[:m] ...), MergeN(inputs[m:] ...))
}
network_nodes.go
package pipeline import (
"net"
"bufio"
) func NetworkSink(addr string, in <-chan int){
listener, err :=net.Listen("tcp", addr)
if err != nil {
panic(err)
}
go func() {
defer listener.Close()
conn, err := listener.Accept()
if err != nil {
panic(err)
}
defer conn.Close()
writer := bufio.NewWriter(conn)
defer writer.Flush()
WriterSink(writer, in)
}()
} func NetworkSource(addr string) <-chan int {
out := make(chan int)
go func() {
conn, err := net.Dial("tcp", addr)
if err != nil {
panic(err)
}
r := ReaderSource(bufio.NewReader(conn), -1)
for v := range r {
out <- v
}
close(out)
}()
return out
}
Go 外部排序-网络版的更多相关文章
- sphinx 源码阅读之分词,压缩索引,倒排——单词对应的文档ID列表本质和lucene无异 也是外部排序再压缩 解压的时候需要全部扫描doc_ids列表偏移量相加获得最终的文档ID
转自:http://github.tiankonguse.com/blog/2014/12/03/sphinx-token-inverted-sort.html 外部排序 现在我们的背景是有16个已经 ...
- 外部排序&多路归并排序
外部排序: 一.定义问题 外部排序指的是大文件的排序,即待排序的记录存储在外存储器上,待排序的文件无法一次装入内存,需要在内存和外部存储器之间进行多次数据交换,以达到排序 整个文件的目的.外部排序最常 ...
- 大数据排序算法:外部排序,bitmap算法;大数据去重算法:hash算法,bitmap算法
外部排序算法相关:主要用到归并排序,堆排序,桶排序,重点是先分成不同的块,然后从每个块中找到最小值写入磁盘,分析过程可以看看http://blog.csdn.net/jeason29/article/ ...
- Go实现分布式外部排序
Go实现分布式外部排序 项目路径: https://github.com/Draymonders/go_external_sort 默认读入文件: small.in 默认输出文件:small.out ...
- Multithreading C++ Out of Core Sotring for Massive Data|多线程C++的大规模数据外部排序
先说一下,这个其实是我为实现PantaRay或者是类似Dreamworks的Out of Core点云GI的技术储备,为大规模点云光线跟踪所准备的第一步.在实际的应用中,int类型会被64bit的ui ...
- 常用算法——排序(一)
排序(Sort)是计算机程序设计中的一种重要操作,也是日常生活中经常遇到的问题.例如,字典中的单词是以字母的顺序排列,否则,使用起来非常困难.同样,存储在计算机中的数据的次序,对于处理这些数据的算法的 ...
- 八大排序算法Java
目录(?)[-] 概述 插入排序直接插入排序Straight Insertion Sort 插入排序希尔排序Shells Sort 选择排序简单选择排序Simple Selection Sort 选择 ...
- 面试题目——《CC150》排序与查找
面试题11.1:给定两个排序后的数组A和B,其中A的末端有足够的缓冲空间容纳B.编写一个方法,将B合并入A并排序. package cc150.sort_search; public class Me ...
- [Data Structure & Algorithm] 八大排序算法
排序有内部排序和外部排序之分,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部的排序记录,在排序过程中需要访问外存.我们这里说的八大排序算法均为内部排序. 下图为排序 ...
随机推荐
- 转载:tar 解压缩命令~
转载自:http://blog.csdn.net/dunyanan1/article/details/38869059tar -c: 建立压缩档案-x:解压-t:查看内容-r:向压缩归档文件末尾追加文 ...
- HDU2602Bone Collector 简单0-1背包
Bone Collector Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) T ...
- go语言递归创建目录
import ( "fmt" "os" ) func main() { //创建C:/temp/log文件夹 // err := os.MkdirAll(&qu ...
- (翻译) TFS源码控制的未来 (TFSVC vs. Git)
博主: 翻译自微软Visual Studio ALM产品组老大Brian Harry 的博客文章 The future of Team Foundation Server Version contro ...
- unintest基础1
import unittest class Testfunc(unittest.TestCase): def testfunc(self): print('testfunc1') def testfu ...
- LeetCode Problem 35:Search Insert Position
描述:Given a sorted array and a target value, return the index if the target is found. If not, return ...
- B - The Suspects(并查集)
B - The Suspects Time Limit:1000MS Memory Limit:20000KB 64bit IO Format:%lld & %llu Desc ...
- (转)IOS崩溃 异常处理(NSSetUncaughtExceptionHandler)
iOS已发布应用中对异常信息捕获和处理 代码下载地址:http://download.csdn.net/detail/daiyelang/6740205 iOS开发中我们会遇到程序抛出异常退出的情况, ...
- 【python】-- Django 中间件、缓存、信号
Django 中间件.缓存.信号 一. Django 中间件 django 中的中间件(middleware),在django中,中间件其实就是一个类,在请求到来和结束后,django会根据自己的 ...
- openssl之EVP系列之7---信息摘要算法结构概述
openssl之EVP系列之7---信息摘要算法结构概述 ---依据openssl doc/crypto/EVP_DigestInit.pod翻译和自己的理解写成 (作者:Dragon ...